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 totalmente gerenciada Google Cloud para lidar com 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 as configurações da API Ingress e da nova API Gateway. Esse método permite testar completamente a nova configuração do gateway em um ambiente ativo sem afetar seus 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 lidar com 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. Limpar os recursos de entrada restantes.

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 para seu 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) aos 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ê traduz 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 de 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

Observe que o campo rules no manifesto HTTPRoute corresponde diretamente às regras de rota 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 de Gateway e 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 seguinte comando curl 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 realizar 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 DNS variam de acordo com o provedor de DNS.

Por exemplo, se você configurou cafe.example.com no Entrada, localize o registro A para 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 transição não ocorre imediatamente para todos os clientes. Os resolvedores de DNS que têm o registro anterior em cache aguardam o valor de time to live (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 que o tráfego para o Entrada foi interrompido, 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 foi executado, limpe os recursos de entrada antigos.

  1. Exclua o recurso de 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 gateway do GKE

A API Gateway oferece uma maneira mais padronizada de configurar a entrada 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 a configuração usada para recursos comuns no controlador Entrada e na API Gateway.

Recurso Anotação no Entrada Configuração no gateway do GKE Paridade
Roteamento com base em host O campo spec.rules.host no objeto de entrada. O campo hostnames no objeto HTTPRoute. Paridade total.
Roteamento baseado em caminho O campo spec.rules.http.paths no objeto Entrada. O campo rules.matches.path no objeto HTTPRoute. Paridade total.
Divisão de tráfego nginx.ingress.kubernetes.io/canary anotação. HTTPRoute com o campo backendRefs ponderado. Paridade total. Além disso, é possível dividir o tráfego com controle detalhado.
afinidade da sessão nginx.ingress.kubernetes.io/affinity e nginx.ingress.kubernetes.io/affinity-mode. GCPTrafficDistributionPolicy com o campo sessionAffinity. Paridade total. O gateway do GKE é compatível com vários tipos de afinidade da sessão, incluindo tipos de afinidade baseados em cookies (HTTP_COOKIE, GENERATED_COOKIE e STRONG_COOKIE_AFFINITY com estado), afinidade baseada em cabeçalho (HEADER_FIELD) e afinidade baseada em IP do cliente (CLIENT_IP).
CORS (compartilhamento de recursos entre origens) nginx.ingress.kubernetes.io/enable-cors HTTPRoute com um filtro CORS. Paridade total. Observação: o gateway do GKE impõe limites ao número de padrões curinga que podem ser definidos por listener ou nome do host.
Regravações de URL nginx.ingress.kubernetes.io/rewrite-target HTTPRoute com um filtro urlRewrite. Paridade parcial. O gateway do GKE 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.
Autenticação nginx.ingress.kubernetes.io/auth-url para autenticação externa.
  • Identity-Aware Proxy (IAP): recurso personalizado GCPBackendPolicy.
  • Outro: exige 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