Personalize o tráfego do GKE Gateway com extensões de serviço


Esta página descreve como o Google Kubernetes Engine (GKE) usa as extensões de serviço para adicionar lógica personalizada ao Cloud Load Balancing.

Esta página destina-se aos administradores de identidade e de contas do GKE e aos programadores que precisam de configurar uma lógica de gestão de tráfego personalizada através de extensões de serviço.

Antes de ler esta página, certifique-se de que conhece o seguinte:

Vista geral

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

Pode modificar os cabeçalhos e os payloads HTTP para pedidos e respostas, ou controlar o encaminhamento de tráfego, sem afetar a seleção do serviço de back-end nem as políticas de segurança. Pode usar as extensões de serviço para tarefas como a divisão avançada do tráfego, a autenticação personalizada ou o registo de pedidos.

O controlador do GKE Gateway suporta as seguintes extensões de serviço:

  • GCPRoutingExtension: esta extensão adiciona lógica personalizada ao equilíbrio de carga na nuvem para controlar o encaminhamento de tráfego. É suportado para o balanceador de carga de aplicações externo regional e o balanceador de carga de aplicações interno regional.

    O recurso `GCPRoutingExtension` está anexado a um gateway e faz
        referência a um serviço. A extensão
        controla o encaminhamento de tráfego.
    Figura: como a GCPRoutingExtension funciona com gateways
  • GCPTrafficExtension: esta extensão insere lógica personalizada no Cloud Load Balancing. Permite que um serviço de extensão altere os cabeçalhos e os payloads de pedidos e respostas. O GCPTrafficExtension não afeta a seleção do serviço de back-end nem as políticas de segurança do serviço de back-end.

    O recurso `GCPTrafficExtension` está anexado a um gateway e faz referência a um serviço ou a um `GoogleAPIServiceName`. A extensão altera os cabeçalhos e os payloads de pedidos e respostas.
    Figura: como a GCPTrafficExtension funciona com gateways

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

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

GatewayClass GCPRoutingExtension GCPTrafficExtension
gke-l7-rilb Suportado Suportado
gke-l7-regional-external-managed Suportado Suportado
gke-l7-global-external-managed Não suportado Suportado

Antes de começar

Antes de começar, certifique-se de que realizou as seguintes tarefas:

  • Ative a API Google Kubernetes Engine.
  • Ative a API Google Kubernetes Engine
  • Se quiser usar a CLI gcloud para esta tarefa, instale-a e, em seguida, inicialize-a. Se instalou anteriormente a CLI gcloud, execute gcloud components update para obter a versão mais recente.

Requisitos do GKE Gateway Controller

Restrições e limitações

A tabela seguinte indica as restrições associadas à configuração das extensões de serviços de gateway no GKE:

Categoria Restrições e limitações
Balanceador de carga O GCPRoutingExtension é suportado apenas para o Application Load Balancer externo regional e o Application Load Balancer interno regional (gke-l7-regional-external-managed e gke-l7-rilb classes de gateway) e não é suportado pela classe de gateway gke-l7-global-external-managed.
Especificação e cadeia de extensões
  • Para um GCPTrafficExtension, cada ExtensionChain pode ter um máximo de 3 Extensions.
  • Para um GCPRoutingExtension, cada ExtensionChain está limitado a 1 Extension.
  • Um GCPTrafficExtensionSpec e um GCPRoutingExtensionSpec podem ter, cada um, um máximo de 5 ExtensionChains.
Sincronização e correspondência
  • O limite de tempo para cada mensagem individual na stream numa extensão tem de estar entre 10 e 1000 milissegundos. Este limite de um segundo aplica-se às extensões de rota e tráfego.
  • Cada MatchCondition num ExtensionChain está limitado a um máximo de 10 CELExpressions.
  • A string MatchCondition resultante enviada para o GCE tem um limite de 512 carateres.
  • A string CELMatcher num CELExpression tem um comprimento máximo de 512 carateres e tem de seguir um padrão específico. O campo BackendRefs de CELExpression não é suportado.
Cabeçalho e metadados
  • A lista ForwardHeaders num Extension pode conter um máximo de 50 nomes de cabeçalhos HTTP.
  • O mapa Metadata numa Extension pode ter um máximo de 16 propriedades.
  • As chaves no mapa Metadata têm de ter entre 1 e 63 carateres.
  • Os valores no mapa Metadata têm de ter entre 1 e 1023 carateres.
Evento
  • Para um GCPRoutingExtension, se requestBodySendMode não estiver definido, a lista supportedEvents só pode conter eventos RequestHeaders.
  • Para um GCPRoutingExtension, se requestBodySendMode estiver definido como FullDuplexStreamed, a lista supportedEvents só pode conter eventos RequestHeaders, RequestBody e RequestTrailers.
GCPTrafficExtension
  • O campo responseBodySendMode é suportado apenas para GCPTrafficExtension.
  • O campo googleAPIServiceName é suportado apenas para GCPTrafficExtension.
googleAPIServiceName e backendRef Quando faz referência a um Serviço que usa a backendRef numa Extensão, tem de cumprir as seguintes condições:
  • Tem de usar HTTP2 como appProtocol.
  • Tem de estar no mesmo espaço de nomes que a extensão e o gateway referenciados pela extensão.
  • Não é possível usar a CNA.
  • 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.
  • Tem de definir exatamente uma das propriedades backendRef ou googleAPIServiceName para um Extension.
  • Tem de definir authority se backendRef estiver definido.
  • Tem de definir authority se googleAPIServiceName estiver definido.
  • Configure o requestBodySendMode para extensões usando apenas o backendRef.
  • Configure o responseBodySendMode para extensões usando apenas o backendRef.

Configure as extensões de serviço do GKE

Pode personalizar o encaminhamento de tráfego, modificar payloads de pedidos ou respostas 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ços por predefinição.

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

  1. Implemente um gateway: para configurar uma extensão de serviço do GKE, tem de implementar primeiro um gateway, que direciona o tráfego externo para o seu cluster. Pode ser um balanceador de carga de aplicações externo global, um balanceador de carga de aplicações externo regional ou um gateway do balanceador de carga de aplicações interno regional.

    Para mais informações sobre a implementação de gateways, consulte o artigo Implementar gateways.

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

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

    1. GCPRoutingExtension para gateways regionais: use esta extensão para o balanceador de carga de aplicações externo regional e o balanceador de carga de aplicações interno regional para implementar uma lógica de encaminhamento personalizada na região.

    2. GCPTrafficExtension para gateways externos globais, externos regionais e internos: use esta extensão para o balanceador de carga de aplicações externo global, o balanceador de carga de aplicações externo regional e o balanceador de carga de aplicações interno regional para realizar a manipulação do tráfego, como a modificação do cabeçalho ou a inspeção do conteúdo, em vários tipos de balanceadores de carga.

Implemente um serviço de texto destacado de back-end

Um serviço de texto destacado implementa uma lógica personalizada para extensões de serviços de gateway no GKE. O gateway invoca estas aplicações de back-end, com base nas configurações de GCPTrafficExtension ou GCPRoutingExtension, para modificar ou encaminhar o tráfego.

Implementa um serviço de chamadas para adicionar lógica personalizada ao seu gateway. Este serviço separado processa personalizações, como a manipulação de cabeçalhos, as transformações de payloads ou o encaminhamento de tráfego.

Para implementar um serviço de back-end que possa funcionar como um texto destacado para o seu gateway, siga estes passos:

  1. (Opcional) Crie um segredo para o TLS: Este comando cria um segredo do Kubernetes do tipo TLS que contém o seu certificado TLS e chave privada.

    Para criar o segredo do TLS para o seu serviço de texto destacado, substitua o seguinte:

    • SECRET_NAME: o nome secreto do seu serviço de anúncios de lances
    • path-to-cert: os caminhos dos ficheiros para o seu certificado
    • path-to-key: os caminhos dos ficheiros para a sua chave
  2. Para verificar se o segredo foi adicionado, execute o seguinte comando:

    kubectl get secrets SECRET_NAME
    

    Substitua SECRET_NAME pelo nome secreto do seu serviço de anúncios externos.

    O resultado deve ser semelhante ao seguinte:

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

    Tem de definir o seguinte:

    • Implementação: para gerir os pods de aplicações que contêm a lógica personalizada para as suas extensões de serviços.
    • Serviço: para expor os pods de aplicações geridos pela implementação como um serviço de rede.
    1. Crie um manifesto de amostra extension-service-app.yaml que tenha Definições de implementaçã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. Valide a configuração:

    1. Confirme se a aplicação foi implementada:

      kubectl get pod --selector app=store
      

      Depois de a aplicação começar a ser executada, o resultado é semelhante ao seguinte:

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

      kubectl get service extension-service
      

      O resultado é semelhante ao seguinte, que mostra um serviço para cada implementação da loja:

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

Configure as extensões de serviços

Pode configurar um GCPRoutingExtension ou um GCPTrafficExtension para personalizar o fluxo de tráfego.

Configure o GCPRoutingExtension para gateways regionais

Pode reencaminhar o tráfego através de um GCPRoutingExtension. Para configurar um GCPRoutingExtension, atualize o HTTPRoute para especificar os pedidos para o anfitrião service-extensions.com.

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

    1. Guarde o seguinte manifesto de exemplo como o ficheiro 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 da sua gateway.

    2. Aplique o manifesto store-route.yaml:

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

    1. Guarde a configuração GCPRoutingExtension no ficheiro de exemplo 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 da sua gateway.

    2. Aplique o manifesto de exemplo ao seu cluster:

      kubectl apply -f gcp-routing-extension.yaml
      
  3. Valide a configuração do GCPRoutingExtension e a respetiva associação ao gateway.

    1. Verifique a implementação do GCPRoutingExtension:

      kubectl describe gcproutingextension my-gateway-extension
      

      O resultado é semelhante ao seguinte:

      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>
      

      O resultado apresenta os detalhes do GCPRoutingExtension, que tem o nome my-gateway-extension, no espaço de nomes predefinido. A saída mostra o campo Spec, que contém a definição de como a extensão deve comportar-se.

    2. Valide a associação do gateway:

      1. Confirme se o GCPRoutingExtension está associado ao gateway. Esta ação pode demorar alguns minutos:

        kubectl describe gateway GATEWAY_NAME
        

        O resultado é semelhante ao seguinte:

        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
        ...
        

        O resultado mostra as anotações que o GKE usa para armazenar os links entre o Gateway e osGoogle Cloud recursos subjacentes. A anotação networking.gke.io/lb-route-extensions confirma a associação do gateway ao GCPRoutingExtension.

      2. Verifique o estado da extensão confirmando que o GCPRoutingExtension tem o estado Reconciled com o motivo ReconciliationSucceeded. Este comando pode demorar alguns minutos.

        kubectl describe gcproutingextension my-gateway-extension
        

        O resultado é semelhante ao seguinte:

        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 motivo: ReconciliationSucceeded. Estas informações confirmam que a extensão foi aplicada com êxito.

  4. Envie tráfego para a sua aplicação.

    Depois de implementar o gateway, a rota e a aplicação no cluster, pode transmitir tráfego para a aplicação.

    1. Para aceder à sua aplicação, tem de encontrar o endereço IP do seu 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 da sua gateway.

      Este comando produz o endereço IP do gateway. Nos comandos de seguimento, substitua GATEWAY_IP_ADDRESS pelo endereço IP da saída.

    2. Teste a atualização do caminho acedendo à versão serviceextensions do serviço de loja em store.example.com/serviceextensions:

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

      O resultado é semelhante ao seguinte:

      {
      "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"
      }
      

Configure o GCPTrafficExtension

Pode usar um GCPTrafficExtension para usar capacidades avançadas de gestão de tráfego no seu ambiente Google Cloud . Pode configurar esta extensão em balanceadores de carga de aplicações externos globais, balanceadores de carga de aplicações externos regionais e balanceadores de carga de aplicações internos regionais. Pode usar GCPTrafficExtension para implementar uma lógica de pedido e resposta personalizada, encaminhamento sofisticado, transformações e políticas de segurança.

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

    1. Guarde o seguinte manifesto de exemplo como o ficheiro 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 seu 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. Guarde a configuração de GCPTrafficExtension no ficheiro de gcp-traffic-extension.yaml de exemplo:

      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 seu gateway, como internal-http, external-http ou global-external-http.

    2. Aplique o manifesto de exemplo ao seu cluster:

      kubectl apply -f gcp-traffic-extension.yaml
      
  3. Valide a configuração do GCPTrafficExtension e a respetiva associação ao gateway.

    1. Verifique a implementação do GCPTrafficExtension:

      kubectl describe gcptrafficextension my-traffic-extension
      

      O resultado é semelhante ao seguinte:

      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 apresenta os detalhes do GCPTrafficExtension denominado my-traffic-extension no espaço de nomes predefinido. Mostra o campo Spec que contém a definição de como a extensão deve funcionar.

    2. Valide a associação do gateway:

      Confirme se o GCPTrafficExtension está associado ao gateway. Este comando pode demorar alguns minutos a ser concluído:

      kubectl describe gateway GATEWAY_NAME
      

      O resultado é semelhante ao seguinte:

      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
      ...
      

      O resultado mostra as anotações que o GKE usa para armazenar os links entre o Gateway e os Google Cloud recursos subjacentes. A anotação networking.gke.io/lb-traffic-extensions confirma a associação.

    3. Verifique o estado da extensão:

      Confirme se o GCPTrafficExtension tem o estado Reconciled com o motivo ReconciliationSucceeded. Este comando pode demorar alguns minutos a ser concluído.

      kubectl describe gcptrafficextension my-traffic-extension
      

      O resultado é semelhante ao seguinte:

      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. Estas informações confirmam que a extensão foi aplicada com êxito.

  4. Envie tráfego para a sua aplicação.

    Depois de implementar o gateway, a rota e a aplicação no cluster, pode transmitir tráfego para a aplicação.

    1. Para aceder à sua aplicação, tem de encontrar o endereço IP do seu 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 da sua gateway.

      Este comando produz o endereço IP do gateway. Nos comandos de seguimento, substitua GATEWAY_IP_ADDRESS pelo endereço IP da saída.

    2. Teste a atualização do caminho acedendo à versão serviceextensions do serviço de loja em store.example.com/serviceextensions:

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

      O resultado é semelhante ao seguinte:

      {
      *   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
      }
      

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

Esta secção oferece sugestões de resolução de problemas para configurar extensões de tráfego em gateways.

Gateway não encontrado

O erro seguinte indica que o recurso 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 este problema, certifique-se de que o recurso Gateway especificado no campo targetRefs do recurso GCPTrafficExtension ou GCPRoutingExtension existe no espaço de nomes especificado.

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

O erro seguinte indica que o serviço ou a porta de serviço especificados 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 este problema, certifique-se de que o serviço e a porta de serviço especificados no campo backendRef do recurso GCPTrafficExtension ou GCPRoutingExtension existem no espaço de nomes especificado.

Nenhum ponto final de rede no NEG

O erro seguinte indica que não existem pontos finais 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 este problema, certifique-se de que o serviço especificado no campo backendRef do recurso GCPTrafficExtension ou GCPRoutingExtension tem pontos finais de rede.

Não recebe uma resposta ou recebe uma resposta com um erro ao enviar o pedido

Se não receber uma resposta ou receber uma resposta com um erro quando envia um pedido, pode indicar que o serviço de texto destacado não está a funcionar corretamente.

Para resolver este problema, verifique se existem erros nos registos do serviço de lances.

Código de erro 404 no payload JSON

O erro seguinte indica que o serviço de texto de chamada não foi encontrado ou não está a responder ao pedido:

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

Para resolver este problema, certifique-se de que o serviço de chamadas está em execução, que está a ouvir na porta correta e que o serviço está configurado corretamente no recurso GCPTrafficExtension ou GCPRoutingExtension.

Código de erro 500 no payload JSON

O erro seguinte indica que o serviço de lances está a ter um erro interno do servidor:

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

Para resolver este problema, verifique os registos do serviço de lances para identificar a causa do erro interno do servidor.

O que se segue?