Comparando as APIs Kubernetes Gateway e Ingress

Navendu Pottekkat

Navendu Pottekkat

October 21, 2022

Ecosystem

Há alguns meses, a nova API de Gateway do Kubernetes atingiu o status beta.

Por que você precisaria de outra API para lidar com tráfego externo quando já existe a estável API de Ingress do Kubernetes e dezenas de implementações? Quais problemas da API de Ingress a nova API de Gateway resolve? Isso significa o fim da API de Ingress?

Vou tentar responder a essas perguntas neste artigo, explorando essas APIs e observando como elas evoluíram.

Padronizando o Acesso Externo a Serviços: A API de Ingress

A API de Ingress do Kubernetes foi criada para padronizar a exposição de serviços no Kubernetes ao tráfego externo. A API de Ingress superou as limitações dos tipos de serviço padrão, NodePort e LoadBalancer, ao introduzir recursos como roteamento e terminação SSL.

Kubernetes Ingress

Existem mais de 20 implementações de controladores de Ingress disponíveis. Neste artigo, vou usar o Apache APISIX e seu controlador de Ingress para exemplos.

APISIX Ingress controller

Você pode criar um recurso de Ingress para configurar o APISIX ou qualquer outra implementação de Ingress.

O exemplo abaixo mostra como você pode rotear o tráfego entre duas versões de uma aplicação com o Ingress do APISIX:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-routes
spec:
  ingressClassName: apisix
  rules:
    - host: local.navendu.me
      http:
        paths:
          - backend:
              service:
                name: bare-minimum-api-v1
                port:
                  number: 8080
            path: /v1
            pathType: Prefix
          - backend:
              service:
                name: bare-minimum-api-v2
                port:
                  number: 8081
            path: /v2
            pathType: Prefix

Dica: Você pode conferir este tutorial prático para aprender mais sobre como configurar o Ingress no Kubernetes com o controlador de Ingress do Apache APISIX.

Como a API de Ingress não está vinculada a nenhuma implementação específica de controlador, você pode substituir o APISIX por qualquer outro controlador de Ingress, e ele funcionará de forma semelhante.

Isso é suficiente para roteamento simples. Mas a API é limitada, e se você quiser usar todos os recursos fornecidos pelo seu controlador de Ingress, você fica preso às anotações.

Por exemplo, a API de Ingress do Kubernetes não fornece um esquema para configurar reescritas. Reescritas são úteis quando a URL do seu upstream/backend difere do caminho configurado na sua regra de Ingress.

O APISIX suporta esse recurso, e você precisa usar anotações personalizadas para aproveitá-lo:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-routes
  annotations:
    k8s.apisix.apache.org/rewrite-target-regex: "/app/(.*)"
    k8s.apisix.apache.org/rewrite-target-regex-template: "/$1"
spec:
  ingressClassName: apisix
  rules:
    - host: local.navendu.me
      http:
        paths:
          - backend:
              service:
                name: bare-minimum-api
                port:
                  number: 8080
            path: /app
            pathType: Prefix

Isso cria um recurso de Ingress que configura o APISIX para rotear qualquer solicitação com o prefixo /app para o backend com o prefixo removido. Por exemplo, uma solicitação para /app/version será encaminhada para /version.

As anotações são específicas para a sua escolha de controlador de Ingress. Essas extensões "proprietárias" limitaram o escopo de portabilidade inicialmente pretendido com a API de Ingress.

CRDs Personalizados > API de Ingress

Ficar preso a anotações também sacrifica a usabilidade dos controladores de Ingress.

Portanto, os controladores resolveram as limitações da API de Ingress criando seus próprios recursos personalizados. O exemplo abaixo mostra como configurar o Ingress para rotear o tráfego entre duas versões de uma aplicação usando o recurso personalizado do APISIX:

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: api-routes
spec:
  http:
    - name: route-1
      match:
        hosts:
          - local.navendu.me
        paths:
          - /v1
      backends:
        - serviceName: bare-minimum-api-v1
          servicePort: 8080
    - name: route-2
      match:
        hosts:
          - local.navendu.me
        paths:
          - /v2
      backends:
        - serviceName: bare-minimum-api-v2
          servicePort: 8081

Esses CRDs tornaram muito mais fácil configurar o Ingress, mas você fica vinculado à implementação específica do controlador de Ingress. Sem a evolução da API de Ingress, você tinha que escolher entre usabilidade ou portabilidade.

Extensão do Ingress e Evolução para a API de Gateway

A API de Ingress não estava quebrada; ela era limitada. A API de Gateway foi projetada para superar essas limitações.

(API de Gateway) visa evoluir o serviço de rede do Kubernetes por meio de interfaces expressivas, extensíveis e orientadas a papéis ...

Ela se inspira nos CRDs personalizados de diferentes controladores de Ingress mencionados anteriormente.

A API de Gateway adiciona muitos recursos "além" das capacidades da API de Ingress. Isso inclui 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 de Ingress.

Divisão de tráfego com o recurso de Ingress do APISIX (veja referência ApisixRoute/v2):

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: traffic-split
spec:
  http:
    - name: rule-1
      match:
        hosts:
          - local.navendu.me
        paths:
          - /get*
      backends:
        - serviceName: bare-minimum-api-v1
          servicePort: 8080
          weight: 90
        - serviceName: bare-minimum-api-v2
          servicePort: 8081
          weight: 10

Divisão de tráfego com a API de Gateway (veja Canary traffic rollout):

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
  name: traffic-split
spec:
  hostnames:
  - local.navendu.me
  rules:
  - backendRefs:
    - name: bare-minimum-api-v1
      port: 8080
      weight: 90
    - name: bare-minimum-api-v2
      port: 8081
      weight: 10

Outra melhoria em relação à API de Ingress é como a API de Gateway separa as responsabilidades. Com o Ingress, o desenvolvedor da aplicação e o operador do cluster trabalham no mesmo objeto Ingress, sem estar cientes das responsabilidades do outro, o que abre espaço para más configurações.

A API de Gateway separa as configurações em objetos Route e Gateway, proporcionando autonomia para o desenvolvedor da aplicação e o operador do cluster. O diagrama abaixo explica isso claramente:

Separação de responsabilidades na API de Gateway

Isso Significa o Fim da API de Ingress?

A API de Gateway é relativamente nova, e suas implementações estão constantemente mudando. Por outro lado, a API de Ingress está em uma versão estável e já passou pelo teste do tempo.

Se o seu caso de uso envolve apenas roteamento simples e se você está disposto a usar anotações personalizadas para obter recursos extras, a API de Ingress ainda é uma escolha sólida.

Como a API de Gateway é um superconjunto da API de Ingress, pode fazer sentido consolidar ambas. Graças à comunidade SIG Network, a API de Gateway ainda está crescendo e em breve estará pronta para produção.

A maioria dos controladores de Ingress e malhas de serviço já implementaram a API de Gateway junto com a API de Ingress, e, à medida que o projeto evolui, mais implementações surgirão.

Pessoalmente, pelo menos por enquanto, eu ficaria com os CRDs personalizados fornecidos pelos controladores de Ingress, como o Apache APISIX, em vez da API de Ingress ou Gateway.

Tags: