Como implantar gateways

Implante recursos de gateway do Kubernetes para gerenciar como o tráfego externo chega aos aplicativos em um único cluster do Google Kubernetes Engine (GKE). A configuração do GKE Gateway oferece um controle flexível e eficiente sobre o tráfego de entrada, melhorando a escalonabilidade e a confiabilidade dos seus aplicativos. Por exemplo, o gateway do GKE oferece recursos otimizados de roteamento e escalonamento automático. Esses recursos são essenciais para a veiculação on-line de baixa latência, garantindo uma experiência do usuário responsiva e ajudando a controlar os custos.

Para implantar gateways em vários clusters ou em uma frota, consulte Como implantar gateways de vários clusters. Para configurações específicas do gateway, como roteamento entre namespaces e divisão de tráfego HTTP, consulte os guias do usuário da API Gateway. Para implantar um gateway para aplicativos de passagem de TLS com roteamento baseado em SNI, consulte Implantar um gateway de passagem de TLS.

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

  • Ative a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Para usar a Google Cloud CLI nesta tarefa, instale e inicialize a CLI gcloud. Se você instalou a CLI gcloud anteriormente, instale a versão mais recente executando o comando gcloud components update. Talvez as versões anteriores da CLI gcloud não sejam compatíveis com a execução dos comandos neste documento.
  • Verifique se você tem um cluster do Autopilot ou Standard. Para criar um novo cluster, consulte Criar um cluster do Autopilot.

  • Verifique se a conta de usuário tem o papel de Editor do Certificate Manager (roles/certificatemanager.editor) para criar os mapas de certificados necessários.

Requisitos do GKE Gateway Controller

  • A API Gateway é compatível apenas com clusters nativos da VPC.
  • Se você estiver usando as GatewayClasses regionais ou entre regiões, ative uma sub-rede somente proxy.
  • O cluster precisa ter o complemento HttpLoadBalancing ativado.
  • Se você estiver usando o Istio, será necessário fazer upgrade do Istio para uma das seguintes versões:
    • 1.15.2 ou mais recente
    • 1.14.5 ou mais recente
    • 1.13.9 ou mais recente
  • Se você estiver usando a VPC compartilhada, será necessário atribuir o papel Compute Network User à conta de serviço do GKE referente ao projeto de serviço no projeto host.

Restrições e limitações

Ao usar o gateway do GKE, entenda as seguintes limitações e restrições:

  • O GatewayClasses do GKE é compatível com diferentes recursos, dependendo do balanceador de carga que eles usam. Para saber mais sobre os diferentes recursos compatíveis com cada GatewayClass, consulte Recursos da GatewayClass.

    Prática recomendada:

    Para ter o melhor desempenho, limite o número de gateways a, no máximo, 100. Exceder esse limite pode afetar o desempenho ou aumentar a latência.

  • O gateway do GKE só é compatível com o canal de lançamento padrão da API Gateway.

  • O gateway do GKE está sempre ativado nos clusters do Autopilot. Não é possível instalar CRDs do canal de lançamento experimental da API Gateway em clusters do Autopilot.

  • Não é possível usar um FrontendConfig ou um BackendConfig para configurar um gateway. Você precisa usar uma política.

  • O gateway do GKE se comporta de maneira diferente da entrada, porque não infere parâmetros de verificação de integridade. Se o Serviço não retornar 200 para solicitações a GET / ou se você tiver outras verificações de prontidão de pod ajustadas, será necessário configurar uma HealthCheckPolicy para seu serviço.

  • Não é possível especificar um número de porta diretamente no nome do host (por exemplo, web.example.com:80) para roteamento de tráfego.

  • Os recursos do balanceador de carga que o GKE cria para gateways aparecem no console do Google Cloud , mas não fazem referência ao gateway ou ao cluster do GKE ao qual estão anexados.

  • Não é possível gerar automaticamente um certificado SSL gerenciado pelo Google com gateways, mas é possível criar e referenciar manualmente um certificado SSL gerenciado pelo Google. Para mais informações, consulte Proteger um gateway.

  • HTTPRoute e TLSRoute são compatíveis. TCPRoutes e UDPRoutes não são compatíveis. Para ver uma lista de campos compatíveis com o controlador do gateway do GKE, consulte Recursos do GatewayClass.

  • Os cabeçalhos de solicitação e resposta personalizados com gateway ou redirecionamentos de caminho e substituições de URL com gateway só estão disponíveis no GKE versão 1.27 ou posterior.

  • Para cabeçalhos de solicitação e resposta personalizados com gateway e redirecionamentos de caminho e substituições de URL com gateway, o GatewayClass gke-l7-gxlb não é compatível.

  • Ao configurar cabeçalhos da solicitação personalizados do HTTPRoute, a variávelGoogle Cloud origin_request_header não é compatível. Para configurar o CORS, use o tipo de filtro CORS.

  • As limitações doGoogle Cloud balanceador de carga de aplicativo clássico se aplicam ao gateway do GKE. Além disso, não é possível configurar um cabeçalho de resposta do host personalizado no serviço de back-end.

  • Os redirecionamentos de caminho e substituições de URL são mutuamente exclusivos. Não é possível usar os dois filtros ao mesmo tempo nas mesmas regras.

  • O Cloud Load Balancing não permite redirecionar o tráfego para uma porta diferente. Para ver uma lista de campos compatíveis com o controlador do gateway do GKE, consulte Recursos do GatewayClass.

  • O gateway do GKE não é compatível com caracteres curinga e URLs dinâmicos. Expressões regulares não são compatíveis com as GatewayClasses gke-l7-gxlb e gke-l7-gxlb-mc. Para mais informações, consulte Configurar a correspondência de expressões regulares.

  • Se você especificar um gateway com uma classe de gateway externo regional, o controlador provisionará um endereço IP interno em vez do endereço externo. Para saber como usar um endereço nomeado com o balanceador de carga de aplicativo externo regional, consulte Implantar um gateway externo regional.

  • O gateway usa NEGs autônomos para provisionar grupos de endpoints de rede. Para garantir que o controlador do Gateway reconcilie corretamente a configuração do balanceador de carga, não é possível modificar a anotação cloud.google.com/neg de um Serviço que faz parte do gateway.

  • O gateway do GKE não permite referência a um Serviço que também é referenciado por um Ingress do GKE.

  • Quando um gateway é configurado para provisionar um endereço IP, não é possível alterar o Gateway.spec.gatewayClass. Para garantir que o Gateway Controller reconcilie corretamente o balanceador de carga, exclua o gateway que já existe e reimplante o manifesto com o valor gatewayClass atualizado.

  • A anotação networking.gke.io/app-protocols não é compatível. Use o campo appProtocol para ter o mesmo resultado.

  • Se você usar o gateway do GKE com external-dns e o estado de integridade do gateway não estiver íntegro, por padrão, todos os registros DNS associados ao gateway serão excluídos das suas zonas de DNS.

    Prática recomendada:

    Ao executar external-dns, defina a flag policy=upsert-only. Essa configuração ajuda a evitar a exclusão de registros DNS.

  • Se uma porta for removida de um Serviço que o Gateway do GKE referencia por uma rota, a anotação de NEG independente no Serviço também precisará atualizar o controlador de NEG independente no Serviço para remover essa porta. Caso contrário, o controlador de NEG vai parar de sincronizar os endpoints de pod para esse Serviço. Para mais detalhes, consulte O controlador de NEG para de gerenciar endpoints quando a porta é removida do serviço.

  • As implantações que usam gateways de vários clusters (MCG, na sigla em inglês) com clusters zonais estão sujeitas a interrupções de serviço durante upgrades de cluster. Esse problema ocorre porque um mecanismo legado de descoberta de grupo de endpoints de rede (NEG, na sigla em inglês) pode informar incorretamente zero back-ends quando o plano de controle do cluster zonal está temporariamente indisponível. Uma correção de longo prazo está em andamento. Para evitar esse ponto único de falha, use clusters regionais do GKE com o MCG.

Ativar a API Gateway no cluster

Antes de usar os recursos de gateway no GKE, seu cluster precisa ter a API Gateway ativada.

Antes de atualizar um cluster do GKE para ativar a API Gateway, verifique se os requisitos mínimos são atendidos antes de prosseguir com a atualização.

Para ativar a API Gateway em um cluster do GKE atual (Autopilot ou Standard), use o comando a seguir. Essa operação pode levar até 45 minutos para que o cluster reconcilie e instale o CustomResourceDefinition.

gcloud container clusters update CLUSTER_NAME \
    --location=CLUSTER_LOCATION\
    --gateway-api=standard

Substitua:

A flag --gateway-api=standard instrui o GKE a instalar os CRDs do canal padrão da API Gateway com o cluster.

Verifique o cluster

Depois de criar ou fazer upgrade do cluster, o controlador de gateway do GKE instala automaticamente o GatewayClasses. Pode levar alguns minutos para que o controlador reconheça os CRDs e instale o GatewayClasses.

  1. Confirme se a API Gateway está ativada no plano de controle do GKE:

    gcloud container clusters describe CLUSTER_NAME \
      --location=CLUSTER_LOCATION \
      --format json
    

    A resposta será semelhante a esta: Se essa saída estiver vazia, execute novamente o comando de atualização do cluster.

    "networkConfig": {
      ...
      "gatewayApiConfig": {
        "channel": "CHANNEL_STANDARD"
      },
      ...
    },
    
  2. Confirme se os GatewayClasses estão instalados no cluster:

    kubectl get gatewayclass
    

    O resultado será assim:

    NAME                             CONTROLLER                  ACCEPTED   AGE
    gke-l7-global-external-managed   networking.gke.io/gateway   True       16h
    gke-l7-regional-external-managed networking.gke.io/gateway   True       16h
    gke-l7-gxlb                      networking.gke.io/gateway   True       16h
    gke-l7-rilb                      networking.gke.io/gateway   True       16h
    

Para entender os recursos de cada GatewayClass do GKE, consulte Recursos do GatewayClass.

Somente GatewayClasses de cluster único são instaladas automaticamente. Para instalar e usar as GatewayClasses de vários clusters para o balanceamento de carga interno e externo de vários clusters, consulte Como ativar gateways de vários clusters.

Implantar um gateway interno

Um gateway interno expõe aplicativos que só podem ser acessados pela VPC ou pelas redes conectadas a ela.

Implantar um gateway interno regional

O exemplo a seguir mostra como implantar um gateway interno regional que permite a comunicação eficiente e segura entre serviços em uma região geográfica específica.

Configurar uma sub-rede somente proxy

É preciso configurar uma sub-rede somente proxy antes de criar um gateway que use um balanceador de carga de aplicativo interno. Cada região de uma VPC em que você usa balanceadores de carga de aplicativo internos precisa ter uma sub-rede somente proxy. Essa sub-rede fornece endereços IP internos aos proxies do balanceador de carga.

  1. Criar uma sub-rede somente proxy:

    gcloud compute networks subnets create SUBNET_NAME \
        --purpose=REGIONAL_MANAGED_PROXY \
        --role=ACTIVE \
        --region=COMPUTE_REGION \
        --network=VPC_NETWORK_NAME \
        --range=CIDR_RANGE
    

    Se você estiver implantando um recurso de gateway regional (gke-l7-rilb ou gke-l7-regional-external-managed) em um cluster IPv6 de pilha única, configure uma sub-rede somente proxy de pilha dupla com a flag --stack-type=IPV4_IPV6. Esse requisito se aplica aos recursos de gateway IPv4 e IPv6 para que os proxies do balanceador de carga possam se comunicar com os pods de back-end IPv6. As sub-redes somente proxy IPv6 de pilha única (criadas com a flag --stack-type=IPV6_ONLY) não são compatíveis, e a rede VPC precisa ter um intervalo IPv6 de ULA interno ativado (com a flag --enable-ula-internal-ipv6):

    gcloud compute networks subnets create SUBNET_NAME \
        --purpose=REGIONAL_MANAGED_PROXY \
        --role=ACTIVE \
        --region=COMPUTE_REGION \
        --network=VPC_NETWORK_NAME \
        --range=CIDR_RANGE \
        --stack-type=IPV4_IPV6
    

    Substitua:

    • SUBNET_NAME: o nome da sub-rede somente proxy.
    • COMPUTE_REGION: a região da sub-rede somente proxy.
    • VPC_NETWORK_NAME: o nome da rede VPC em que você cria essa sub-rede somente proxy. Precisa ser a mesma rede VPC em que o cluster do GKE está localizado e em que o gateway foi implantado. Isso é importante para uma comunicação perfeita entre o balanceador de carga e os serviços de back-end.
    • CIDR_RANGE: o intervalo de endereços IPv4 principal da sub-rede. Esse valor precisa ser um intervalo CIDR IPv4, mesmo para uma sub-rede somente proxy de pilha dupla (IPV4_IPV6), porque o Compute Engine aloca automaticamente o intervalo de endereços IPv6. Use uma máscara de sub-rede de até /26 de comprimento para que ao menos 64 endereços IPv4 estejam disponíveis para os proxies na região. A máscara de sub-rede recomendada é /23.
  2. Verifique sua sub-rede somente proxy:

    gcloud compute networks subnets describe SUBNET_NAME \
        --region=COMPUTE_REGION
    

    A saída é semelhante à seguinte (para uma sub-rede somente proxy de pilha dupla, a saída inclui os campos internalIpv6Prefix, ipv6AccessType e ipv6GceEndpoint):

    ...
    gatewayAddress: 10.1.1.1
    internalIpv6Prefix: fd20:1d14:f522:2:0:0:0:0/64
    ipCidrRange: 10.1.1.0/24
    ipv6AccessType: INTERNAL
    ipv6GceEndpoint: VM_AND_FR
    kind: compute#subnetwork
    name: proxy-subnet
    network: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/networks/default
    privateIpGoogleAccess: false
    privateIpv6GoogleAccess: DISABLE_GOOGLE_ACCESS
    purpose: REGIONAL_MANAGED_PROXY
    region: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION
    role: ACTIVE
    selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION/subnetworks/proxy-subnet
    stackType: IPV4_IPV6
    state: READY
    

Criar um gateway

Um recurso de gateway representa um plano de dados que roteia o tráfego no Kubernetes. Um Gateway pode representar vários tipos diferentes de balanceamento de carga e roteamento, dependendo do GatewayClass que o deriva. Para saber mais sobre o recurso Gateway, consulte a descrição desse recurso ou a especificação da API.

Nesse caso, o administrador do cluster do GKE quer criar um gateway que possa ser usado por equipes diferentes para expor aplicativos internamente. O administrador implanta o gateway e as equipes de aplicativo implantam as rotas de maneira independente e as anexam a esse gateway.

  1. Salve o seguinte manifesto de gateway em um arquivo chamado gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
       name: internal-http
    spec:
      # Specify an existing GatewayClass.
      gatewayClassName: gke-l7-rilb
      listeners:
      # Listen for HTTP traffic on port 80.
      - name: http
        protocol: HTTP
        port: 80
    

    Esse manifesto inclui os seguintes campos:

    • gatewayClassName: gke-l7-rilb especifica o GatewayClass que deriva este gateway. gke-l7-rilb corresponde ao balanceador de carga de aplicativo interno.
    • port: 80 especifica que o gateway expõe apenas a porta 80 para detectar o tráfego HTTP.

    Esse gateway está configurado para processar o tráfego HTTP apenas na porta 80. Ele não é compatível com HTTPS (porta 443) por padrão. Se você tentar se conectar por HTTPS, a solicitação poderá falhar.

  2. Para implantar o gateway no cluster:

    kubectl apply -f gateway.yaml
    
  3. Verifique se o gateway foi implantado corretamente. Pode levar alguns minutos para implantar todos os recursos.

    kubectl describe gateways.gateway.networking.k8s.io internal-http
    

    O resultado será o seguinte:

    Name:         internal-http
    Namespace:    default
    Spec:
      Gateway Class Name:  gke-l7-rilb
      Listeners:
        Allowed Routes:
          Kinds:
            Group:  gateway.networking.k8s.io
            Kind:   HTTPRoute
          Namespaces:
            From:  Same
        Name:      http
        Port:      80
        Protocol:  HTTP
     Status:
       Addresses:
         Type:   IPAddress
         Value:  192.168.1.14
       Conditions:
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:               The OSS Gateway API has deprecated this condition, do not depend on it.
         Observed Generation:   1
         Reason:                Scheduled
         Status:                True
         Type:                  Scheduled
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:
         Observed Generation:   1
         Reason:                Accepted
         Status:                True
         Type:                  Accepted
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:
         Observed Generation:   1
         Reason:                Programmed
         Status:                True # Indicates that the Gateway is ready.
         Type:                  Programmed
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:               The OSS Gateway API has altered the "Ready" condition semantics and reserved it for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
         Observed Generation:   1
         Reason:                Ready
         Status:                True
         Type:                  Ready
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:
         Observed Generation:   1
         Reason:                Healthy
         Status:                True
         Type:                  networking.gke.io/GatewayHealthy
    Events:
      Type    Reason  Age                From                       Message
      ----    ------  ----               ----                       -------
      Normal  ADD     92s                networking.gke.io/gateway  test/internal-http
      Normal  UPDATE  45s (x3 over 91s)  networking.gke.io/gateway  test/internal-http
      Normal  SYNC    45s                networking.gke.io/gateway  SYNC on test/internal-http was a success
    

    Nesta saída, o status de True para a condição Programmed indica que o gateway está pronto.

    Neste ponto, um gateway implantado no cluster já provisionou um balanceador de carga e um endereço IP. No entanto, o gateway não tem rotas e não sabe como enviar tráfego para os back-ends. Sem as rotas, todo o tráfego vai para um back-end padrão, que retorna um HTTP 404. Em seguida, implante um aplicativo e rotas que informam ao gateway como acessar os back-ends do aplicativo.

Implante os aplicativos de demonstração

As equipes de aplicativos podem implantar os próprios aplicativos e rotas independentemente da implantação dos gateways. Em alguns casos, a equipe de aplicativos pode querer ser proprietária do gateway e implantá-lo por conta própria como um recurso dedicado aos aplicativos deles. Consulte Vinculação de rotas para ver diferentes modelos de propriedade de gateways e rotas. No entanto, neste exemplo, a equipe da loja implanta o aplicativo e um HTTPRoute associado para expor o aplicativo dela pelo gateway internal-http criado na seção anterior.

O recurso HTTPRoute tem muitos campos configuráveis para correspondência de tráfego. Para uma explicação dos campos do HTTPRoute, consulte a especificação da API.

  1. Para implantar o aplicativo da loja (store-v1, store-v2 e store-german) no cluster:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
    

    Isso cria três implantações e três serviços, chamados store-v1, store-v2 e store-german.

  2. Para validar a implantação do aplicativo:

    kubectl get pod
    

    A saída será semelhante à seguinte depois que o aplicativo estiver em execução:

    NAME                        READY   STATUS    RESTARTS   AGE
    store-german-66dcb75977-5gr2n   1/1     Running   0          38s
    store-v1-65b47557df-jkjbm       1/1     Running   0          14m
    store-v2-6856f59f7f-sq889       1/1     Running   0          14m
    
  3. Para confirmar que os serviços também foram implantados:

    kubectl get service
    

    A saída mostra um serviço para cada implantação de loja:

    NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    store-german   ClusterIP   10.48.3.183   <none>        8080/TCP   4s
    store-v1       ClusterIP   10.48.2.224   <none>        8080/TCP   5s
    store-v2       ClusterIP   10.48.4.48    <none>        8080/TCP   5s
    

Implante o HTTPRoute

Os recursos de rota definem regras específicas do protocolo que mapeiam o tráfego de um gateway para os back-ends do Kubernetes. O recurso HTTPRoute faz a correspondência e filtragem de tráfego HTTP e HTTPS e é compatível com todas os GatewayClasses gke-l7.

Nesta seção, você verá como implantar um HTTPRoute, que programa o gateway com as regras de roteamento necessárias para alcançar o aplicativo da loja.

  1. Salve o seguinte manifesto HTTPRoute em um arquivo chamado store-route.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store
    spec:
      # Attach the HTTPRoute to a Gateway.
      parentRefs:
      - kind: Gateway
        name: internal-http
      # Route requests that have `store.example.com` in the Host header.
      hostnames:
      - "store.example.com"
      rules:
      # Send requests with the `env: canary` header to the `store-v2` Service.
      - matches:
        - headers:
          - name: env
            value: canary
        backendRefs:
        - name: store-v2
          port: 8080
      # Send requests with `/de` in the path to the `store-german` Service.
      - matches:
        - path:
            value: /de
        backendRefs:
        - name: store-german
          port: 8080
      # Send unmatched requests to the store-v1 Service.
      - backendRefs:
        - name: store-v1
          port: 8080
    
  2. Implante o HTTPRoute no cluster:

    kubectl apply -f store-route.yaml
    

    O HTTPRoute store está vinculado ao gateway internal-http usando a propriedade parentRefs: Essas regras de roteamento são configuradas no balanceador de carga subjacente, como neste diagrama:

    As regras de roteamento configuradas pelo HTTPRoute da loja

    Essas regras de roteamento processarão o tráfego HTTP da seguinte maneira:

    • O tráfego para store.example.com/de vai para o Serviço store-german.
    • O tráfego para store.example.com com o cabeçalho HTTP "env: canary" vai para o Serviço store-v2.
    • O tráfego restante para store.example.com vai para o serviço store-v1.
  3. Verifique se o HTTPRoute foi implantado:

    kubectl describe httproute store
    

    O resultado será assim:

    Name:         store
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  gateway.networking.k8s.io/v1
    Kind:         HTTPRoute
    # Multiple lines are omitted here.
    Spec:
      Hostnames:
        store.example.com
      Parent Refs:
        Group:  gateway.networking.k8s.io
        Kind:   Gateway
        Name:   internal-http
      Rules:
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v1
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v2
          Port:    8080
          Weight:  1
        Matches:
          Headers:
            Name:   env
            Type:   Exact
            Value:  canary
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-german
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /de
    Status:
      Parents:
        Conditions:
          Last Transition Time:  2022-11-01T04:18:52Z
          Message:
          Reason:                Accepted
          Status:                True
          Type:                  Accepted
          Last Transition Time:  2022-11-01T04:18:52Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   internal-http
    Events:
      Type    Reason  Age                From                   Message
      ----    ------  ----               ----                   -------
      Normal  ADD     24m                sc-gateway-controller  default/store
      Normal  SYNC    16m (x4 over 23m)  sc-gateway-controller  Bind of HTTPRoute "default/store" to ParentRef {Group:       gateway.networking.k8s.io",
      # Multiple lines are omitted here.
    
  4. Verifique se o HTTPRoute está vinculado ao Gateway:

    kubectl describe gateway
    

    O resultado será assim:

    Name:         internal-http
    Namespace:    default
    Labels:       <none>
    <...>
    Status:
      Addresses:
        Type:   IPAddress
        Value:  10.128.15.203
      Conditions:
        Last Transition Time:  2022-11-01T03:47:01Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2022-11-01T03:47:01Z
        Message:
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2022-11-01T03:47:01Z
          Message:
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    http
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
          <...>
    

Enviar tráfego para o aplicativo

Agora que o gateway, a rota e o aplicativo estão implantados no cluster, é possível transmitir o tráfego para o aplicativo. O gateway está configurado para exibir tráfego HTTP apenas na porta 80. As solicitações feitas com HTTPS podem falhar, a menos que o TLS tenha sido configurado separadamente.

  1. Recuperar o endereço IP do gateway para enviar tráfego ao aplicativo:

    kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}"
    

    A saída é um endereço IP.

  2. Envie tráfego para esse endereço IP de uma instância de máquina virtual (VM) conectada ao cluster. Isso é necessário porque o gateway tem um endereço IP interno. Ele só é acessível na rede VPC. Como internal-http é um balanceador de carga regional, a VM do cliente precisa estar na mesma região que o cluster do GKE.

    Crie uma VM de teste na mesma rede VPC e região:

    gcloud compute instances create test-vm \
        --zone=COMPUTE_ZONE \
        --network=VPC_NETWORK_NAME
    

    Conecte-se à VM usando SSH:

    gcloud compute ssh test-vm --zone=COMPUTE_ZONE
    

    No shell da VM, faça uma solicitação para store.example.com:

    curl http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    Substitua GATEWAY_IP_ADDRESS pelo endereço IP da etapa anterior.

    A saída do app de demonstração mostra informações sobre o local em que o app está em execução:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v1-84b47c7f58-pmgmk",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:31:17",
      "zone": "ZONE_NAME"
    }
    
  3. Teste a correspondência de caminho acessando a versão em alemão do serviço da loja em store.example.com/de:

    curl http://store.example.com/de --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    A resposta confirma que a solicitação foi exibida por um pod store-german:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "Gutentag!", 
      "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal",
      "pod_name": "store-german-5cb6474c55-lq5pl", 
      "pod_name_emoji": "🧞‍♀",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:35:37",
      "zone": "ZONE_NAME"
    }
    
  4. Por fim, use o cabeçalho HTTP env: canary para enviar o tráfego à versão canário do serviço de armazenamento:

    curl -H "env: canary" http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    A resposta confirma que a solicitação foi exibida por um pod store-v2:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v2", 
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v2-5788476cbd-s9thb", 
      "pod_name_emoji": "🦰",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:38:26",
      "zone": "ZONE_NAME"
    }
    

Implantar um gateway externo

Um gateway externo expõe aplicativos que podem ser acessados pela Internet ou por redes fora da sua rede VPC. A implantação é semelhante a uma implantação do gateway interno, mas você precisa proteger seus aplicativos porque o gateway é acessível à Internet pública.

Você tem duas opções para criar um gateway externo: um global ou um regional.

  • Gateway externo regional: esse gateway usa um endereço IP regional como o front-end do gateway. O comportamento desse gateway depende do nível de serviço de rede selecionado:
    • Se você escolher o nível de serviço de rede Standard (padrão), o endereço IP regional será anunciado apenas na região local do Compute Google Cloud em que o gateway externo regional está implantado. Os clientes que enviam tráfego para esse endereço IP são roteados pelo ISP local e pela Internet pública antes de chegar à região do Google em que o endereço IP é divulgado.
    • Se você escolher o nível Premium de serviço de rede, o endereço IP regional será anunciado na rede global do Google. Isso significa que o tráfego do cliente entra no backbone global de alta qualidade do Google em um ponto de peering de borda do Google o mais próximo possível do cliente, mesmo que o destino seja um endereço IP regional. Esse local reduz significativamente a latência e melhora o desempenho, minimizando a distância que o tráfego percorre pela Internet pública.
  • Gateway externo global: esse gateway usa um endereço IP global (ou endereço IP anycast) como o front-end do gateway. Esse endereço IP é divulgado em todas as regiões do Google Cloud Compute. Os clientes que enviam tráfego para esse endereço IP anycast são roteados para o local do Google mais próximo em que o endereço IP é divulgado. O gateway externo global só está disponível no Nível de serviço de rede Premium.

Implantar um gateway externo regional

O exemplo a seguir mostra como expor um aplicativo de loja com vários certificados anexados ao gateway externo regional usando certificados autogerenciados e um HTTPRoute.

Criar uma sub-rede proxy para o gateway regional

É preciso configurar uma sub-rede somente proxy antes de criar um gateway que usa um balanceador de carga de aplicativo externo regional. Cada região de uma VPC em que você usa o balanceador de carga de aplicativo externo regional precisa ter uma sub-rede external_managed_proxy. Essa sub-rede fornece endereços IP internos aos proxies do balanceador de carga.

Criar um certificado para proteger o tráfego de clientes

É possível usar um certificado emitido e validado pela autoridade certificadora (AC) ou criar um certificado autoassinado. Para mais informações sobre como criar um certificado, consulte Armazenar um certificado em um Secret do Kubernetes.

Para proteger o tráfego entre os clientes e o gateway regional, use os seguintes métodos:

  • Certificados do Gerenciador de Certificados gerenciados pelo Google ou autogerenciados
  • Certificados SSL regionais autogerenciados
  • Secrets do Kubernetes

Os certificados SSL gerenciados pelo Google ou CertificateMap não são compatíveis com gateways regionais.

Para mais informações, consulte Certificados e balanceadores de carga do Google Cloud .

Criar um gateway HTTP(S) externo regional

  1. Crie um endereço IP estático regional para o balanceador de carga externo.

    gcloud compute addresses create IP_ADDRESS_NAME \
      --region=COMPUTE_REGION \
      --network-tier=STANDARD
    

    Substitua:

    • IP_ADDRESS_NAME: o nome do novo endereço IP estático.
    • COMPUTE_REGION: a região do Compute Engine em que o cluster está em execução.
  2. Crie um gateway de balanceador de carga de aplicativo externo regional usando um certificado autogerenciado da seguinte maneira e salve o manifesto como regional-gateway.yaml:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: external-regional-http
      spec:
        # Name of an existing GatewayClass.
        gatewayClassName: gke-l7-regional-external-managed
        # Listen for HTTPS traffic on port 443
        listeners:
        - name: https
          protocol: HTTPS
          port: 443
          tls:
            # Terminate the TLS session with the client at the Gateway.
            mode: Terminate
            # Certificates for the Gateway to use to create a new TLS session.
            certificateRefs:
            - name: store-example-com
        # The name of the static IP address of the external load balancer.
        # You can also use the `IPAddress` type to specify the actual IP address.
        addresses:
        - type: NamedAddress
          value: IP_ADDRESS_NAME
    
  3. Aplique o manifesto regional-gateway:

      kubectl apply -f regional-gateway.yaml
    
  4. Verifique a configuração.

      kubectl get gateway
    

    O resultado será assim:

    NAME            CLASS                              ADDRESS         READY   AGE
    external-http   gke-l7-regional-external-managed   35.118.32.224   True    49s
    

    Para ver mais detalhes, use um comando de descrição:

    kubectl describe gateway
    

    O resultado será o seguinte:

    Name:         external-regional-http
    Namespace:    default
    Labels:       <none>
    ...
    Spec:
      Gateway Class Name:  gke-l7-regional-external-managed
      Listeners:
        Allowed Routes:
          Namespaces:
            From:  Same
        Name:      https
        Port:      443
        Protocol:  HTTPS
        Tls:
          Certificate Refs:
            Group:
            Kind:   Secret
            Name:   store-example-com
          Mode:     Terminate
      ...
    

Implante os aplicativos de demonstração

As equipes de aplicativos podem implantar os próprios aplicativos e rotas independentemente da implantação dos gateways. Em alguns casos, a equipe de aplicativos pode querer ser proprietária do gateway e implantá-lo por conta própria como um recurso dedicado aos aplicativos deles. Consulte Vinculação de rotas para ver diferentes modelos de propriedade de gateways e rotas. No entanto, neste exemplo, a equipe da loja implanta o aplicativo e um HTTPRoute associado para expor o aplicativo dela pelo gateway external-http criado na seção anterior.

Para mais informações sobre os campos de HTTPRoute, consulte a especificação da API.

  1. Implante o aplicativo de amostra no cluster:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
    

    Esse aplicativo cria três implantações e três serviços, chamados store-v1, store-v2 e store-german.

  2. Para validar a implantação do aplicativo:

    kubectl get pod
    

    O resultado será assim:

    NAME                            READY   STATUS    RESTARTS   AGE
    store-german-66dcb75977-5gr2n   1/1     Running   0          38s
    store-v1-65b47557df-jkjbm       1/1     Running   0          14m
    store-v2-6856f59f7f-sq889       1/1     Running   0          14m
    
  3. Verifique se os serviços foram implantados:

    kubectl get service
    

    O resultado será assim:

    NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    store-german   ClusterIP   10.48.3.183   <none>        8080/TCP   4s
    store-v1       ClusterIP   10.48.2.224   <none>        8080/TCP   5s
    store-v2       ClusterIP   10.48.4.48    <none>        8080/TCP   5s
    

Criar um HTTPRoute

Os recursos de rota definem regras específicas do protocolo que mapeiam o tráfego de um gateway para os back-ends do Kubernetes. O recurso HTTPRoute faz a correspondência e filtragem de tráfego HTTP e HTTPS e é compatível com todas os GatewayClasses gke-l7-*.

Nesta seção, você implantará um HTTPRoute, que configura o Gateway com regras de roteamento necessárias para acessar o aplicativo de amostra.

  1. Salve o seguinte manifesto em um arquivo chamado store-route-external.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
    spec:
      parentRefs:
      # Bind the route to the 'external-http' Gateway.
      - kind: Gateway
        name: external-http
      hostnames:
      - "store.example.com"
      rules:
      # Default rule for store.example.com that sends traffic to the store-v1 service.
      - backendRefs:
        - name: store-v1
          port: 8080
      # Match requests with the "env: canary" header and send them to the store-v2 service.
      - matches:
        - headers:
          - name: env
            value: canary
        backendRefs:
        - name: store-v2
          port: 8080
      # Match requests with the path "/de" and sends them to the store-german service.
      - matches:
        - path:
            value: /de
        backendRefs:
        - name: store-german
          port: 8080
    

    Esse manifesto descreve um HTTPRoute que faz referência ao Gateway external-http.

  2. Aplique o manifesto ao cluster:

    kubectl apply -f store-route-external.yaml
    

    O HTTPRoute store está vinculado ao gateway external-http usando a propriedade parentRefs: Veja no diagrama a seguir as regras de roteamento configuradas no balanceador de carga subjacente:

    As regras de roteamento configuradas pelo HTTPRoute da loja

    As regras de roteamento processam tráfego HTTP da seguinte maneira:

    • Tráfego para store.example.com/de, trajeto para o serviço store-german.
    • O tráfego para store.example.com com o cabeçalho HTTP "env: canary" encaminha para o serviço store-v2.
    • O tráfego restante para os trajetos store.example.com é enviado para o serviço store-v1.
  3. Verifique se o HTTPRoute foi implantado:

    kubectl describe httproute store-external
    

    O resultado será assim:

    Name:         store-external
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  gateway.networking.k8s.io/v1
    Kind:         HTTPRoute
    # Multiple lines are omitted here.
    Spec:
      Hostnames:
        store.example.com
      Parent Refs:
        Group:  gateway.networking.k8s.io
        Kind:   Gateway
        Name:   external-http
      Rules:
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v1
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v2
          Port:    8080
          Weight:  1
        Matches:
          Headers:
            Name:   env
            Type:   Exact
            Value:  canary
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-german
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /de
    Status:
      Parents:
        # This section shows the status of this route in relation to each Gateway attached.
        Conditions:
          Last Transition Time:  2022-11-01T05:42:31Z
          Message:
          Reason:                Accepted
          Status:                True # Means that the Gateway has validated and accepted this route's configuration.
          Type:                  Accepted
          Last Transition Time:  2022-11-01T05:43:18Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   external-http
    Events:
      Type     Reason  Age    From                   Message
      ----     ------  ----   ----                   -------
      Normal   ADD     2m48s  sc-gateway-controller  default/store-external
      Normal  SYNC  61s (x3 over 2m27s)  sc-gateway-controller  Bind of HTTPRoute "default/store-external" to ParentRef Group:       "gateway.networking.k8s.io",
      ...
    
  4. Verifique se o HTTPRoute está vinculado ao Gateway:

    kubectl describe gateway external-http
    

    O resultado será assim:

    Name:         external-http
    Namespace:    default
    Labels:       <none>
    # Multiple lines are omitted here.
    Status:
      Addresses:
        Type:   IPAddress
        Value:  34.149.207.45
      Conditions:
        Last Transition Time:  2022-11-01T05:37:21Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2022-11-01T05:43:18Z
        Message:
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2022-11-01T05:43:18Z
          Message:
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    https
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
          # Multiple lines are omitted here.
    

Enviar tráfego para o aplicativo

Agora que o gateway, a rota e o aplicativo estão implantados no cluster, é possível transmitir o tráfego para o aplicativo.

  1. Consiga o endereço IP do gateway:

    kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"
    

    A saída é um endereço IP.

  2. Crie uma VM:

    gcloud cloud-shell ssh
    
  3. Enviar tráfego para o endereço IP do gateway a partir da VM. Defina o cabeçalho do host manualmente, porque você não é o proprietário do nome do host example.com.

    curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

    Substitua GATEWAY_IP_ADDRESS pelo endereço IP do gateway da etapa anterior.

    cacert.pem: o arquivo de certificado que você gerou. Salve esse arquivo na máquina que você usa para se conectar ao gateway.

    A saída mostra informações do app de demonstração sobre o local em que ele está em execução:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v1-84b47c7f58-pmgmk",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-09-25T13:31:17",
      "zone": "us-central1-a"
    }
    
  4. Teste a correspondência de caminho acessando a versão em alemão do serviço store da loja em store.example.com/de:

    curl https://store.example.com/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

    A resposta confirma que a solicitação foi exibida por um pod store-german:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "Gutentag!",
      "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal",
      "pod_name": "store-german-5cb6474c55-lq5pl",
      "pod_name_emoji": "🧞‍♀",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-09-25T13:35:37",
      "zone": "us-central1-a"
    }
    
  5. Envie o tráfego para a versão canário do serviço store usando o cabeçalho HTTP env: canary:

    curl -H "env: canary" https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

    A resposta confirma que a solicitação foi exibida por um pod store-v2:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v2",
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v2-5788476cbd-s9thb",
      "pod_name_emoji": "👩🏿",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-09-25T13:38:26",
      "zone": "us-central1-a"
    }
    

Implantar um gateway externo global

O exemplo a seguir mostra como expor um aplicativo de loja com vários certificados anexados ao gateway externo global e agrupados em um mapa de certificados usando o Gerenciador de certificados e um HTTPRoute.

Criar um mapa de certificados

O Google recomenda usar o Gerenciador de certificados para gerenciar os certificados quando você precisar de 15 ou mais certificados por gateway ou quando precisar usar certificados curinga.

Também é possível proteger o gateway externo usando secrets do Kubernetes ou certificados SSL gerenciados pelo Google. Para mais informações, consulte Segurança do gateway.

Nesta seção, você cria certificados usando o Gerenciador de certificados para proteger os aplicativos em execução no cluster.

  1. Ative a API Certificate Manager:

    gcloud services enable certificatemanager.googleapis.com
    
  2. Criar um mapa de certificados:

    gcloud beta certificate-manager maps create store-example-com-map
    
  3. Carregue suas chaves e seu certificado gerenciado pelo Google em um Certificado:

    gcloud beta certificate-manager certificates create store-example-com-cert \
        --certificate-file="CERTIFICATE_FILE" \
        --private-key-file="PRIVATE_KEY_FILE"
    

    Substitua:

    • CERTIFICATE_FILE: o nome do arquivo de certificado. O arquivo precisa ter a extensão .pem. Por exemplo, cert.pem.
    • PRIVATE_KEY_FILE: o nome do arquivo da chave privada.

    Para mais informações, consulte Como criar uma chave privada e um certificado.

  4. Crie um CertificateMapEntry que atribua o certificado ao mapa de certificados:

    gcloud beta certificate-manager maps entries create store-example-com-map-entry \
        --map=store-example-com-map \
        --hostname=store.example.com \
        --certificates=store-example-com-cert
    

Para saber como proteger um gateway usando outras fontes de certificados, como secrets do Kubernetes ou certificados SSL, consulte Proteger um gateway.

Criar um gateway

Um recurso de gateway representa um plano de dados que roteia o tráfego no Kubernetes. Um Gateway pode representar muitos tipos diferentes de balanceamento de carga e roteamento, dependendo da GatewayClass usada.

Para saber mais sobre o recurso Gateway, consulte a descrição do recurso Gateway ou a especificação da API.

Nesta seção, você vai criar um gateway. As equipes de aplicativos podem usar o gateway para expor seus aplicativos à Internet implantando as rotas de maneira independente e anexando-as com segurança ao gateway.

  1. Salve o seguinte manifesto em um arquivo chamado gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      # This GatewayClass uses a global external Application Load Balancer.
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
    
    

    Este manifesto descreve um Gateway com os seguintes campos:

    • gatewayClassName: gke-l7-global-external-managed: especifica o GatewayClass para esse gateway. Esta classe de gateway usa um balanceador de carga de aplicativo externo global.
    • protocol: HTTPS e port: 443: especifica que o gateway expõe a porta 443 para o tráfego HTTPS. Esses campos ativam o TLS.
    • networking.gke.io/certmap: store-example-com-map: especifica o nome do mapa de certificados no Certificate Manager.

    Não há uma seção TLS porque o TLS está configurado com o Gerenciador de certificados usando a anotação networking.gke.io/certmap.

  2. Aplique o manifesto ao cluster:

    kubectl apply -f gateway.yaml
    

    Pode levar alguns minutos para o GKE implantar os recursos.

  3. Verifique se o gateway foi implantado:

    kubectl describe gateway
    

    O resultado será assim:

    Name:         external-http
    Namespace:    default
    Labels:       <none>
    ...
    Spec:
      Gateway Class Name:  gke-l7-global-external-managed
      Listeners:
        Allowed Routes:
          Namespaces:
            From:  Same
        Name:      https
        Port:      443
        Protocol:  HTTPS
        Tls:
          Certificate Refs:
            Group:
            Kind:   Secret
            Name:   store-example-com
          Mode:     Terminate
     ...
    

    Esta saída mostra que o gateway implantado no cluster tem um balanceador de carga e um endereço IP público. O gateway não tem rotas, o que significa que não pode enviar tráfego para back-ends. Sem as rotas, todo o tráfego vai para um back-end padrão, que retorna um HTTP 404. Na próxima seção, você implantará rotas, que instrui o gateway a enviar tráfego para back-ends.

Implantar o aplicativo de demonstração

É possível implantar aplicativos e rotas independentemente da implantação de gateways.

Para mais informações sobre como implantar os aplicativos de demonstração, consulte este link.

Criar um HTTPRoute

É preciso criar um HTTPRoute para fazer a correspondência e a filtragem de tráfego HTTP e HTTPS.

Enviar tráfego para o aplicativo

Depois de implantar o aplicativo e criar HTTPRoutes, é possível transmitir tráfego para ele.

Para mais informações sobre como enviar tráfego para o aplicativo, consulte este link.

Implantar um gateway externo regional

O exemplo a seguir mostra como expor um aplicativo de loja com vários certificados anexados ao gateway externo regional usando certificados autogerenciados e um HTTPRoute.

Criar uma sub-rede proxy para o gateway regional

É preciso configurar uma sub-rede somente proxy antes de criar um gateway que usa um balanceador de carga de aplicativo externo regional. Cada região de uma VPC em que você usa o balanceador de carga de aplicativo externo regional precisa ter uma sub-rede external_managed_proxy. Essa sub-rede fornece endereços IP internos aos proxies do balanceador de carga.

Criar um certificado para proteger o tráfego de clientes

É possível usar um certificado emitido e validado pela autoridade certificadora (AC) ou criar um certificado autoassinado. Para mais informações sobre como criar um certificado, consulte Armazenar um certificado em um Secret do Kubernetes.

Para proteger o tráfego entre os clientes e o gateway regional, use os seguintes métodos:

  • Certificados do Gerenciador de Certificados gerenciados pelo Google ou autogerenciados
  • Certificados SSL regionais autogerenciados
  • Secrets do Kubernetes

Os certificados SSL gerenciados pelo Google ou CertificateMap não são compatíveis com gateways regionais.

Para mais informações, consulte Certificados e balanceadores de carga do Google Cloud .

Criar um gateway HTTP(S) externo regional

  1. Crie um endereço IP estático regional para o balanceador de carga externo.

    gcloud compute addresses create IP_ADDRESS_NAME \
      --region=COMPUTE_REGION \
      --network-tier=STANDARD
    

    Substitua:

    • IP_ADDRESS_NAME: o nome do novo endereço IP estático.
    • COMPUTE_REGION: a região do Compute Engine em que o cluster está em execução.
  2. Crie um gateway de balanceador de carga de aplicativo externo regional usando um certificado autogerenciado da seguinte maneira e salve o manifesto como regional-gateway.yaml:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: external-regional-http
      spec:
        # Name of an existing GatewayClass.
        gatewayClassName: gke-l7-regional-external-managed
        # Listen for HTTPS traffic on port 443
        listeners:
        - name: https
          protocol: HTTPS
          port: 443
          tls:
            # Terminate the TLS session with the client at the Gateway.
            mode: Terminate
            # Certificates for the Gateway to use to create a new TLS session.
            certificateRefs:
            - name: store-example-com
        # The name of the static IP address of the external load balancer.
        # You can also use the `IPAddress` type to specify the actual IP address.
        addresses:
        - type: NamedAddress
          value: IP_ADDRESS_NAME
    
  3. Aplique o manifesto regional-gateway:

      kubectl apply -f regional-gateway.yaml
    
  4. Verifique a configuração.

      kubectl get gateway
    

    O resultado será assim:

    NAME            CLASS                              ADDRESS         READY   AGE
    external-http   gke-l7-regional-external-managed   35.118.32.224   True    49s
    

    Para ver mais detalhes, use um comando de descrição:

    kubectl describe gateway
    

    O resultado será assim:

    Name:         external-regional-http
    Namespace:    default
    Labels:       <none>
    ...
    Spec:
      Gateway Class Name:  gke-l7-regional-external-managed
      Listeners:
        Allowed Routes:
          Namespaces:
            From:  Same
        Name:      https
        Port:      443
        Protocol:  HTTPS
        Tls:
          Certificate Refs:
            Group:
            Kind:   Secret
            Name:   store-example-com
          Mode:     Terminate
      ...
    

Implantar o aplicativo de demonstração

É possível implantar aplicativos e rotas independentemente da implantação de gateways.

Para mais informações sobre como implantar os aplicativos de demonstração, consulte este link.

Criar um HTTPRoute

É preciso criar um HTTPRoute para fazer a correspondência e a filtragem de tráfego HTTP e HTTPS.

Enviar tráfego para o aplicativo

Depois de implantar o aplicativo e criar HTTPRoutes, é possível transmitir tráfego para ele.

Para mais informações sobre como enviar tráfego para o aplicativo, consulte este link.

Usar gateways compartilhados

A API Gateway usa recursos separados, gateways e recursos de rota para implantar balanceadores de carga e regras de roteamento. Isso é diferente do Ingress, que combina tudo em um recurso. Ao dividir a responsabilidade entre recursos, o gateway permite que o balanceador de carga e as regras de roteamento dele sejam implantados separadamente e implantados por diferentes usuários ou equipes. Isso permite que gateways se tornem gateways compartilhados que se anexam a muitas rotas diferentes, que podem ser gerenciadas por equipes independentes e de propriedade total delas, mesmo em namespaces diferentes.

Implantar rotas em um gateway compartilhado

Este exemplo se baseia no gateway internal-http implantado em Implantar um gateway interno.

Neste exemplo, a equipe do site implanta o aplicativo dela, os serviços e um HTTPRoute correspondente ao tráfego do gateway a esses serviços.

  1. Implantar o aplicativo de exemplo:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/site.yaml
    
  2. Salve o seguinte manifesto em um arquivo chamado site-route-internal.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: site-internal
    spec:
      # Attach the HTTPRoute to the `internal-http` Gateway.
      parentRefs:
      - kind: Gateway
        name: internal-http
      # Route requests that have `site.example.com` in the Host header.
      hostnames:
      - "site.example.com"
      # Send all requests to the `site-v1` Service.
      rules:
      - backendRefs:
        - name: site-v1
          port: 8080
    

    Esse manifesto descreve um HTTPRoute que corresponde a todo o tráfego de site.example.com e o encaminha ao serviço site-v1.

  3. Aplique o manifesto ao cluster:

    kubectl apply -f site-route-internal.yaml
    
  4. Verifique se o HTTPRoute está vinculado ao Gateway:

    kubectl describe httproute.gateway.networking.k8s.io site-internal
    

    O resultado será assim:

    Status:
      Parents:
        Conditions:
          Last Transition Time:  2023-01-09T15:05:43Z
          Message:
          Reason:                Accepted
          Status:                True
          Type:                  Accepted
          Last Transition Time:  2023-01-09T15:05:43Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   internal-http
          ...
    

    Se a condição Accepted do gateway for True, o HTTPRoute foi vinculado corretamente ao gateway. Para saber mais sobre o campo "Status", consulte Status da rota.

  5. Verifique se o tráfego para o gateway é roteado corretamente:

    curl -H "host: site.example.com" GATEWAY_IP_ADDRESS
    curl -H "host: store.example.com" GATEWAY_IP_ADDRESS
    

    Substitua GATEWAY_IP_ADDRESS pelo endereço IP do gateway interno.

    Use uma máquina virtual (VM) na mesma VPC que o gateway.

    O resultado será o seguinte:

    {
      "cluster_name": "CLUSTER_NAME",
      "host_header": "site.example.com",
      "metadata": "site-v1",
      "pod_name": "site-v1-5d64fc4d7d-fz6f6",
      "pod_name_emoji": "👩🏼‍🍳",
      "project_id": "PROJECT_ID",
      "timestamp": "2022-11-02T19:07:01",
      "zone": "ZONE_NAME"
    }
    ...
    {
      "cluster_name": "CLUSTER_NAME",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "pod_name": "store-v1-6d8d58d78-vz8pn",
      "pod_name_emoji": "🧝🏻‍♂️",
      "project_id": "PROJECT_ID",
      "timestamp": "2022-11-02T19:07:01",
      "zone": "ZONE_NAME"
    }
    

    Essa saída indica que as solicitações com o cabeçalho de host site.example.com chegam ao serviço site-v1, enquanto as solicitações com o cabeçalho de host store.example.com chegam ao serviço store-v1.

Configurar o nível de rede

É possível especificar o nível de rede e a versão de IP para o endereço de listener temporário de um gateway usando o campo type na matriz addresses[] na definição do gateway. Se você omitir o campo spec.addresses, o controlador de gateway vai provisionar um endereço IP temporário padrão com base no tipo de pilha do cluster (um endereço IPv4 em clusters IPv4 de pilha única e de pilha dupla ou um endereço IPv6 em clusters IPv6 de pilha única quando uma sub-rede compatível estiver disponível). Para recursos de gateway gke-l7-regional-external-managed, omitir o campo spec.addresses resulta em um endereço IPv4 temporário de nível Standard em clusters IPv4 de pilha única e de pilha dupla ou em um endereço IPv6 temporário de nível Premium em clusters IPv6 de pilha única (o nível Standard não é compatível com endereços IPv6).

Em clusters IPv6 de pilha única, ao alocar um endereço IP temporário para um recurso de gateway regional (gke-l7-rilb ou gke-l7-regional-external-managed), o controlador de gateway seleciona a sub-rede na seguinte ordem:

  1. Se um recurso GCPGatewayPolicy anexado ao recurso Gateway especificar o campo spec.default.subnetwork, o endereço IP temporário será alocado dessa sub-rede.
  2. Se nenhuma sub-rede for especificada em um recurso GCPGatewayPolicy e a sub-rede do nó principal do cluster tiver o tipo de acesso IPv6 necessário (INTERNAL para gke-l7-rilb ou EXTERNAL para gke-l7-regional-external-managed), o endereço IP temporário será alocado da sub-rede do nó principal.
  3. Se nenhuma sub-rede compatível estiver disponível, o controlador de gateway vai informar um erro. Para instruções sobre como configurar uma sub-rede personalizada, consulte Requisito de sub-rede IPv6 externa regional em clusters IPv6 internos.

Use os seguintes valores para o campo type:

  • networking.gke.io/premium-ephemeral-ipv4-address: atribui um endereço IPv4 temporário de nível Premium (gke-l7-regional-external-managed).
  • networking.gke.io/standard-ephemeral-ipv4-address: atribui um endereço IPv4 temporário de nível Standard (gke-l7-regional-external-managed).
  • networking.gke.io/premium-ephemeral-ipv6-address: atribui um endereço IPv6 temporário de nível Premium (gke-l7-regional-external-managed).
  • networking.gke.io/ephemeral-ipv4-address/REGION: atribui um endereço IPv4 temporário regional em REGION (gke-l7-rilb e gke-l7-cross-regional-internal-managed-mc).
  • networking.gke.io/ephemeral-ipv6-address/REGION: atribui um endereço IPv6 temporário regional em REGION (gke-l7-rilb).

Para atribuir endereços IP de ambos os níveis de rede ou de ambas as versões de IP (por exemplo, um endereço IPv4 e um endereço IPv6 em um cluster de pilha dupla), especifique vários tipos no campo addresses.

O exemplo a seguir mostra como fazer com que o Google Cloud atribua um endereço IP de nível Premium a um gateway. Para provisionar um endereço IPv4 de nível Standard, use networking.gke.io/standard-ephemeral-ipv4-address.

  1. Salve o seguinte manifesto de amostra como external-regional-http.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-regional-http
    spec:
      # Name of an existing GatewayClass.
      gatewayClassName: gke-l7-regional-external-managed
      # Listen for HTTPS traffic on port 443.
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
        tls:
          # Terminate the TLS session with the client at the Gateway.
          mode: Terminate
          # Certificates for the Gateway to use to create a new TLS session.
          certificateRefs:
          - name: store-example-com
      addresses:
      # Request a Premium Tier ephemeral IPv4 address for the Gateway.
      # For a Premium Tier ephemeral IPv6 address, use:
      # networking.gke.io/premium-ephemeral-ipv6-address
      - type: networking.gke.io/premium-ephemeral-ipv4-address
    
  2. Aplique o manifesto de amostra:

    kubectl apply -f external-regional-http.yaml
    

Configurar o back-end padrão do gateway

Todas as gke-l7-* GatewayClasses retornam HTTP 404 para tráfego sem correspondência. É possível configurar o back-end padrão usando uma rota padrão explícita que envia tráfego incomparável a um serviço fornecido pelo usuário.

Os gateways são configurados para processar códigos do erro como 404 (Não encontrado) e 500 (erro de servidor), mesmo sem definições explícitas de back-end. O comportamento padrão pode variar entre as implementações de gateway. Para ter mais controle sobre o tratamento de erros, configure back-ends personalizados.

O HTTPRoute a seguir é um exemplo de como personalizar o back-end padrão. Se você aplicar uma HTTPRoute semelhante às seguintes, ela terá precedência sobre o back-end padrão implícito:

kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: custom-default-backend
spec:
  parentRefs:
  - kind: Gateway
    name: my-internal-gateway
  # Omit the `hostnames` field to route all unmatched traffic from the
  # attached Gateway.
  rules:
  - backendRefs:
    - name: my-custom-default-backend-service
      port: 8080

Esse HTTPRoute corresponde a todo o tráfego de um gateway específico. Só é possível ter uma regra assim para cada gateway. Caso contrário, as regras entrarão em conflito, e a ordem de precedência será aplicada.

É possível usar um back-end padrão para evitar que alguém crie um back-end de rota padrão que direcione todo o tráfego do gateway. Um HTTPRoute explícito sempre tem precedência sobre novos HTTPRoutes com regras de roteamento conflitantes.

Configurar um endereço IP estático para um gateway

Cada gateway tem um endereço IP que usa para detectar o tráfego. Se você não especificar um endereço IP no Gateway, o controlador do Gateway fornecerá automaticamente um endereço IP. Também é possível criar um endereço IP estático para que ele exista, independentemente do ciclo de vida do gateway.

Depois que um gateway é implantado, o endereço IP dele é exibido no campo de status:

kind: Gateway
...
status:
  addresses:
    - value: 10.15.32.3

Dependendo da GatewayClass, o endereço IP é alocado dos seguintes pools e sub-redes:

GatewayClasses Pool de endereços IPv4 padrão Pool de endereços IPv6 padrão (temporário e estático)
  • gke-l7-rilb
  • gke-l7-rilb-mc
Endereços IPv4 particulares regionais do intervalo de endereços IPv4 do nó principal Endereços IPv6 internos regionais do intervalo de endereços IPv6 interno da sub-rede do nó principal (ULA /64) quando a sub-rede do nó principal usa ipv6AccessType: INTERNAL ou de uma sub-rede na mesma região configurada com ipv6AccessType: INTERNAL (somente gke-l7-rilb)
  • gke-l7-regional-external-managed
  • gke-l7-regional-external-managed-mc
Endereços IPv4 públicos regionais do pool de endereços IPv4 externos regionais do Google Endereços IPv6 externos regionais do intervalo de endereços IPv6 externo da sub-rede do nó principal (GUA público /64) quando a sub-rede do nó principal usa ipv6AccessType: EXTERNAL ou de uma sub-rede VPC separada na mesma região configurada com ipv6AccessType: EXTERNAL (somente gke-l7-regional-external-managed; consulte Requisito de sub-rede IPv6 externa regional em clusters IPv6 internos)
  • gke-l7-global-external-managed
  • gke-l7-global-external-managed-mc
  • gke-l7-gxlb
  • gke-l7-gxlb-mc
Endereços IPv4 públicos globais dos intervalos de endereços IPv4 externos globais do Google Endereços IPv6 públicos globais dos intervalos de endereços IPv6 externos globais do Google

Requisito de sub-rede IPv6 externa regional em clusters IPv6 internos

Ao contrário dos endereços IPv4 externos regionais (que são alocados de um pool gerenciado pelo Google independente de sub-redes VPC), os endereços IPv6 externos regionais do Compute Engine (NETLB) precisam ser alocados de uma sub-rede VPC configurada com ipv6AccessType: EXTERNAL.

Se a sub-rede do nó principal do cluster já estiver configurada com --ipv6-access-type=EXTERNAL, o controlador de gateway usará a sub-rede do nó principal por padrão para endereços IPv6 gke-l7-regional-external-managed.

Se o cluster usar uma sub-rede de nó IPv6 interna (--ipv6-access-type=INTERNAL), a sub-rede de nó principal do cluster terá apenas endereços locais exclusivos (ULA, na sigla em inglês) particulares. Antes de implantar um recurso de gateway IPv6 gke-l7-regional-external-managed (usando um endereço IPv6 temporário ou estático), é preciso criar uma sub-rede na mesma rede VPC e região com --ipv6-access-type=EXTERNAL:

  1. Crie uma sub-rede somente IPv6 (ou de pilha dupla) com acesso IPv6 externo na mesma rede VPC e região do cluster:

    gcloud compute networks subnets create EXTERNAL_IPV6_SUBNET_NAME \
        --network=VPC_NETWORK_NAME \
        --region=COMPUTE_REGION \
        --stack-type=IPV6_ONLY \
        --ipv6-access-type=EXTERNAL
    

    Substitua:

    • EXTERNAL_IPV6_SUBNET_NAME: o nome da sub-rede com acesso IPv6 externo.
    • VPC_NETWORK_NAME: o nome da rede VPC em que o cluster do GKE é executado.
    • COMPUTE_REGION: a região do Compute Engine em que o cluster é executado.

    Para criar uma sub-rede de pilha dupla em vez de uma sub-rede somente IPv6, substitua --stack-type=IPV6_ONLY por --stack-type=IPV4_IPV6 --range=IPV4_CIDR_RANGE, em que IPV4_CIDR_RANGE é um intervalo CIDR IPv4 principal não utilizado na rede VPC.

  2. Configure o recurso Gateway para usar a sub-rede IPv6 externa:

    • Para um endereço IPv6 temporário: anexe um recurso GCPGatewayPolicy ao recurso de gateway e especifique o nome da sub-rede no campo spec.default.subnetwork. Salve o seguinte manifesto como gateway-policy.yaml:

      apiVersion: networking.gke.io/v1
      kind: GCPGatewayPolicy
      metadata:
        name: GATEWAY_POLICY_NAME
        namespace: GATEWAY_NAMESPACE
      spec:
        default:
          subnetwork: EXTERNAL_IPV6_SUBNET_NAME
        targetRef:
          group: gateway.networking.k8s.io
          kind: Gateway
          name: GATEWAY_NAME
      

      Substitua:

      • GATEWAY_POLICY_NAME: o nome do recurso GCPGatewayPolicy.
      • GATEWAY_NAMESPACE: o namespace do recurso de gateway de destino.
      • EXTERNAL_IPV6_SUBNET_NAME: o nome da sub-rede que você criou na etapa anterior.
      • GATEWAY_NAME: o nome do recurso de gateway de destino.

      Aplique o manifesto gateway-policy.yaml:

      kubectl apply -f gateway-policy.yaml
      
    • Para um endereço IPv6 estático (NamedAddress): especifique a flag --subnet=EXTERNAL_IPV6_SUBNET_NAME ao criar o recurso de endereço IPv6 estático, conforme mostrado em Usar um endereço IP nomeado.

O campo addresses.NamedAddress permite especificar um endereço IP independentemente do gateway. É possível criar um recurso de endereço IP estático antes da implantação do gateway, e o recurso é referenciado pelo NamedAddress. Reutilize o endereço IP estático mesmo que o gateway seja excluído.

Usar um endereço IP nomeado

Para configurar um endereço IPv4 ou IPv6 estático, especifique NamedAddress. É preciso provisionar um endereço IP estático antes de criar um gateway.

  1. Crie um recurso de endereço IP estático:

    • Endereço IPv4 interno regional (gke-l7-rilb):

      gcloud compute addresses create IP_ADDRESS_NAME \
          --purpose=SHARED_LOADBALANCER_VIP \
          --region=COMPUTE_REGION \
          --subnet=SUBNET \
          --project=PROJECT_ID
      
    • Endereço IPv6 interno regional (gke-l7-rilb):

      gcloud compute addresses create IP_ADDRESS_NAME \
          --region=COMPUTE_REGION \
          --subnet=CLUSTER_NODE_SUBNET \
          --ip-version=IPV6 \
          --project=PROJECT_ID
      
    • Endereço IPv6 externo regional (gke-l7-regional-external-managed):

      gcloud compute addresses create IP_ADDRESS_NAME \
          --region=COMPUTE_REGION \
          --subnet=EXTERNAL_IPV6_SUBNET_NAME \
          --ip-version=IPV6 \
          --endpoint-type=NETLB \
          --project=PROJECT_ID
      

    Substitua:

    • IP_ADDRESS_NAME: o nome do novo endereço IP estático.
    • COMPUTE_REGION: para gateways regionais, a região do Compute Engine em que o cluster está em execução. Essa flag não é necessária para gateways globais externos.
    • SUBNET ou CLUSTER_NODE_SUBNET: a sub-rede do endereço IP interno. Essa flag não é necessária para gateways globais externos.
    • EXTERNAL_IPV6_SUBNET_NAME: a sub-rede regional configurada com ipv6AccessType: EXTERNAL de onde o endereço IPv6 externo regional será alocado.
    • PROJECT_ID: o projeto em que o cluster do GKE está em execução.

    Os comandos anteriores alocam automaticamente um endereço IP da sub-rede especificada. Também é possível especificar um endereço IPv4 personalizado ou um intervalo de endereços IPv6 /96 personalizado com a flag --addresses. Para mais informações, consulte Reservar um endereço IP interno estático e Reservar um endereço IP externo estático.

  2. Salve o seguinte manifesto em um arquivo chamado named-ip-gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: internal-http
    spec:
      gatewayClassName: gke-l7-rilb
      listeners:
      - name: http
        protocol: HTTP
        port: 80
      addresses:
      - type: NamedAddress
        value: IP_ADDRESS_NAME
    

    Esse manifesto descreve um gateway que faz referência ao endereço IP nomeado.

  3. Aplique o manifesto ao cluster:

    kubectl apply -f named-ip-gateway.yaml
    
  4. Verifique o endereço IP do gateway:

    kubectl describe gateway internal-http
    

    O resultado será o seguinte:

    Name:         internal-http
    Namespace:    default
    Labels:       <none>
    ...
    Spec:
      Addresses:
        Type:              NamedAddress
        Value:             IP_ADDRESS_NAME
      Gateway Class Name:  gke-l7-rilb
      Listeners:
        Allowed Routes:
          Namespaces:
            From:  Same
        Name:      http
        Port:      80
        Protocol:  HTTP
    Status:
      Addresses:
        Type:   IPAddress
        Value:  10.15.32.103
    

Configurar regras de firewall IPv6 para VPC compartilhada ou gerenciamento manual de firewall

Quando a criação automática de regras de firewall está desativada ou restrita (como em projetos de serviço de VPC compartilhada), é necessário criar manualmente uma regra de firewall IPv6 de entrada para permitir o tráfego de sondagens de verificação de integridade IPv6 do Google Cloud (2600:2d00:1:b029::/64), proxies do Google Front End (GFE) para balanceadores de carga de aplicativo externos globais (2600:2d00:1:1::/64) e o internalIpv6Prefix da sub-rede somente proxy regional para balanceadores de carga de aplicativo regionais:

gcloud compute firewall-rules create FIREWALL_RULE_NAME \
    --network=VPC_NETWORK_NAME \
    --action=ALLOW \
    --direction=INGRESS \
    --rules=tcp:80,tcp:443 \
    --source-ranges="2600:2d00:1:b029::/64,2600:2d00:1:1::/64,PROXY_SUBNET_INTERNAL_IPV6_PREFIX" \
    --target-tags=GKE_NODE_TAG

Substitua:

  • FIREWALL_RULE_NAME: o nome da regra de firewall.
  • VPC_NETWORK_NAME: o nome da sua rede VPC.
  • PROXY_SUBNET_INTERNAL_IPV6_PREFIX: o prefixo IPv6 /64 interno da sua sub-rede regional somente proxy (internalIpv6Prefix).
  • GKE_NODE_TAG: a tag de rede aplicada aos nós do cluster.

Configurar redirecionamentos de HTTP para HTTPS

O Cloud Load Balancing oferece redirecionamento de HTTP para HTTPS. Um balanceador de carga de aplicativo externo redireciona as solicitações HTTP não criptografadas para um balanceador de carga HTTPS que usa o mesmo endereço IP. Quando você cria um gateway com redirecionamentos de HTTP para HTTPS ativados, os dois balanceadores de carga são criados automaticamente. As solicitações para o endereço IP externo do Gateway na porta 80 são redirecionadas automaticamente para o mesmo endereço IP externo na porta 443.

Por padrão, os redirecionamentos de HTTP para HTTPS não são definidos no gateway.

Para redirecionar o tráfego HTTP para HTTPS, configure um gateway para processar o tráfego HTTP e HTTPS. Se você desativar o HTTP ou o HTTPS, o Gateway não redirecionará o tráfego.

Os exemplos a seguir mostram como usar o redirecionamento de HTTP para HTTPS para garantir que o tráfego dos clientes que vai para os aplicativos da Web seja sempre redirecionado para uma página segura.

Os redirecionamentos de HTTP para HTTPS não são compatíveis com as GatewayClasses gke-l7-gxlb e gke-l7-gxlb-mc. Para saber mais sobre os diferentes recursos compatíveis com cada GatewayClass, consulte Recursos da GatewayClass.

A seção hostnames em um HTTPRoute é opcional. É possível criar um redirecionamento geral para todos os nomes de host em uma porta HTTP específica omitindo a seção hostnames. Além disso, é possível usar um redirecionamento curinga, por exemplo:

...
hostnames:
- "*.example.com" # Matches all subdomains of example.com
...

Redirecionar o tráfego HTTP de um namespace de infraestrutura

Em alguns casos, não há uma distinção clara entre as equipes de administrador de infraestrutura ou de plataforma e a prevenção do uso indevido do Gateway.

O exemplo a seguir restringe ainda mais o uso do listener HTTP para impedir o uso não intencional de protocolos não seguros por parte das equipes do aplicativo. Este exemplo configura o gateway para permitir que um HTTPRoute use o listener HTTP apenas se a rota estiver em um namespace que tenha o rótulo otherInfra: httpToHttps. No entanto, o gateway permite que HTTPRoutes em qualquer namespace usem o listener HTTPS. É possível restringir o namespace http-redirect usando o RBAC do Kubernetes para que as equipes de aplicativo não possam criar um HTTPRoute nesse namespace por engano.

  1. Crie o namespace de um gateway. Salve o manifesto como gateway-namespace.yaml:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: gateway-infra
    
  2. Aplique o manifesto:

    kubectl apply -f gateway-namespace.yaml
    
  3. Crie o namespace de um gateway e salve o manifesto como redirect-namespace.yaml:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: http-redirect
      labels:
        otherInfra: httpToHttps
    

    Esse namespace http-redirect tem o rótulo otherInfra: httpToHttps.

  4. Aplique o manifesto:

    kubectl apply -f redirect-namespace.yaml
    
  5. Para restringir o uso do listener http, crie um gateway usando o manifesto a seguir. Salve o manifesto como external-gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
      namespace: gateway-infra
    spec:
      # Name of an existing GatewayClass.
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        #  Allow only HTTPRoutes from namespaces that have the
        # `otherInfra: httpToHttps` label to use this listener.
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
          namespaces:
            from: Selector
            selector:
              matchLabels:
                otherInfra: httpToHttps
      - name: https
        protocol: HTTPS
        port: 443
        # Allow HTTPRoutes from any namespace to use this listener.
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
          namespaces:
            from: All
        tls:
          mode: Terminate
          options:
            networking.gke.io/pre-shared-certs: store-example-com
    
    • O campo namespace especifica que o gateway é criado no namespace gateway-infra.

    • O campo namespaces na seção allowedRoutes restringe o listener HTTP ao namespace correspondente ao rótulo otherInfra: httpToHttps.

  6. Aplique o manifesto:

    kubectl apply -f external-gateway.yaml
    
  7. Para forçar o redirecionamento HTTPS, crie um HTTPRoute padrão usando o seguinte manifesto. Salve o manifesto como http-redirect.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: redirect
      # Create the HTTPRoute in the `http-redirect` namespace.
      namespace: http-redirect
    spec:
      # Attach the HTTPRoute to the `http` listener in the `external-http`
      # Gateway.
      parentRefs:
      - namespace: gateway-infra
        name: external-http
        sectionName: http
      rules:
      # Respond to the request with an HTTPS redirection.
      - filters:
        - type: RequestRedirect
          requestRedirect:
            scheme: https
    
    • O campo sectionName instrui o gateway a corresponder apenas ao listener http. O filtro RequestRedirect força o redirecionamento para o listener https.
  8. Aplique o manifesto:

    kubectl apply -f http-redirect.yaml
    
  9. Crie um serviço para um aplicativo que usa o manifesto a seguir. Salve o manifesto como service-deployment.yaml.

    apiVersion: v1
    kind: Service
    metadata:
      name: store-v1
    spec:
      selector:
        app: store
        version: v1
      ports:
      - port: 8080
        targetPort: 8080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: store-v1
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: store
          version: v1
      template:
        metadata:
          labels:
            app: store
            version: v1
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
            ports:
            - containerPort: 8080
            env:
            - name: METADATA
              value: "store-v1"
    
  10. Aplique o manifesto:

    kubectl apply -f service-deployment.yaml
    
  11. Crie um HTTPRoute para um aplicativo que só permita HTTPS usando o manifesto a seguir. Salve o manifesto como http-route.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
      labels:
        gateway: external-http
    spec:
      # Attach the HTTPRoute to the HTTPS listener in the `external-http`
      # Gateway.
      parentRefs:
      - name: external-http
        namespace: gateway-infra
        sectionName: https
      # Match requests that have the `store.example.com` Host header.
      hostnames:
      - "store.example.com"
      # Route requests to the `store-v1` Service.
      rules:
      - backendRefs:
        - name: store-v1
          port: 8080
    
  12. Aplique o manifesto:

    kubectl apply -f http-route.yaml
    

Configurar redirecionamentos de caminho e substituições de URL

Os redirecionamentos de caminho envolvem redirecionar uma solicitação recebida de um caminho de URL para outro. Os redirecionamentos de caminho permitem alterar a estrutura do URL quando precisar lidar com URLs desatualizados ou descontinuados.

As substituições de URL ajudam a modificar o URL recebido antes de processá-lo no servidor. Isso permite alterar a estrutura ou o formato do URL sem alterar de fato a estrutura do arquivo ou o conteúdo subjacente. A substituição de URL é vantajosa para criar URLs fáceis de lembrar e de entender para usuários e SEO. Por padrão, os redirecionamentos de caminho e as substituições de URL não estão configurados. Você precisa configurar explicitamente esses redirecionamentos ou substituições usando um filtro no seu HTTPRoute.

O gateway do GKE é compatível com redirecionamentos de caminho e substituições de URL. Para mais informações, consulte Redirecionamentos de caminho HTTP e substituições.

Configurar redirecionamentos de caminho

É possível configurar redirecionamentos de caminho para substituir o caminho inteiro ou apenas um prefixo no URL.

Substituir o caminho inteiro

  1. Para substituir um caminho inteiro, configure um filtro em um HTTPRoute que substitui qualquer URL contendo o prefixo /any-path no caminho do URL pelo valor restrito /new-path.

  2. Crie um manifesto HTTPRoute da seguinte maneira e nomeie-o como store.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        parentRefs:
        - kind: Gateway
          name: external-http
        hostnames:
        - store.example.com
        rules:
        - matches:
          - path:
              # Match requests by a prefix, like `/any-path` and `/any-path/home`.
              type: PathPrefix
              value: /any-path
          filters:
          - type: RequestRedirect
            requestRedirect:
              path:
                # Replace the full path with `/new-path`. For example, both
                # `/any-path/home` and `/any-path` become `/new-path`.
                type: ReplaceFullPath
                replaceFullPath: /new-path
              statusCode: 302
    

    Por exemplo, esse manifesto define uma regra de rota para um HTTPRoute da seguinte maneira: qualquer rota para o URL https://store.example.com/any-path/... será redirecionada para um novo local, https://store.example.com/new-path/ (restrito).

  3. Aplique o manifesto:

    kubectl apply -f store.yaml
    

Essa regra de roteamento segue uma regra de redirecionamento restrito, o que significa que o navegador não tenta armazenar o redirecionamento em cache. Em vez disso, ele redireciona para a versão mais recente.

Substituir apenas um prefixo

  1. Para substituir apenas um prefixo, configure um filtro em um HTTPRoute que substitui qualquer URL contendo o prefixo /any-prefix no caminho do URL pelo valor restrito /new-prefix.

  2. Crie um manifesto HTTPRoute da seguinte maneira e nomeie-o como store.yaml:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: store
    spec:
      parentRefs:
        - kind: Gateway
          name: external-http
      hostnames:
      - store.example.com
      rules:
      - matches:
          - path:
              # Match requests by prefix, like `/any-prefix` and
              # `/any-prefix/home`.
              type: PathPrefix
              value: /any-prefix
        filters:
        - type: RequestRedirect
          requestRedirect:
            path:
              # Replace the matched prefix with `/new-prefix`. For example,
              # `/any-prefix` becomes `/new-prefix` and `/any-prefix/home`
              # becomes `/new-prefix/home`.
              type: ReplacePrefixMatch
              replacePrefixMatch: /new-prefix
            statusCode: 302
    

    Por exemplo, esse manifesto define uma regra de rota para um HTTPRoute da seguinte maneira: qualquer rota para o URL https://store.example.com/any-path/v1/... será redirecionada para um novo local, https://store.example.com/new-path/v1/... (somente).

  3. Aplique o manifesto:

      kubectl apply -f store.yaml
    

Essa regra de rota segue a regra de redirecionamento único, que ajuda a garantir que o navegador sempre redirecione você para a mesma página pretendida.

Configurar substituições de URL

Defina substituições de URL para alterar como o URL aparece para os usuários. É possível usar substituições de URL para torná-los mais fáceis de usar, melhorar SEO ou para redirecionar os usuários a uma nova página.

Substituir o nome do host inteiro

Para substituir o nome do host inteiro:

  1. Configure um filtro em um HTTPRoute que instrui o gateway a substituir as informações do Host no cabeçalho da solicitação de www.example.com para store.example.com antes de encaminhar a solicitação ao serviço de back-end.

  2. Crie um manifesto HTTPRoute da seguinte maneira e nomeie-o como www.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: www
      spec:
        parentRefs:
          - kind: Gateway
            name: external-http
        hostnames:
        - www.example.com
        rules:
        - filters:
          - type: URLRewrite
            # Replace the hostname in the URL with `store.example.com`.
            urlRewrite:
              hostname: store.example.com
          backendRefs:
          - name: store-v1
            port: 8080
    

    Por exemplo, com a configuração acima, qualquer solicitação para https://www.example.com é encaminhada para o serviço de back-end com o cabeçalho Host: store.example.com, no lugar de Host: www.example.com.

  3. Aplique o manifesto:

      kubectl apply -f www.yaml
    

Substituir usando modificadores de caminho

É possível combinar substituições com modificadores de caminho para fornecer modificações avançadas de URL e caminho antes de redirecionar a solicitação para o serviço de back-end.

Para substituir usando modificadores de caminho:

  1. Configure um filtro em um HTTPRoute que instrui o gateway a substituir as informações do "Host" no cabeçalho da solicitação de www.example.comto store.example.com e substitua o valor /store por / antes de encaminhar a solicitação ao serviço de back-end.

  2. Crie um manifesto HTTPRoute da seguinte maneira e nomeie-o como www.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: www
      spec:
        parentRefs:
          - kind: Gateway
            name: external-http
        hostnames:
        - www.example.com
        rules:
        - matches:
          - path:
              type: PathPrefix
              value: /store
          filters:
          - type: URLRewrite
            # For URLs that have `/store` in the path, replace the hostname with
            # store.example.com and replace the `/store` prefix with `/de`.
            urlRewrite:
              hostname: store.example.com
              path:
                type: ReplacePrefixMatch
                replacePrefixMatch: /de
          backendRefs:
          - name: store-german
            port: 8080
    

    Por exemplo, com a configuração acima, qualquer solicitação para https://www.example.com/store/... é encaminhada para o serviço de back-end com Host: store.example.com no cabeçalho da solicitação (no lugar de Host: www.example.com), e /store é substituído por /de.

  3. Aplique o manifesto:

    kubectl apply -f www.yaml
    

Reescrever usando expressões regulares

É possível usar um recurso GCPHTTPFilter com spec.urlRewrite.regexModifier para reescrever caminhos de URL usando expressões regulares antes de encaminhar a solicitação para o serviço de back-end.

Para reescrever um caminho de URL usando uma expressão regular:

  1. Salve o seguinte manifesto como store-regex-rewrite-filter.yaml:

    apiVersion: networking.gke.io/v1
    kind: GCPHTTPFilter
    metadata:
      name: store-regex-rewrite-filter
    spec:
      urlRewrite:
        regexModifier:
          pathPattern: /service1/
          pathSubstitution: /service2/
    

    Este manifesto descreve um GCPHTTPFilter com as seguintes propriedades:

    • urlRewrite.regexModifier: configura a reescrita do caminho do URL usando expressões regulares.
    • pathPattern: especifica a expressão regular RE2 que corresponde ao caminho do URL da solicitação, como /service1/([a-zA-Z0-9]+).
    • pathSubstitution: especifica a string de substituição que substitui o caminho do URL correspondente, que pode referenciar grupos de captura numerados de pathPattern, como /service2/\1.
  2. Aplique o manifesto ao cluster:

    kubectl apply -f store-regex-rewrite-filter.yaml
    
  3. Salve o seguinte manifesto como www-regex-rewrite.yaml:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: www-regex-rewrite
    spec:
      parentRefs:
      - kind: Gateway
        name: external-http
      hostnames:
      - www.example.com
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /service1/
        filters:
        - type: ExtensionRef
          extensionRef:
            group: networking.gke.io
            kind: GCPHTTPFilter
            name: store-regex-rewrite-filter
        backendRefs:
        - name: store-v1
          port: 8080
    

    Esse manifesto descreve um HTTPRoute com as seguintes propriedades:

    • extensionRef: faz referência ao GCPHTTPFilter store-regex-rewrite-filter criado na etapa anterior.
    • backendRefs: encaminha a solicitação reescrita para o serviço store-v1. Por exemplo, uma solicitação para https://www.example.com/service1/item123 é reescrita para /service2/item123 antes de ser encaminhada para o serviço de back-end store-v1.
  4. Aplique o manifesto ao cluster:

    kubectl apply -f www-regex-rewrite.yaml
    

Verificar a configuração

Para verificar se o filtro foi aplicado depois de criar seu HTTPRoute com filtros de substituição de URL ou redirecionamentos de caminho, faça isto:

kubectl get httproute www -o yaml

O resultado será assim:

  apiVersion: gateway.networking.k8s.io/v1
  kind: HTTPRoute
  metadata:
    annotations:
      kubectl.kubernetes.io/last-applied-configuration: |
        {"apiVersion":"gateway.networking.k8s.io/v1","kind":"HTTPRoute","metadata":{"annotations":{},"name":"www","namespace":"default"},"spec":{"hostnames":["www.example.com"],"parentRefs":[{"kind":"Gateway","name":"external-http"}],"rules":[{"backendRefs":[{"name":"store-german","port":8080}],"filters":[{"type":"URLRewrite","urlRewrite":{"hostname":"store.example.com","path":{"replacePrefixMatch":"/de","type":"ReplacePrefixMatch"}}}],"matches":[{"path":{"type":"PathPrefix","value":"/store"}}]}]}}
    creationTimestamp: "2023-06-22T01:00:42Z"
    generation: 3
    name: www
    namespace: default
    resourceVersion: "51268631"
    uid: e516493e-806d-44d6-ae0d-1c9ff25682cf
  spec:
    hostnames:
    - www.example.com
    parentRefs:
    - group: gateway.networking.k8s.io
      kind: Gateway
      name: external-http
    rules:
    - backendRefs:
      - group: ""
        kind: Service
        name: store-german
        port: 8080
        weight: 1
      filters:
      - type: URLRewrite
        urlRewrite:
          hostname: store.example.com
          path:
            replacePrefixMatch: /de
            type: ReplacePrefixMatch
      matches:
      - path:
          type: PathPrefix
          value: /store
  status:
    parents:
    - conditions:
      - lastTransitionTime: "2023-06-22T01:11:26Z"
        message: ""
        observedGeneration: 2
        reason: Accepted
        status: "True"
        type: Accepted
      - lastTransitionTime: "2023-06-22T01:11:26Z"
        message: ""
        observedGeneration: 2
        reason: ReconciliationSucceeded
        status: "True"
        type: Reconciled
      controllerName: networking.gke.io/gateway
      parentRef:
        group: gateway.networking.k8s.io
        kind: Gateway
        name: external-http

Para ver mais detalhes, use o comando "describe":

kubectl describe httproute

Configurar o compartilhamento de recursos entre origens (CORS)

O Compartilhamento de recursos entre origens (CORS) é um mecanismo de segurança que ajuda os aplicativos da Web em execução em uma origem (domínio) a acessar com segurança os recursos hospedados em uma origem diferente.

É possível configurar políticas de CORS diretamente nos recursos HTTPRoute usando o filtro CORS. Essa abordagem permite que o balanceador de carga injete os cabeçalhos de resposta de CORS apropriados e processe solicitações de simulação de CORS (OPTIONS), transferindo essa responsabilidade dos seus serviços de back-end.

Configurar uma política de CORS

O exemplo a seguir mostra um HTTPRoute configurado com um filtro CORS que permite solicitações entre origens de https://www.example.com para métodos e cabeçalhos específicos:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: route-with-cors
  namespace: default
spec:
  parentRefs:
  - name: my-gateway
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /api
    backendRefs:
    - name: my-backend
      port: 8080
    filters:
    - type: CORS
      cors:
        allowOrigins:
        - "https://www.example.com"
        allowMethods:
        - GET
        - POST
        - DELETE
        allowHeaders:
        - "x-request-header-1"
        - "x-request-header-2"
        exposeHeaders:
        - "x-response-header-a"
        - "x-response-header-b"
        allowCredentials: true
        maxAge: 3600

O bloco de configuração cors é compatível com os seguintes campos:

  • allowOrigins: uma lista de origens permitidas. Os protocolos http e https são compatíveis. É possível especificar essas origens em qualquer um dos seguintes formatos:
    • Origens explícitas (por exemplo, https://www.example.com).
    • Um único caractere curinga (*) para permitir todas as origens. Se esse caractere curinga for usado, nenhuma outra origem poderá ser especificada. Por motivos de segurança, não recomendamos combinar o caractere curinga catch-all com a configuração allowCredentials (para mais informações, consulte a definição de campo a seguir).
    • Padrões de caracteres curinga (por exemplo, https://*.domain.com). O caractere curinga * precisa aparecer imediatamente após o esquema (http:// ou https://) e ser seguido por um ponto (por exemplo, http://*.domain.com), uma porta (por exemplo, https://*:4433) ou ser o último caractere (por exemplo, http://*).
  • allowMethods: os métodos HTTP permitidos para solicitações CORS. Aceita o caractere curinga (*) para permitir todos os métodos. Se o caractere curinga for usado, nenhum outro método poderá ser especificado.
  • allowHeaders: os cabeçalhos HTTP que os clientes podem enviar. Aceita o caractere curinga (*) para permitir todos os cabeçalhos. Se o caractere curinga for usado, nenhum outro cabeçalho poderá ser especificado.
  • exposeHeaders: os cabeçalhos HTTP que são seguros para exposição ao script do cliente. Aceita o caractere curinga (*) para expor todos os cabeçalhos.
  • allowCredentials: controla se o navegador pode compartilhar a resposta do servidor para solicitações enviadas no modo de credenciais, como solicitações que contêm cookies ou autenticação HTTP. O padrão é false. Ao definir essa configuração, considere os seguintes aspectos de segurança:
    • Se você especificar o caractere curinga * como o valor de qualquer um dos campos allowMethods, allowHeaders ou exposeHeaders, o navegador vai bloquear uma resposta a uma solicitação de modo credenciado. Esse bloqueio ocorre mesmo que o valor do campo allowCredentials esteja definido como true por motivos de segurança.
    • Quando allowOrigins contém o caractere curinga *, o controlador do gateway do GKE não copia literalmente o caractere curinga * do campo allowOrigins para os cabeçalhos de resposta. Como resultado, o navegador não vai bloquear essa resposta a uma solicitação de modo credenciado, permitindo que qualquer site potencialmente malicioso acesse os dados do usuário. Por esse motivo, não recomendamos uma configuração com as seguintes definições: allowCredentials: true e allowOrigins com o caractere curinga *.
  • maxAge: especifica por quanto tempo (em segundos) o navegador pode armazenar em cache a resposta de simulação. O padrão é 5 segundos. O valor precisa ser 1 ou maior.

Limitações

  • Somente gateways de cluster único: o CORS não é compatível com gateways de vários clusters.
  • Incompatibilidade com RequestRedirect: não é possível usar um filtro CORS e um filtro RequestRedirect na mesma regra de rota.
  • Limites de expressão regular: o controlador do GKE Gateway representa internamente padrões de caracteres curinga no valor do campo allowOrigins como expressões regulares. Há limites no uso de expressões regulares, que afetam as GatewayClasses da seguinte maneira:
    • Para o GatewayClass gke-l7-global-external-managed, é possível usar apenas uma expressão regular por listener de gateway (compartilhada com outros recursos). Essa limitação está sujeita a regras de contagem duplicada, o que significa que não é possível combinar um padrão de caractere curinga com uma correspondência de PathPrefix.
    • Para as GatewayClasses gke-l7-regional-external-managed e gke-l7-rilb, é possível usar até cinco expressões regulares por nome do host (compartilhadas com outros recursos).
    • O caractere curinga catch-all (*) não é contabilizado nesses limites.
    • Um único padrão de caractere curinga em um filtro CORS pode ser contabilizado várias vezes no limite de expressões regulares. O controlador de gateway do GKE multiplica um filtro CORS em uma regra HTTPRoute pelo número de correspondências nessa regra. Além disso, uma correspondência do tipo PathPrefix conta duas vezes, a menos que o caminho seja /.

Para mais informações sobre o comportamento padrão do CORS na API Gateway, consulte o Guia do usuário do CORS upstream.

Configurar cabeçalhos de solicitação e resposta personalizados

Os cabeçalhos de solicitação e cabeçalho de resposta personalizados permitem especificar cabeçalhos adicionais para solicitações e respostas HTTP(S). Dependendo das informações detectadas pelo balanceador de carga, esses cabeçalhos podem incluir as seguintes informações:

  • Latência para o cliente
  • Localização geográfica do endereço IP do cliente
  • Parâmetros da conexão TLS

Por padrão, não há cabeçalhos personalizados adicionados à solicitação enviada aos seus serviços de back-end ou recebida deles. É necessário configurar explicitamente os cabeçalhos personalizados usando um filtro no seu HTTPRoute.

É possível configurar cabeçalhos personalizados adicionando uma seção de filtro às regras do HTTPRoute da seguinte maneira:

Configurar cabeçalhos da solicitação personalizados

Crie um manifesto do HTTPRoute com um filtro RequestHeaderModifier e salve-o como http-route-request.yaml:

  apiVersion: gateway.networking.k8s.io/v1
  kind: HTTPRoute
  metadata:
    name: store
  spec:
    <...>
    rules:
        filters:
          - type: RequestHeaderModifier
            requestHeaderModifier:
              <...>

Aplique o manifesto:

  kubectl apply -f http-route-request.yaml

Configurar cabeçalhos de resposta personalizados

Crie um manifesto do HTTPRoute com um filtro ResponseHeaderModifier e salve-o como http-route-response.yaml:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: store
spec:
  <...>
  rules:
      filters:
        - type: ResponseHeaderModifier
          responseHeaderModifier:
            <...>

Aplique o manifesto:

  kubectl apply -f http-route-response.yaml

É possível adicionar, definir e remover cabeçalhos conforme descrito na Implementação da API Gateway. É possível configurar o HTTPRoute com um cabeçalho personalizado usando as variáveis compatíveis doGoogle Cloud .

Exemplo 1:

Para configurar um HTTPRoute que adiciona informações de localização do cliente à solicitação HTTP antes de enviá-las ao serviço de back-end, crie um manifesto do HTTPRoute e nomeie-o como external-http-request.yaml:

  apiVersion: gateway.networking.k8s.io/v1
  kind: HTTPRoute
  metadata:
    name: store
  spec:
    parentRefs:
      - kind: Gateway
        name: external-http
    hostnames:
    - store.example.com
    rules:
      - matches:
        - path:
            type: PathPrefix
            value: /fr
        filters:
          # Add custom headers to requests that have `/fr` in the path.
          - type: RequestHeaderModifier
            requestHeaderModifier:
              add:
                - name: X-Client-Geo-Location
                  value: "{client_region},{client_city}"
        backendRefs:
          - name: store-french
            port: 8080

Por exemplo, para clientes localizados em Estrasburgo, na França, o gateway adiciona um cabeçalho como X-Client-Geo-Location:FR,Strasbourg.

Exemplo 2:

Para configurar um HTTPRoute que adiciona um cabeçalho de resposta personalizado compatível com o HTTP Strict Transport Security, crie um manifesto do HTTPRoute e nomeie-o como external-http-response.yaml:

  apiVersion: gateway.networking.k8s.io/v1
  kind: HTTPRoute
  metadata:
    name: store
  spec:
    parentRefs:
      - kind: Gateway
        name: external-http
    hostnames:
    - store.example.com
    rules:
      - matches:
        - path:
            type: PathPrefix
            value: /de
        filters:
          # Add custom headers to responses to requests that have `/de` in the
          # path.
          - type: ResponseHeaderModifier
            responseHeaderModifier:
              add:
                - name: Strict-Transport-Security
                  value: max-age=63072000
        backendRefs:
          - name: store-german
            port: 8080

Verifique a configuração

  1. Para verificar a configuração depois de configurar os cabeçalhos de solicitação e resposta personalizados, faça isto:

      kubectl get httproute
    

    O resultado será assim:

      NAME    HOSTNAMES               AGE
      store   ["store.example.com"]   4d23h
    
  2. Para ver mais detalhes, use o comando "describe":

      kubectl describe httproute
    

    O resultado será o seguinte:

      Name:         store
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  gateway.networking.k8s.io/v1
      Kind:         HTTPRoute
      Metadata:
        Creation Timestamp:  2023-05-27T00:51:01Z
        Generation:          5
        Resource Version:    25418887
        UID:                 2e07a1b8-420b-41b4-acd1-cecbfcd39f42
      Spec:
        Hostnames:
          store.example.com
        Parent Refs:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   external-http
        Rules:
          Backend Refs:
            Group:
            Kind:    Service
            Name:    store-v1
            Port:    8080
            Weight:  1
          Matches:
            Path:
              Type:   PathPrefix
              Value:  /
          Backend Refs:
            Group:
            Kind:    Service
            Name:    store-v2
            Port:    8080
            Weight:  1
          Matches:
            Headers:
              Name:   env
              Type:   Exact
              Value:  canary
            Path:
              Type:   PathPrefix
              Value:  /
          Backend Refs:
            Group:
            Kind:    Service
            Name:    store-german
            Port:    8080
            Weight:  1
          Filters:
            Request Header Modifier:
              Add:
                Name:   X-Client-Geo-Location
                Value:  {client_region},{client_city}
            Type:       RequestHeaderModifier
          Matches:
            Path:
              Type:   PathPrefix
              Value:  /de
      Status:
        <...>
    

Configurar a correspondência de expressões regulares

O gateway do GKE é compatível com a correspondência de expressões regulares para caminhos, parâmetros de consulta e cabeçalhos de HTTPRoute. Você pode usar expressões regulares para definir regras de roteamento flexíveis.

A correspondência de expressões regulares é compatível com as seguintes GatewayClasses:

  • gke-l7-global-external-managed
  • gke-l7-global-external-managed-mc
  • gke-l7-regional-external-managed
  • gke-l7-regional-external-managed-mc
  • gke-l7-rilb
  • gke-l7-rilb-mc
  • gke-l7-cross-regional-internal-managed-mc

Limitações

  • Sintaxe RE2: somente a sintaxe RE2 é aceita. O RE2 não é compatível com lookahead, lookbehind ou referências anteriores.
  • Cotas e limites:
    • Máximo de correspondências de expressão regular: é possível configurar até cinco correspondências de expressão regular por correspondência de caminho (HTTPRoute).
    • Tamanho máximo: o tamanho máximo de uma expressão regular é de 250 caracteres.
  • Impacto na performance: a correspondência de expressões regulares é computacionalmente cara. O uso de correspondências de expressões regulares pode aumentar a latência da solicitação:
    • Uma correspondência de expressão regular: aumento de latência de cerca de 100 microssegundos por solicitação.
    • Cinco correspondências de expressão regular: aumento de latência de cerca de 200 microssegundos por solicitação.

Configurar a correspondência de expressões regulares de caminho

Para configurar a correspondência de caminho usando uma expressão regular, na regra de correspondência path, defina o valor do campo type como RegularExpression.

O exemplo a seguir encaminha solicitações, em que o caminho corresponde à expressão regular /videos/hd.* (por exemplo, /videos/hd-123 ou /videos/hd-promo.mp4), para o serviço store-videos-hd:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: store-path-regex
spec:
  parentRefs:
  - kind: Gateway
    name: internal-http
  hostnames:
  - "store.example.com"
  rules:
  - matches:
    - path:
        type: RegularExpression
        value: /videos/hd.*
    backendRefs:
    - name: store-videos-hd
      port: 8080

Configurar a correspondência de expressões regulares de parâmetros de consulta

Para corresponder parâmetros de consulta usando uma expressão regular, na regra de correspondência queryParams, defina o valor do campo type como RegularExpression.

O exemplo a seguir roteia solicitações, em que o parâmetro de consulta param1 corresponde à expressão regular .*param_value.*-hd, para o serviço android-hd:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: store-query-regex
spec:
  parentRefs:
  - kind: Gateway
    name: internal-http
  hostnames:
  - "store.example.com"
  rules:
  - matches:
    - queryParams:
      - name: param1
        type: RegularExpression
        value: .*param_value.*-hd
    backendRefs:
    - name: android-hd
      port: 8080

Configurar a correspondência de expressões regulares de cabeçalho

Para corresponder cabeçalhos HTTP usando uma expressão regular, na regra de correspondência headers, defina o valor do campo type como RegularExpression.

O exemplo a seguir encaminha solicitações, em que o cabeçalho User-Agent corresponde à expressão regular .*Android.*-hd, para o serviço android-hd:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: store-header-regex
spec:
  parentRefs:
  - kind: Gateway
    name: internal-http
  hostnames:
  - "store.example.com"
  rules:
  - matches:
    - headers:
      - name: User-Agent
        type: RegularExpression
        value: .*Android.*-hd
    backendRefs:
    - name: android-hd
      port: 8080

Configurar mTLS de front-end

Para ativar a autenticação de certificado do cliente, o balanceador de carga de aplicativo do Google oferece mTLS de front-end. Para gateways do GKE, o mTLS de front-end permite configurar e aplicar a validação de certificado do cliente a todos os recursos GatewayClass compatíveis, sejam globais ou regionais. Para mais informações, consulte Configurar mTLS de front-end para um gateway.

Configurar TLS de back-end

O TLS autenticado de back-end é um recurso de segurança que permite que o balanceador de carga do gateway do GKE verifique a identidade dos back-ends aos quais ele se conecta. Para gateways do GKE, essa funcionalidade permite configurar e aplicar a validação de certificado de back-end a GatewayClasses compatíveis, como balanceadores de carga gerenciados externos globais ou regionais e balanceadores de carga internos regionais.

Para mais informações, consulte Proteger um gateway.

Para exigir que o gateway também autentique a própria identidade nos back-ends (TLS mútuo), use um certificado do cliente no recurso de gateway. Para instruções, consulte Configurar o TLS mútuo (mTLS) de back-end para um gateway.

Status da rota

Os recursos de HTTPRoute emitem condições e eventos para ajudar os usuários a entender se um HTTPRoute foi vinculado a um ou mais Gateways ou se ele foi rejeitado.

Condições do HTTPRoute

As condições do HTTPRoute indicam o status da Rota e dos Gateways aos quais ela está vinculada. Como uma rota pode ser vinculada a vários gateways, mostraremos uma lista de gateways e as condições individuais entre a rota e cada gateway.

  • Accepted=True indica que o HTTPRoute está vinculado a um Gateway.
  • Accepted=False indica que a vinculação do HTTPRoute foi rejeitada com esse gateway.

Se não houver gateways listados no título Gateway bindings, os rótulos HTTPRoute e seletores de rótulos de gateway podem não corresponder. Isso pode ocorrer se a rota não está sendo selecionada por nenhum gateway.

Eventos do HTTPRoute

Os eventos HTTPRoute fornecem detalhes sobre o status da HTTPRoute. Os eventos são agrupados pelos seguintes motivos:

  • Eventos ADD são acionados por um recurso que está sendo adicionado.
  • Os eventos UPDATE são acionados por um recurso que está sendo atualizado.
  • Os eventos SYNC são acionados pela reconciliação periódica.

Combinação, precedência e validação de rotas

Precedência da rota

A API Gateway define regras de precedência rígidas que definem como o tráfego é correspondido por rotas que tenham regras de rota sobrepostas. A precedência entre dois HTTPRoutes sobrepostos é a seguinte:

  1. Mesclagem de nomes do host: a correspondência de nome do host mais longa ou mais específica.
  2. Mesclagem de caminho: a correspondência de caminho mais longa ou mais específica.
  3. Mesclagem de cabeçalhos: o maior número de cabeçalhos HTTP correspondentes.
  4. Conflito: se as três regras anteriores não estabelecerem precedência, a precedência irá para o recurso HTTPRoute com o carimbo de data/hora mais antigo.

Mesclagem de rotas

Para GatewayClasses gke-l7, todos os HTTPRoutes de um determinado gateway são mesclados no mesmo recurso de mapa de URL. A maneira como os HTTPRoutes são mesclados depende do tipo de sobreposição entre HTTPRoutes. O HTTPRoute do exemplo anterior pode ser dividido em três HTTPRoutes separados para ilustrar a mesclagem e a precedência de rotas:

  1. Mesclagem de rotas: todas as três HTTPRoutes são anexadas com o mesmo gateway de internal-http para que sejam mescladas.
  2. Mesclagem de nome do host: todas as três rotas correspondem a store.example.com. Portanto, as regras de nome de host delas são mescladas.
  3. Mesclagem de caminhos: store-german-route tem um caminho /de mais específico. Portanto, ele não é mesclado. As rotas store-v1-route e store-v2-route também correspondem ao mesmo caminho /*, então são mesclados ao caminho.
  4. Mesclagem de cabeçalho: store-v2-route tem um conjunto mais específico de correspondências de cabeçalho HTTP do que store-v1-route e, portanto, não são combinados.
  5. Conflito: como as rotas podem ser mescladas no nome do host, no caminho e nos cabeçalhos, não há conflitos, e todas as regras de roteamento serão aplicadas ao tráfego.

O único HTTPRoute usado no exemplo anterior é equivalente a estas três rotas separadas:

kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: store-v1-route
spec:
  parentRefs:
  - kind: Gateway
    name: internal-http
  hostnames:
  - "store.example.com"
  rules:
  - backendRefs:
    - kind: Service
      name: store-v1
      port: 8080
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: store-v2-route
spec:
  parentRefs:
  - kind: Gateway
    name: internal-http
  hostnames:
  - "store.example.com"
  rules:
  - matches:
    - headers:
      - type: Exact
        name: env
        value: canary
    backendRefs:
    - kind: Service
      name: store-v2
      port: 8080
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: store-german-route
spec:
  parentRefs:
  - kind: Gateway
    name: internal-http
  hostnames:
  - "store.example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /de
    backendRefs:
    - kind: Service
      name: store-german
      port: 8080

Gateways do Kubernetes e gateways do Istio

Observe que a API Gateway do Kubernetes e a API do Istio têm um recurso chamado Gateway. Eles executam funções semelhantes, mas não são a mesma funcionalidade. Se você estiver usando o Istio e a API Gateway no mesmo cluster do Kubernetes, esses nomes serão sobrepostos ao usar o kubectl na linha de comando. kubectl get gateway pode retornar os recursos do gateway do Kubernetes, e não os recursos do gateway do Istio, ou vice-versa.

$ kubectl api-resources
NAME       SHORTNAMES   APIGROUP                       NAMESPACED   KIND
gateways   gw           networking.istio.io/v1beta1    true         Gateway
gateways   gtw          networking.k8s.io/v1beta1      true         Gateway

Se estiver usando o Istio e fizer upgrade para o GKE 1.20 e posterior, é recomendável começar a usar o nome curto do recurso do gateway ou especificar o grupo da API. O nome curto de um gateway do Kubernetes é gtw, e o de um gateway do Istio é gw. Os comandos a seguir retornam os recursos do gateway do Kubernetes e do Istio, respectivamente.

# Kubernetes Gateway
$ kubectl get gtw
NAME                        CLASS
multi-cluster-gateway       gke-l7-global-external-managed-mc

$ kubectl get gateway.networking.x-k8s.io
NAME                        CLASS
multi-cluster-gateway       gke-l7-global-external-managed-mc

# Istio Gateway
$ kubectl get gw
NAME               AGE
bookinfo-gateway   64m

$ kubectl get gateway.networking.istio.io
NAME               AGE
bookinfo-gateway   64m

Solução de problemas

Sub-rede somente proxy ausente na região

Sintoma:

O seguinte problema pode ocorrer ao criar um gateway regional (interno ou externo):

generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/[REGION_NAME]/targetHttpProxies/gkegw-x5vt-default-internal-http-[ID]'. A reserved managed proxy subnetwork with purpose REGIONAL_MANAGED_PROXY is required.

Motivo:

Essa mensagem de erro indica que não existe sub-rede somente proxy na região do seu gateway.

Alternativa:

Para resolver esse problema, configure uma sub-rede apenas proxy.

Já existe uma sub-rede somente proxy na região com a finalidade incorreta

Sintoma:

O seguinte problema pode ocorrer quando você cria uma sub-rede somente proxy para seu gateway regional (interno ou externo):

ERROR: (gcloud.compute.networks.subnets.create) Could not fetch resource:
 - The resource 'projects/[PROJECT_NAME]/regions/[REGION_NAME]/subnetworks/[PROXY_ONLY_SUBNET_NAME]' already exists

Motivo:

Essa mensagem de erro indica que você tentou criar uma sub-rede somente proxy regional em uma região que já tem uma sub-rede somente proxy.

Alternativa:

Para resolver esse problema, use os passos a seguir:

  1. Verifique se já existe uma sub-rede somente proxy na região e se ela tem a finalidade correta:

    1. Liste suas sub-redes para descobrir qual delas é a sub-rede somente proxy na região:

      gcloud compute networks subnets list --regions=COMPUTE_REGION
      

      Substitua COMPUTE_REGION pela região do Compute Engine em que você quer criar o gateway regional.

    2. Descreva a sub-rede somente proxy na região para encontrar a finalidade dela:

      gcloud compute networks subnets describe PROXY_ONLY_SUBNET \
          --region COMPUTE_REGION | grep -E 'name|purpose'
      

      Substitua PROXY_ONLY_SUBNET pela sub-rede somente proxy.

    O gateway do GKE só oferece suporte a sub-redes somente proxy REGIONAL_MANAGED_PROXY para gateways regionais (internos ou regionais).

  2. Se a sub-rede somente proxy atual na região foi criada com a finalidade INTERNAL_HTTPS_LOAD_BALANCER, migre a finalidade para REGIONAL_MANAGED_PROXY.

Nenhum upstream íntegro

Sintoma:

O seguinte problema pode ocorrer quando você cria um gateway mas não pode acessar os serviços de back-end (código de resposta 503):

no healthy upstream

Motivo:

Esta mensagem de erro indica que a sondagem da verificação de integridade não consegue encontrar a integridade dos serviços de back-end. É possível que os serviços de back-end estejam íntegros, mas talvez seja necessário personalizar as verificações de integridade.

Alternativa:

Para resolver esse problema, personalize a verificação de integridade com base nos requisitos do aplicativo (por exemplo, /health) usando uma HealthCheckPolicy.

Recursos de gateway órfãos após a exclusão do cluster

Sintoma:

Ao tentar recriar o gateway, os recursos do balanceador de carga gerenciado pelo GKE ainda permanecem visíveis no console do Google Cloud , mas não podem ser excluídos usando a UI, que mostra uma mensagem semelhante a esta:

This load balancing service is read-only. It is managed by GKE and can be modified only by GKE.

Motivo:

Esse problema ocorre quando o controlador de gateway não limpa os recursos Google Cloud subjacentes desatualizados durante a exclusão e recriação do cluster ou do gateway.

Alternativa:

Para resolver esse problema, exclua os recursos de balanceamento de carga órfãos usando os comandos da Google Cloud CLI da seguinte maneira:


gcloud compute forwarding-rules delete FORWARDING_RULE_NAME

# For HTTP proxies
gcloud compute target-http-proxies delete PROXY_NAME

# For HTTPS proxies
gcloud compute target-https-proxies delete PROXY_NAME

gcloud compute url-maps delete URL_MAP_NAME

# For global backend services
gcloud compute backend-services delete BACKEND_SERVICE_NAME --global

# For regional backend services
gcloud compute backend-services delete BACKEND_SERVICE_NAME --region=REGION

gcloud compute health-checks delete HEALTH_CHECK_NAME

gcloud compute network-endpoint-groups delete NEG_NAME --zone=ZONE

Substitua:

  • FORWARDING_RULE_NAME: o nome da regra de encaminhamento.
  • PROXY_NAME: o nome do proxy de destino.
  • URL_MAP_NAME: o nome do mapa de URL.
  • BACKEND_SERVICE_NAME: o nome do serviço de back-end.
  • HEALTH_CHECK_NAME: o nome da verificação de integridade.
  • NEG_NAME: o nome do grupo de endpoints da rede.
  • REGION: a região do serviço de back-end regional.
  • ZONE: a zona do grupo de endpoints de rede.

A seguir