Personalizar o tráfego do gateway do GKE usando extensões de serviço


Nesta página, descrevemos como o Google Kubernetes Engine (GKE) usa as extensões de serviço para adicionar lógica personalizada ao balanceamento de carga do Cloud.

Esta página é destinada a administradores de identidade e conta do GKE e desenvolvedores que precisam configurar a lógica de gerenciamento de tráfego personalizado usando extensões de serviço.

Antes de ler esta página, confira se você conhece os seguintes conceitos:

Visão geral

O GKE usa extensões de serviço para adicionar lógica personalizada ao Cloud Load Balancing. Uma extensão se conecta a um Gateway e faz referência a um Service ou a um GoogleAPIServiceName. O GoogleAPIServiceName é compatível apenas com GCPTrafficExtensions.

É possível modificar cabeçalhos e payloads HTTP para solicitações e respostas ou controlar o roteamento de tráfego sem afetar a seleção de serviços de back-end ou as políticas de segurança. É possível usar extensões de serviço para tarefas como divisão avançada de tráfego, autenticação personalizada ou registro de solicitações.

O controlador de gateway do GKE é compatível com as seguintes extensões de serviço:

  • GCPRoutingExtension: essa extensão adiciona lógica personalizada ao Cloud Load Balancing para controlar o roteamento de tráfego. Ele tem suporte para balanceadores de carga de aplicativo externos e internos regionais.

    O recurso "GCPRoutingExtension" é anexado a um gateway e faz referência a um serviço. A extensão
        controla o roteamento de tráfego.
    Figura: como a `GCPRoutingExtension` funciona com gateways
  • GCPTrafficExtension: essa extensão insere uma lógica personalizada no balanceamento de carga do Cloud. Ele permite que um serviço de extensão mude os cabeçalhos e payloads de solicitações e respostas. O GCPTrafficExtension não afeta a seleção de serviços de back-end nem as políticas de segurança de serviços de back-end.

    O recurso "GCPTrafficExtension" é anexado a uma gateway e
        faz referência a um serviço ou a um "GoogleAPIServiceName". A extensão
        muda os cabeçalhos e os payloads de solicitações e respostas.
    Figura: como a `GCPTrafficExtension` funciona com os gateways

Google Cloud Compatibilidade da extensão de serviço com GatewayClasses

A tabela a seguir descreve a compatibilidade das extensões de serviço Google Cloud com diferentes GatewayClasses:

GatewayClass GCPRoutingExtension GCPTrafficExtension
gke-l7-rilb Compatível Compatível
gke-l7-regional-external-managed Compatível Compatível
gke-l7-global-external-managed Incompatível Compatível

Antes de começar

Antes de começar, veja se você realizou as seguintes tarefas:

  • Ative a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Se você quiser usar a CLI do Google Cloud para essa tarefa, instale e, em seguida, inicialize a CLI gcloud. Se você instalou a gcloud CLI anteriormente, instale a versão mais recente executando gcloud components update.

Requisitos do GKE Gateway Controller

Restrições e limitações

A tabela a seguir lista as restrições associadas à configuração das extensões de serviço do gateway no GKE:

Categoria Restrições e limitações
Balanceador de carga O GCPRoutingExtension tem suporte apenas para balanceadores de carga de aplicativo externos regionais e balanceadores de carga de aplicativo internos regionais (classes de gateway gke-l7-regional-external-managed e gke-l7-rilb) e não tem suporte para a classe de gateway gke-l7-global-external-managed.
Cadeia de extensão e especificação
  • Para um GCPTrafficExtension, cada ExtensionChain pode ter no máximo 3 Extensions.
  • Para um GCPRoutingExtension, cada ExtensionChain é limitado a uma Extension.
  • Um GCPTrafficExtensionSpec e um GCPRoutingExtensionSpec podem ter, no máximo, 5 ExtensionChains.
Tempo e correspondência
  • O tempo limite para cada mensagem individual no stream em uma extensão precisa ser de 10 a 1.000 milissegundos. Esse limite de um segundo se aplica a extensões de rota e tráfego.
  • Cada MatchCondition em um ExtensionChain é limitado a um máximo de 10 CELExpressions.
  • A string MatchCondition resultante enviada para o GCE tem um limite de 512 caracteres.
  • A string CELMatcher em um CELExpression tem um comprimento máximo de 512 caracteres e precisa seguir um padrão específico. Não oferecemos suporte ao campo BackendRefs de CELExpression.
Cabeçalho e metadados
  • A lista ForwardHeaders em um Extension pode conter no máximo 50 nomes de cabeçalhos HTTP.
  • O mapa Metadata em um Extension pode ter no máximo 16 propriedades.
  • As chaves no mapa Metadata precisam ter entre 1 e 63 caracteres.
  • Os valores no mapa Metadata precisam ter entre 1 e 1.023 caracteres.
Evento
  • Para um GCPRoutingExtension, se requestBodySendMode não estiver definido, a lista supportedEvents só poderá conter eventos RequestHeaders.
  • Para um GCPRoutingExtension, se requestBodySendMode for definido como FullDuplexStreamed, a lista supportedEvents só poderá conter eventos RequestHeaders, RequestBody e RequestTrailers.
GCPTrafficExtension
  • O campo responseBodySendMode é aceito apenas para GCPTrafficExtension.
  • O campo googleAPIServiceName é aceito apenas para GCPTrafficExtension.
googleAPIServiceName e backendRef Ao fazer referência a um serviço que usa backendRef em uma extensão, você precisa atender às seguintes condições:
  • É necessário usar HTTP2 como appProtocol.
  • Precisa estar no mesmo namespace que a extensão e o gateway referenciado pela extensão.
  • Não é possível usar o IAP.
  • Não é possível usar políticas de segurança do Google Cloud Armor (campo securityPolicy de GCPBackendPolicyConfig).
  • Não é possível usar o Cloud CDN.
  • É necessário definir exatamente um entre backendRef ou googleAPIServiceName para um Extension.
  • Precisa definir authority se backendRef estiver definido.
  • Precisa definir authority se googleAPIServiceName estiver definido.
  • Configure requestBodySendMode para extensões usando apenas backendRef.
  • Configure responseBodySendMode para extensões usando apenas backendRef.

Configurar extensões de serviço do GKE

É possível personalizar o roteamento de tráfego, modificar payloads de solicitação ou resposta e integrar com serviços externos configurando as extensões de serviço do GKE. Os gateways não têm extensões de serviço por padrão.

Para configurar as extensões de serviço do GKE:

  1. Implantar um gateway: para configurar uma extensão de serviço do GKE, primeiro é necessário implantar um gateway, que direciona o tráfego externo para o cluster. Pode ser um balanceador de carga de aplicativo externo global, um balanceador de carga de aplicativo externo regional ou um gateway de balanceador de carga de aplicativo interno regional.

    Para mais informações sobre a implantação de gateways, consulte Como implantar gateways.

  2. Implantar um serviço de chamada de back-end: crie um serviço do Kubernetes que represente o serviço de back-end para execução de lógica personalizada. O balanceador de carga invoca esse serviço.

  3. Configure as extensões de serviço: configure as extensões de serviço adequadas com base no tipo e nos requisitos do balanceador de carga.

    1. GCPRoutingExtension para gateways regionais: use essa extensão para balanceadores de carga de aplicativo externos regionais e balanceadores de carga de aplicativo internos regionais para implementar uma lógica de roteamento personalizada na região.

    2. GCPTrafficExtension para gateways globais externos, regionais externos e internos: use essa extensão para balanceadores de carga de aplicativo globais externos, regionais externos e regionais internos para realizar a manipulação de tráfego, como modificação de cabeçalho ou inspeção de payload, em vários tipos de balanceadores de carga.

Implantar um serviço de chamada de back-end

Um serviço de chamada implementa uma lógica personalizada para extensões de serviço de gateway no GKE. O gateway invoca esses aplicativos de back-end com base nas configurações GCPTrafficExtension ou GCPRoutingExtension para modificar ou rotear o tráfego.

Você implanta um serviço de chamada para adicionar lógica personalizada ao gateway. Esse serviço separado processa o processamento personalizado, como manipulação de cabeçalho, transformações de payload ou roteamento de tráfego.

Para implantar um serviço de back-end que possa funcionar como um callout para o Gateway, siga estas etapas:

  1. (Opcional) Criar um secret para TLS: este comando cria um secret do Kubernetes do tipo TLS que contém o certificado TLS e a chave privada.

    Para criar o secret TLS para seu serviço de chamada, substitua o seguinte:

    • SECRET_NAME: o nome secreto do serviço de chamada.
    • path-to-cert: os caminhos de arquivo para o certificado
    • path-to-key: os caminhos de arquivo para a chave
  2. Para verificar se o secret foi adicionado, execute o seguinte comando:

    kubectl get secrets SECRET_NAME
    

    Substitua SECRET_NAME pelo nome secreto do serviço de chamada.

    A saída será semelhante a esta:

    NAME            TYPE                DATA   AGE
    SECRET_NAME     kubernetes.io/tls   2      12s
    
  3. Defina os recursos de implantação e serviço.

    Você precisa definir o seguinte:

    • Implantação: para gerenciar os pods de aplicativos que contêm a lógica personalizada das extensões de serviço.
    • Serviço: para expor os pods de aplicativos gerenciados pela implantação como um serviço de rede.
    1. Crie um exemplo de manifesto extension-service-app.yaml com definições de implantação e serviço:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
      name: extension-service-app
      spec:
      selector:
          matchLabels:
            app: store
        replicas: 1
        template:
          metadata:
            labels:
              app: store
          spec:
            containers:
            - name: serviceextensions
              image: us-docker.pkg.dev/service-extensions-samples/callouts/python-example-basic:main
              ports:
              - containerPort: 8080
              - containerPort: 443
              volumeMounts:
              - name: certs
                mountPath: "/etc/certs/"
                readOnly: true
              env:
              - name: POD_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: NAMESPACE
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.namespace
              - name: TLS_SERVER_CERT
                value: "/etc/certs/path-to-cert"
              - name: TLS_SERVER_PRIVKEY
                value: "/etc/certs/path-to-key"
                resources:
                requests:
                  cpu: 10m
            volumes:
            - name: certs
              secret:
                secretName: SECRET_NAME
                optional: false
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: extension-service
      spec:
        ports:
        - port: 443
          targetPort: 443
          appProtocol: HTTP2
        selector:
          app: store
      
    2. Aplique o manifesto extension-service-app.yaml:

      kubectl apply -f extension-service-app.yaml
      
  4. Verifique a configuração:

    1. Verifique se o aplicativo foi implantado:

      kubectl get pod --selector app=store
      

      Depois que o aplicativo começar a ser executado, a saída será semelhante a esta:

      NAME                                     READY   STATUS    RESTARTS   AGE
      extension-service-app-85f466bc9b-b5mf4   1/1     Running   0          7s
      
    2. Verifique se o serviço foi implantado:

      kubectl get service extension-service
      

      A saída é semelhante à seguinte, que mostra um serviço para cada implantação de loja:

      NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
      extension-service   ClusterIP   34.118.225.9   <none>        443/TCP   2m40s
      

Configurar as extensões de serviço

É possível configurar um GCPRoutingExtension ou um GCPTrafficExtension para personalizar o fluxo de tráfego.

Configurar o GCPRoutingExtension para gateways regionais

É possível redirecionar o tráfego usando um GCPRoutingExtension. Para configurar um GCPRoutingExtension, atualize o HTTPRoute para especificar as solicitações do host service-extensions.com.

  1. Atualize o HTTPRoute. Modifique o HTTPRoute para incluir nomes de host ou caminhos que acionam a extensão de roteamento.

    1. Salve o seguinte exemplo de manifesto como o arquivo store-route.yaml:

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store
      spec:
        parentRefs:
        - kind: Gateway
          name:GATEWAY_NAME
        hostnames:
        - "store.example.com"
        - "service-extensions.example.com"
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
        - matches:
          - headers:
            - name: env
              value: canary
          backendRefs:
          - name: store-v2
            port: 8080
        - matches:
          - path:
              value: /de
          backendRefs:
          - name: store-german
            port: 8080
      

      Substitua GATEWAY_NAME pelo nome do gateway.

    2. Aplique o manifesto store-route.yaml:

      kubectl apply -f store-route.yaml
      
  2. Defina o GCPRoutingExtension.

    1. Salve a configuração GCPRoutingExtension no arquivo de amostra gcp-routing-extension.yaml:

      kind: GCPRoutingExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: my-gateway-extension
        namespace: default
      spec:
        targetRefs:
        - group: "gateway.networking.k8s.io"
          kind: Gateway
          name: GATEWAY_NAME
        extensionChains:
        - name: chain1
          matchCondition:
            celExpressions:
            - celMatcher: request.path.contains("serviceextensions")
          extensions:
          - name: ext1
            authority: "myext.com"
            timeout: 1s
              backendRef:
                group: ""
              kind: Service
              name: extension-service
              port: 443
      

      Substitua GATEWAY_NAME pelo nome do gateway.

    2. Aplique o manifesto de exemplo ao cluster:

      kubectl apply -f gcp-routing-extension.yaml
      
  3. Verifique a configuração do GCPRoutingExtension e a vinculação dele ao gateway.

    1. Verifique a implantação GCPRoutingExtension:

      kubectl describe gcproutingextension my-gateway-extension
      

      O resultado será assim:

      Name:         my-gateway-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPRoutingExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:    myext.com
            Backend Ref:
              Group:
              Kind: Service
              Name: extension-service
              Port: 443
            Name:       ext1
            Timeout:    1s
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      A saída mostra os detalhes do GCPRoutingExtension, que é chamado my-gateway-extension, no namespace padrão. A saída mostra o campo Spec, que contém a definição de como a extensão precisa se comportar.

    2. Verifique a vinculação do gateway:

      1. Confirme se o GCPRoutingExtension está vinculado ao gateway. Isso pode levar alguns minutos:

        kubectl describe gateway GATEWAY_NAME
        

        O resultado será assim:

        Name:         GATEWAY_NAME
        Namespace:    default
        Labels:       none
        Annotations:  networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr
                      networking.gke.io/backend-services:
                        /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re...
                      networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1
                      networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73
                      networking.gke.io/health-checks:
                        /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio...
                      networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z
                      networking.gke.io/lb-route-extensions:
                        /projects/1234567890/locations/us-central1/lbRouteExtensions/test-hgbk-default-internal-http-lwh0op4qorb0
                      networking.gke.io/lb-traffic-extensions:
                      networking.gke.io/ssl-certificates:
                      networking.gke.io/target-http-proxies:
                        /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj
                      networking.gke.io/target-https-proxies:
                      networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj
        API Version:  gateway.networking.k8s.io/v1
        Kind:         Gateway
        Metadata:
          Creation Timestamp:  2025-03-02T16:37:50Z
          Finalizers:
          gateway.finalizer.networking.gke.io
          Generation:        1
          Resource Version:  31284863
          UID:               fd512611-bad2-438e-abfd-5619474fbf31
        ...
        

        A saída mostra as anotações que o GKE usa para armazenar os links entre o gateway e os recursos Google Cloud . A anotação networking.gke.io/lb-route-extensions confirma a vinculação do gateway ao GCPRoutingExtension.

      2. Verifique o status da extensão confirmando que o GCPRoutingExtension tem um status Reconciled com o motivo ReconciliationSucceeded. Esse comando pode levar alguns minutos.

        kubectl describe gcproutingextension my-gateway-extension
        

        O resultado será assim:

        Name:         my-gateway-extension
        Namespace:    default
        Labels:       <none>
        Annotations:  <none>
        API Version:  networking.gke.io/v1
        Kind:         GCPRoutingExtension
        Metadata:
          Creation Timestamp:  2025-03-02T17:12:30Z
          Generation:          1
          Resource Version:    31284378
          UID:                 ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
        Spec:
          Extension Chains:
            Extensions:
              Authority:  myext.com
              Backend Ref:
                Group:
                Kind:   Service
                Name:   extension-service
                Port:   443
              Name:     ext1
              Timeout:  1s
            Match Condition:
              Cel Expressions:
                Cel Matcher:  request.path.contains("serviceextensions")
            Name:             chain1
          Target Refs:
            Group:  gateway.networking.k8s.io
            Kind:   Gateway
            Name:   GATEWAY_NAME
        Status:
          Ancestors:
            Ancestor Ref:
              Group:      gateway.networking.k8s.io
              Kind:       Gateway
              Name:       GATEWAY_NAME
              Namespace:  default
            Conditions:
              Last Transition Time:  2025-03-02T17:14:15Z
              Message:
              Reason:                Accepted
              Status:                True
              Type:                  Accepted
              Last Transition Time:  2025-03-02T17:14:15Z
              Message:
              Reason:                ReconciliationSucceeded
              Status:                True
              Type:                  Reconciled
            Controller Name:         networking.gke.io/gateway
        Events:
          Type    Reason  Age                From                   Message
          ----    ------  ----               ----                   -------
          Normal  ADD     2m31s              sc-gateway-controller  default/my-gateway-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
          Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
        

        O campo Status.Conditions mostra uma condição Reconciled com Status: True e Reason: ReconciliationSucceeded.

        Verdadeiro e Razão: ReconciliationSucceeded. Essas informações confirmam que a extensão foi aplicada.

  4. Envie tráfego para o aplicativo.

    Depois que o gateway, a rota e o aplicativo forem implantados no cluster, será possível transmitir o tráfego para o aplicativo.

    1. Para acessar o aplicativo, você precisa encontrar o endereço IP do gateway.

      No terminal, use o seguinte comando:

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

      Substitua GATEWAY_NAME pelo nome do gateway.

      Esse comando gera o endereço IP do gateway. Nos comandos de acompanhamento, substitua GATEWAY_IP_ADDRESS pelo endereço IP da saída.

    2. Para testar a atualização do caminho, acesse a versão serviceextensions do serviço da loja em store.example.com/serviceextensions:

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

      O resultado será assim:

      {
      "cluster_name": "gke1",
      "host_header": "service-extensions.com",
      "metadata": "store-v1",
      "pod_name": "store-v1-5d9554f847-cvxpd",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo",
      "timestamp": "2025-03-15T12:00:00",
      "zone": "us-central1-c"
      }
      

Configurar o GCPTrafficExtension

É possível usar um GCPTrafficExtension para usar recursos avançados de gerenciamento de tráfego no ambiente Google Cloud . É possível configurar essa extensão em balanceadores de carga de aplicativo externos globais, regionais e internos. É possível usar GCPTrafficExtension para implementar lógica de solicitação e resposta personalizada, roteamento sofisticado, transformações e políticas de segurança.

  1. Atualize o HTTPRoute. Modifique o HTTPRoute para incluir nomes de host ou caminhos que acionam a extensão de tráfego.

    1. Salve o seguinte exemplo de manifesto como o arquivo store-route.yaml:

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store
      spec:
        parentRefs:
        - kind: Gateway
          name: GATEWAY_NAME
        hostnames:
        - "store.example.com"
        - "service-extensions.example.com"
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
        - matches:
          - headers:
            - name: env
              value: canary
          backendRefs:
          - name: store-v2
            port: 8080
        - matches:
          - path:
              value: /de
          backendRefs:
          - name: store-german
            port: 8080
      

      Substitua GATEWAY_NAME pelo nome do gateway, como internal-http, external-http ou global-external-http.

    2. Aplique o manifesto store-route.yaml ao cluster:

      kubectl apply -f store-route.yaml
      
  2. Defina o GCPTrafficExtension.

    1. Salve a configuração GCPTrafficExtension no arquivo de amostra gcp-traffic-extension.yaml:

      kind: GCPTrafficExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: my-traffic-extension
        namespace: default
      spec:
        targetRefs:
        - group: "gateway.networking.k8s.io"
          kind: Gateway
          name: GATEWAY_NAME
        extensionChains:
        - name: chain1
          matchCondition:
            celExpressions:
            - celMatcher: request.path.contains("serviceextensions")
          extensions:
          - name: ext1
            authority: "myext.com"
            timeout: 1s
            backendRef:
              group: ""
              kind: Service
              name: extension-service
              port: 443
      

      Substitua GATEWAY_NAME pelo nome do gateway, como internal-http, external-http ou global-external-http.

    2. Aplique o manifesto de exemplo ao cluster:

      kubectl apply -f gcp-traffic-extension.yaml
      
  3. Verifique a configuração do GCPTrafficExtension e a vinculação dele ao gateway.

    1. Verifique a implantação GCPTrafficExtension:

      kubectl describe gcptrafficextension my-traffic-extension
      

      O resultado será assim:

      Name:         my-traffic-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:    myext.com
            Backend Ref:
              Group:
              Kind: Service
              Name: extension-service
              Port: 443
            Name:       ext1
            Timeout:    1s
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      A saída mostra os detalhes do GCPTrafficExtension chamado my-traffic-extension no namespace padrão. Ele mostra o campo Spec, que contém a definição de como a extensão deve se comportar.

    2. Verifique a vinculação do gateway:

      Confirme se o GCPTrafficExtension está vinculado ao gateway. Esse comando pode levar alguns minutos para ser concluído:

      kubectl describe gateway GATEWAY_NAME
      

      O resultado será assim:

      Name:         GATEWAY_NAME
      Namespace:    default
      Labels:       <none>
      Annotations:  networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr
                    networking.gke.io/backend-services:
                      /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re...
                    networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1
                    networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73
                    networking.gke.io/health-checks:
                      /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio...
                    networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z
                    networking.gke.io/lb-traffic-extensions:
                      /projects/1234567890/locations/us-central1/lbTrafficExtensions/test-hgbk-default-internal-http-lwh0op4qorb0
                    networking.gke.io/ssl-certificates:
                    networking.gke.io/target-http-proxies:
                      /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj
                    networking.gke.io/target-https-proxies:
                    networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj
      API Version:  gateway.networking.k8s.io/v1
      Kind:         Gateway
      Metadata:
        Creation Timestamp:  2025-03-02T16:37:50Z
        Finalizers:
          gateway.finalizer.networking.gke.io
        Generation:        1
        Resource Version:  31284863
        UID:               fd512611-bad2-438e-abfd-5619474fbf31
      ...
      

      A saída mostra as anotações que o GKE usa para armazenar os links entre o gateway e os recursos Google Cloud subjacentes. A anotação networking.gke.io/lb-traffic-extensions confirma a vinculação.

    3. Verifique o status da extensão:

      Confirme se o GCPTrafficExtension tem o status Reconciled com o motivo ReconciliationSucceeded. Esse comando pode levar alguns minutos para ser concluído.

      kubectl describe gcptrafficextension my-traffic-extension
      

      O resultado será assim:

      Name:         my-traffic-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:          1
        Resource Version:    31284378
        UID:                 ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:  myext.com
            Backend Ref:
              Group:
              Kind:   Service
              Name:   extension-service
              Port:   443
            Name:     ext1
            Timeout:  1s
          Match Condition:
            Cel Expressions:
              Cel Matcher:  request.path.contains("serviceextensions")
          Name:             chain1
        Target Refs:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   GATEWAY_NAME
      Status:
        Ancestors:
          Ancestor Ref:
            Group:      gateway.networking.k8s.io
            Kind:       Gateway
            Name:       GATEWAY_NAME
            Namespace:  default
          Conditions:
            Last Transition Time:  2025-03-02T17:14:15Z
            Message:
            Reason:                Accepted
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-03-02T17:14:15Z
            Message:
            Reason:                ReconciliationSucceeded
            Status:                True
            Type:                  Reconciled
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                From                   Message
        ----    ------  ----               ----                   -------
        Normal  ADD     2m31s              sc-gateway-controller  default/my-traffic-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPTrafficExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
        Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPTrafficExtension "default/my-traffic-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
      

      O campo Status.Conditions mostra uma condição Reconciled com Status: True e Reason: ReconciliationSucceeded. Essas informações confirmam que a extensão foi aplicada.

  4. Envie tráfego para o aplicativo.

    Depois que o gateway, a rota e o aplicativo forem implantados no cluster, será possível transmitir o tráfego para o aplicativo.

    1. Para acessar o aplicativo, você precisa encontrar o endereço IP do gateway.

      No terminal, use o seguinte comando:

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

      Substitua GATEWAY_NAME pelo nome do gateway.

      Esse comando gera o endereço IP do gateway. Nos comandos de acompanhamento, substitua GATEWAY_IP_ADDRESS pelo endereço IP da saída.

    2. Para testar a atualização do caminho, acesse a versão serviceextensions do serviço da loja em store.example.com/serviceextensions:

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

      O resultado será assim:

      {
      *   Request completely sent off
      < HTTP/1.1 200 OK
      < server: Werkzeug/2.3.7 Python/3.11.3
      < date: Sun, 02 Mar 2025 16:58:10 GMT
      < content-type: application/json
      < access-control-allow-origin: *
      < hello: service-extensions
      < via: 1.1 google
      < transfer-encoding: chunked
      }
      

Resolver problemas de extensões de tráfego em gateways

Esta seção fornece dicas de solução de problemas para configurar extensões de tráfego em gateways.

Gateway não encontrado

O erro a seguir indica que o recurso de gateway especificado no campo targetRefs do recurso GCPTrafficExtension ou GCPRoutingExtension não existe:

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.gatewayRef: gateway "my-gateway" not found in namespace "default"

Para resolver esse problema, verifique se o recurso de gateway especificado no campo targetRefs do recurso GCPTrafficExtension ou GCPRoutingExtension existe no namespace especificado.

Serviço ou porta de serviço não encontrada

O erro a seguir indica que a porta de serviço ou serviço especificada no campo backendRef do recurso GCPTrafficExtension ou GCPRoutingExtension não existe:

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: service "callout-service" not found in namespace "default"

Para resolver esse problema, verifique se o serviço e a porta de serviço especificados no campo backendRef do recurso GCPTrafficExtension ou GCPRoutingExtension existem no namespace especificado.

Não há endpoints de rede no NEG

O erro a seguir indica que não há endpoints de rede no NEG associados ao serviço especificado no campo backendRef do recurso GCPTrafficExtension ou GCPRoutingExtension:

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: no network endpoints found for service "callout-service"

Para resolver esse problema, verifique se o serviço especificado no campo backendRef do recurso GCPTrafficExtension ou GCPRoutingExtension tem endpoints de rede.

Nenhuma resposta ou resposta com um erro ao enviar a solicitação

Se você não receber uma resposta ou receber uma resposta com um erro ao enviar uma solicitação, isso pode indicar que o serviço de chamada não está funcionando corretamente.

Para resolver esse problema, verifique se há erros nos registros do serviço de chamada.

Código de erro 404 no payload JSON

O erro a seguir indica que o serviço de chamada não foi encontrado ou não está respondendo à solicitação:

{
  "error": {
    "code": 404,
    "message": "Requested entity was not found.",
    "status": "NOT_FOUND"
  }
}

Para resolver esse problema, verifique se o serviço de chamada está em execução, se ele está escutando na porta correta e se ele está configurado corretamente no recurso GCPTrafficExtension ou GCPRoutingExtension.

Código de erro 500 no payload JSON

O erro a seguir indica que o serviço de chamada está com um erro interno do servidor:

{
  "error": {
    "code": 500,
    "message": "Internal server error.",
    "status": "INTERNAL"
  }
}

Para resolver esse problema, verifique os registros do serviço de chamada para identificar a causa do erro interno do servidor.

A seguir