Uma Comparação Abrangente de API Gateways, Kubernetes Gateways e Service Meshes

Navendu Pottekkat

Navendu Pottekkat

June 9, 2023

Technology

Ainda há muita confusão sobre gateways de API, gateways do Kubernetes e service meshes. Grande parte disso se deve a:

  1. As pessoas frequentemente mencionam essas tecnologias com as mesmas palavras-chave, como implantações canário, limitação de taxa e descoberta de serviços.
  2. Todas essas tecnologias usam proxies reversos.
  3. Alguns gateways de API têm seus próprios gateways do Kubernetes e service meshes, e vice-versa.
  4. Há muitos artigos/vídeos que comparam as três tecnologias e concluem por que uma é melhor que a outra.

Neste artigo, tentarei explicar essas tecnologias e compartilhar como elas diferem fundamentalmente e atendem a diferentes casos de uso.

Gateways de API

Um gateway de API fica entre seus aplicativos clientes e suas APIs. Ele aceita todas as solicitações dos clientes, encaminha-as para as APIs necessárias e retorna a resposta aos clientes em um pacote combinado.

Basicamente, é um proxy reverso com muitas funcionalidades.

Gateway de API

Além disso, um gateway de API também pode ter recursos como autenticação, segurança, controle de tráfego granular e monitoramento, permitindo que os desenvolvedores de APIs se concentrem apenas nas necessidades de negócios.

Existem muitas soluções de gateway de API disponíveis. Algumas das soluções gratuitas e de código aberto populares são:

  • Apache APISIX: Um gateway de API de alto desempenho, extensível e nativo da nuvem, construído sobre o Nginx.
  • Gloo Edge: Um gateway de API construído sobre o proxy Envoy.
  • Kong: Um gateway de API plugável também construído sobre o Nginx.
  • Tyk: Um gateway de API escrito em Go que suporta protocolos REST, GraphQL, TCP e gRPC.

Plataformas de nuvem como GCP, AWS e Azure também têm seus próprios gateways de API proprietários.

Gateways de API, gateways do Kubernetes e service meshes suportam implantações canário — lançando gradualmente uma nova versão de software para um pequeno subconjunto de usuários antes de disponibilizá-la para todos.

O exemplo abaixo mostra como configurar uma implantação canário no Apache APISIX.

Implantações canário com um gateway de API

Você pode enviar uma solicitação para a API de Administração do APISIX com a seguinte configuração:

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
  "uri":"/*",
  "plugins":{
    "traffic-split":{
      "rules":[
        {
          "weighted_upstreams":[
            {
              "upstream":{
                "name":"api-v1",
                "type":"roundrobin",
                "nodes":{
                  "api-v1:8080":1
                }
              },
              "weight":95
            },
            {
              "weight":5
            }
          ]
        }
      ]
    }
  },
  "upstream":{
    "type":"roundrobin",
    "nodes":{
      "api-v2:8080":1
    }
  }
}'

O APISIX agora roteará 95% do tráfego para o serviço api-v1 e 5% para o serviço api-v2.

Gateways do Kubernetes

Gateways do Kubernetes são simplesmente gateways de API nativos do Kubernetes. Ou seja, você pode gerenciar esses gateways de API com a API do Kubernetes, semelhante a um pod, serviço ou implantação do Kubernetes.

No Kubernetes, suas APIs são pods e serviços implantados em um cluster. Em seguida, você usa um gateway do Kubernetes para direcionar o tráfego externo para o seu cluster.

O Kubernetes fornece duas APIs para isso, a API Ingress e a API Gateway.

Gateway do Kubernetes

API Ingress do Kubernetes

A API Ingress foi criada para superar as limitações dos tipos de serviço padrão, NodePort e LoadBalancer, introduzindo recursos como roteamento e terminação SSL. Ela também padronizou como você expõe os serviços do Kubernetes ao tráfego externo.

Ela tem dois componentes, o Ingress e o controlador Ingress.

O objeto nativo do Kubernetes Ingress define um conjunto de regras sobre como o tráfego externo pode acessar seus serviços.

Esta configuração de exemplo mostra o roteamento de tráfego com base no caminho URI com o objeto Kubernetes Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-routes
spec:
  ingressClassName: apisix
  rules:
    - http:
        paths:
          - backend:
              service:
                name: api-v1
                port:
                  number: 8080
            path: /v1
            pathType: Exact
          - backend:
              service:
                name: api-v2
                port:
                  number: 8080
            path: /v2
            pathType: Exact

Um controlador Ingress implementa essas regras e roteia o tráfego para o seu cluster usando um proxy reverso.

Existem mais de 20 implementações de controladores Ingress. O APISIX tem um controlador Ingress que envolve o gateway de API APISIX para funcionar como Ingress do Kubernetes.

Ingress do APISIX

O controlador Ingress do APISIX converte o objeto Kubernetes Ingress em configuração do APISIX.

O controlador Ingress do APISIX traduz a configuração

O APISIX então implementa essa configuração.

Implantações canário com a API Ingress do Kubernetes

Você pode substituir o APISIX por qualquer outro controlador Ingress, pois a API Ingress não está vinculada a nenhuma implementação específica.

Essa neutralidade de fornecedor funciona bem para configurações simples. Mas se você quiser fazer roteamentos complexos, como uma implantação canário, deve confiar em anotações específicas do fornecedor.

O exemplo abaixo mostra como configurar uma implantação canário usando Nginx Ingress. As anotações personalizadas usadas aqui são específicas para o Nginx:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "5"
  name: api-canary
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: api-v2
          servicePort: 8080
        path: /

A configuração acima roteará 5% do tráfego para o serviço api-v2.

Além das anotações, controladores Ingress como o APISIX têm CRDs personalizados do Kubernetes para superar as limitações da API Ingress.

O exemplo abaixo usa o CRD do APISIX, ApisixRoute, para configurar uma implantação canário:

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: api-canary
spec:
  http:
    - name: route
      match:
        paths:
          - /*
      backends:
        - serviceName: api-v1
          servicePort: 8080
          weight: 95
        - serviceName: api-v2
          servicePort: 8080
          weight: 5

Esses CRDs personalizados tornaram muito mais fácil configurar o Ingress e aproveitar todas as capacidades do gateway de API subjacente, mas às custas da portabilidade.

API Gateway do Kubernetes

A API Gateway é um novo objeto do Kubernetes que visa "corrigir" a API Ingress.

Ela se inspira nos CRDs personalizados desenvolvidos pelos controladores Ingress para adicionar correspondência baseada em cabeçalhos HTTP, divisão de tráfego ponderada e outros recursos que exigem anotações proprietárias personalizadas com a API Ingress.

O exemplo abaixo mostra a configuração de uma implantação canário com a API Gateway do Kubernetes:

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
  name: api-canary
spec:
  rules:
  - backendRefs:
    - name: api-v1
      port: 8080
      weight: 95
    - name: api-v2
      port: 8080
      weight: 5

Qualquer controlador Ingress (que implemente a API Gateway) pode agora implementar essa configuração.

A API Gateway também faz muitas melhorias em relação à API Ingress, mas ainda está em alpha, e as implementações da API Gateway estão constantemente quebrando.

Service Meshes

Gateways de API e gateways do Kubernetes funcionam além dos limites do aplicativo, resolvendo problemas de borda enquanto abstraem suas APIs.

Os Service Meshes resolvem um desafio diferente.

Um service mesh está mais preocupado com a comunicação entre serviços (tráfego leste-oeste) do que com a comunicação serviço-cliente (tráfego norte-sul).

Normalmente, isso é alcançado implantando proxies sidecar com APIs/serviços.

Service mesh

Aqui, os proxies sidecar lidam com a comunicação entre serviços, em vez de o desenvolvedor ter que codificar a lógica de rede nos serviços.

Existem muitos service meshes disponíveis. Alguns dos mais populares são:

  • Istio: De longe, o service mesh mais popular. Ele é construído sobre o proxy Envoy, que muitos service meshes usam.
  • Linkerd: Um service mesh leve que usa o linkerd2-proxy, escrito em Rust especificamente para o Linkerd.
  • Consul Connect: Um service mesh que enfatiza segurança e observabilidade. Ele pode funcionar com um proxy embutido ou com o Envoy.

Novas ofertas de service mesh, como Cilium, oferecem alternativas aos service meshes baseados em sidecar, usando capacidades de rede diretamente do kernel por meio do eBPF.

Service mesh sem sidecar

Um service mesh típico requer 8 proxies para 8 serviços, enquanto service meshes baseados em eBPF, como o Cilium, não. Adaptado de Cilium Service Mesh – Everything You Need to Know.

Os service meshes também têm gateways de entrada/saída básicos para lidar com o tráfego norte-sul de e para os serviços. Os gateways de entrada são os pontos de entrada do tráfego externo para um service mesh, e os gateways de saída permitem que os serviços dentro de um mesh acessem serviços externos.

Gateways de entrada e saída com um service mesh

O Apache APISIX também tem uma implementação de service mesh chamada Amesh. Ele funciona com o plano de controle do Istio usando o protocolo xDS, substituindo o proxy Envoy padrão no sidecar.

Um service mesh permite que você configure implantações canário. Por exemplo, você pode dividir as solicitações de um serviço entre duas versões de outro serviço.

Implantações canário com um service mesh

O exemplo abaixo mostra a configuração de uma implantação canário com o service mesh Istio:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: api-virtual-service
spec:
  hosts:
    - api
  http:
    - route:
        - destination:
            host: api
            subset: v1
          weight: 80
        - destination:
            host: api
            subset: v2
          weight: 20
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: api-destination-rule
spec:
  host: api
  subsets:
    - name: v1
      labels:
        version: "1.0"
    - name: v2
      labels:
        version: "2.0"

Essas configurações são específicas para o Istio. Para mudar para um service mesh diferente, você deve criar uma configuração diferente, mas igualmente dependente do fornecedor.

A especificação Service Mesh Interface (SMI) foi criada para resolver esse problema de portabilidade.

A SMI spec é um conjunto de CRDs do Kubernetes que um usuário de service mesh pode usar para definir aplicativos sem se vincular a implementações de service mesh.

Uma tentativa de padronização só funcionará se todos os projetos estiverem a bordo. Mas isso não aconteceu com a especificação SMI, e apenas alguns projetos participaram ativamente.

Mais recentemente, o SIG Network do Kubernetes tem evoluído a API Gateway para suportar service meshes.

A iniciativa GAMMA (Gateway API for Mesh Management and Administration) é um grupo dedicado ao projeto Gateway API com o objetivo de "investigar, projetar e rastrear recursos da API Gateway, semântica e outros artefatos relacionados à tecnologia de service mesh e casos de uso."

A API Gateway é um próximo passo natural para a API Ingress, mas ainda precisamos esperar para ver como ela funcionará para service meshes. O Istio anunciou sua intenção de usar a API Gateway como sua API padrão para todo o gerenciamento de tráfego e continua a impulsionar o projeto.

O exemplo abaixo mostra configurando uma implantação canário no Istio com a API Gateway. A ideia subjacente é usar parentRefs para se conectar a outros serviços em vez do gateway:

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: api-canary
spec:
  parentRefs:
  - kind: Service
    name: api-a
    port: 8080
  rules:
  - backendRefs:
    - name: api-b-v1
      port: 8080
      weight: 95
    - name: api-b-v2
      port: 8080
      weight: 5

algumas preocupações de que o projeto GAMMA possa se inclinar para atender às necessidades de um projeto específico em vez da comunidade maior, o que eventualmente levará a outros projetos usando suas próprias APIs, semelhante ao cenário de CRDs personalizados após a API Ingress do Kubernetes.

Mas o projeto Gateway API tem sido a melhor tentativa de padronizar o gerenciamento de tráfego em service meshes. O projeto SMI também se juntou à iniciativa GAMMA com uma visão compartilhada e ajudará a defender implementações consistentes da API Gateway por projetos de service mesh.

Outros projetos como Flagger e Argo Rollouts também se integraram à API Gateway.

O que você deve usar?

Há apenas uma resposta correta para essa pergunta; "depende."

Se você está desenvolvendo APIs e precisa de autenticação, segurança, roteamento ou métricas, é melhor usar um gateway de API do que construir isso por conta própria em suas APIs.

Se você quiser fazer algo semelhante em um ambiente Kubernetes, deve usar um gateway do Kubernetes em vez de tentar ajustar seu gateway de API para funcionar no Kubernetes. Felizmente, muitos gateways de API também funcionam com configurações nativas do Kubernetes.

Mas às vezes, os recursos oferecidos por um gateway de API + controlador Ingress podem ser exagerados para um ambiente Kubernetes, e você pode querer voltar a um gerenciamento de tráfego simples.

Os service meshes, por outro lado, resolvem um conjunto de problemas completamente diferente. Eles também trazem seus próprios gateways para lidar com o tráfego norte-sul (geralmente suficientes), mas também permitem que você use seus próprios gateways com mais recursos.

A convergência do gateway de API e do service mesh por meio da API Gateway do Kubernetes deve facilitar para o desenvolvedor de aplicativos se concentrar em resolver problemas em vez de se preocupar com a implementação subjacente.

Projetos como o Apache APISIX usam a mesma tecnologia para construir as ofertas de gateway de API e service mesh e se integram bem com essas especificações, incentivando escolhas neutras em relação ao fornecedor.

Também é provável que você não precise de nenhum desses. Você pode nem mesmo precisar de microsserviços ou de uma arquitetura distribuída, mas quando precisar, gateways e meshes podem facilitar muito sua vida.

Tags: