Migrar a Entrada para a API Gateway

Nesta página, mostramos como migrar o gerenciamento de tráfego no Google Kubernetes Engine (GKE) da API Ingress para a API Gateway. A API Gateway oferece uma solução Google Cloud totalmente gerenciada para processar o tráfego de aplicativos.

Para minimizar o tempo de inatividade e reduzir o risco, a abordagem mais eficaz para migrar para a API Gateway é executar simultaneamente a API Ingress atual e as novas configurações da API Gateway. Esse método permite testar completamente a nova configuração do gateway em um ambiente ativo sem afetar os serviços atuais. Depois de validar a nova configuração do gateway, faça uma transição rápida de DNS para redirecionar o tráfego para a API Gateway e garantir uma transição tranquila e de baixo risco.

Em geral, a estratégia de migração envolve as seguintes fases:

  1. Configure o novo balanceador de carga.
  2. Defina regras para processar o tráfego de entrada.
  3. Implante a nova configuração e teste o fluxo de tráfego para o novo endereço IP do gateway.
  4. Mude o tráfego de produção para a API Gateway.
  5. Limpe os recursos restantes do Entrada.

Configurar o novo balanceador de carga

Nesta fase, você implanta um recurso de gateway do Kubernetes para fazer o balanceamento de carga do tráfego no cluster do GKE. Quando você implanta um recurso Gateway, o GKE configura um balanceador de carga de aplicativo da camada 7 para expor o tráfego HTTP(S) a aplicativos executados no cluster. Você implanta um recurso de gateway para cada cluster ou balanceador de carga necessário.

No exemplo a seguir, você configura um balanceador de carga de aplicativo externo global. Para criar um gateway, salve o manifesto a seguir como gateway.yaml:

kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: external-http-gateway
spec:
  gatewayClassName: gke-l7-global-external-managed # GKE's managed external Application Load Balancer
  listeners:
  - name: http
    protocol: HTTP
    port: 80
    allowedRoutes:
      namespaces:
        from: Same # Only allow HTTPRoutes from the same namespace

O manifesto anterior descreve um Gateway que inclui os seguintes campos:

  • gatewayClassName: gke-l7-global-external-managed: especifica o GatewayClass para esse gateway. Essa classe de gateway usa um balanceador de carga de aplicativo externo global.
  • protocol: HTTP e port: 80: especifica que o gateway expõe a porta 80 para o tráfego HTTP.

Definir regras de tráfego para o tráfego de entrada

Os recursos de rota definem regras específicas do protocolo que mapeiam o tráfego de um gateway para os serviços de back-end.

Nesta fase, você vai traduzir o manifesto do Entrada em um recurso HTTPRoute. Para converter o manifesto do Entrada, siga as etapas na ferramenta ingress2gateway.

Este exemplo pressupõe que você tenha o seguinte recurso do Entrada:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cafe-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: cafe.example.com
    http:
      paths:
      - path: /tea
        pathType: Prefix
        backend:
          service:
            name: tea-svc
            port:
              number: 80
      - path: /coffee
        pathType: Prefix
        backend:
          service:
            name: coffee-svc
            port:
              number: 80

Depois de converter o manifesto usando a ferramenta ingress2gateway, a saída será o manifesto HTTPRoute traduzido.

Salve o seguinte manifesto de amostra como httproute.yaml:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: cafe-route
spec:
  # This route attaches to our new Gateway
  parentRefs:
  - name: external-http-gateway
  # The hostname is the same as before
  hostnames:
  - "cafe.example.com"
  # The routing rules are now more explicit
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /tea
    backendRefs:
    - name: tea-svc
      port: 80
  - matches:
    - path:
        type: PathPrefix
        value: /coffee
    backendRefs:
    - name: coffee-svc
      port: 80

O campo rules no manifesto HTTPRoute corresponde diretamente às regras de roteamento definidas no manifesto Entrada original.

Implantar e testar a nova configuração

Nesta fase, você aplica os manifestos do Gateway e do HTTPRoute criados nas duas fases anteriores e testa se o tráfego flui para o novo endereço IP do Gateway.

  1. Aplique os manifestos do gateway e do HTTPRoute:

    kubectl apply -f gateway.yaml
    kubectl apply -f httproute.yaml
    
  2. Consiga o endereço IP do gateway. Pode levar alguns minutos para alocar o endereço IP:

    kubectl get gateway external-http-gateway -o=jsonpath="{.status.addresses[0].value}" --watch
    

    A saída é o endereço IP externo do gateway, por exemplo, 203.0.113.90.

  3. Teste o novo endereço IP do gateway. Use o comando curl a seguir para enviar uma solicitação ao endereço IP e especificar o nome do host cafe.example.com. Exemplo:

    curl --resolve cafe.example.com:80:203.0.113.90 http://cafe.example.com/tea
    curl --resolve cafe.example.com:80:203.0.113.90 http://cafe.example.com/coffee
    

    Substitua 203.0.113.90 pelo endereço IP externo que você recebeu na etapa anterior. A saída confirma que o novo endereço IP do gateway roteia corretamente o tráfego para cafe.example.com sem fazer uma busca DNS.

Direcionar o tráfego para o novo endereço IP do gateway

Nesta fase, você corta o tráfego ativo do Entrada anterior para o novo Gateway atualizando os registros DNS para apontar para o novo endereço IP do Gateway. As etapas exatas para atualizar os registros de DNS variam de acordo com o provedor.

Por exemplo, se você configurou cafe.example.com no Entrada, localize o registro A de cafe.example.com com seu provedor de DNS e mude o valor do antigo endereço IP do Ingress para 203.0.113.90, que é o novo endereço IP do gateway.

Depois que você atualiza o registro DNS, o tráfego começa a mudar do Entrada para o Gateway, mas a migração não ocorre imediatamente para todos os clientes. Os resolvedores de DNS que têm o registro anterior armazenado em cache aguardam o valor de tempo de vida (TTL) do registro expirar antes de consultar o registro novamente e receber o endereço IP atualizado. Por isso, continue executando o Entrada atual e o novo Gateway em conjunto até verificar se o tráfego para o Entrada cessou, o que indica que a propagação de DNS foi concluída e os clientes não estão mais sendo direcionados para o endereço IP antigo. Para verificar isso, monitore o tráfego no balanceador de carga ou no controlador de entrada. Para mais informações, consulte Como verificar a propagação de DNS.

Se você usa o Cloud DNS, é possível usar pesos de destino para transferir incrementalmente o tráfego do endereço IP antigo para o novo. Para mais informações, consulte Configurar políticas de roteamento de DNS e verificações de integridade.

Limpar os recursos de entrada restantes

Depois de confirmar que o novo gateway está funcionando corretamente, limpe os recursos de entrada antigos.

  1. Exclua o recurso Entrada:

    kubectl delete ingress cafe-ingress
    
  2. Desinstale o controlador ingress-nginx. Por exemplo, se você usou o Helm para instalar o controlador, execute o seguinte comando:

    helm uninstall ingress-nginx -n ingress-nginx
    

Comparação de recursos entre o Ingress NGINX e o GKE Gateway

A API Gateway oferece uma maneira mais padronizada de configurar o ingresso e tem paridade de recursos para os recursos mais comuns, como roteamento, cabeçalhos e divisão de tráfego.

A tabela a seguir compara as anotações usadas para recursos comuns no controlador de entrada e na API Gateway.

Recurso Anotação no Entrada Anotação no gateway do GKE Paridade
Regravações de URL nginx.ingress.kubernetes.io/rewrite-target HTTPRoute com um filtro urlRewrite. Paridade parcial. O GKE Gateway só oferece suporte a substituições de prefixo.
Manipulação de cabeçalho nginx.ingress.kubernetes.io/proxy-set-headers ou add-headers HTTPRoute com um modificador requestHeaderModifier ou um filtro responseHeaderModifier. Paridade total.
Roteamento baseado em caminho spec.rules.http.paths no objeto de entrada. rules.matches.path no objeto HTTPRoute. Paridade total.
Roteamento com base em host spec.rules.host no objeto de entrada. hostnames no objeto HTTPRoute. Paridade total.
Divisão de tráfego nginx.ingress.kubernetes.io/canary anotações. HTTPRoute com backendRefs ponderado. Paridade total. Além disso, é possível dividir o tráfego com controle refinado.
Autenticação nginx.ingress.kubernetes.io/auth-url para autenticação externa.
  • Identity-Aware Proxy (IAP): CRD BackendPolicy.
  • Outro: requer uma abordagem mais personalizada, possivelmente com malha de serviço ou filtros personalizados.
Paridade parcial. O Identity-Aware Proxy é a maneira recomendada de proteger seu gateway e é configurado no back-end.

A seguir