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 extensões de serviço para adicionar lógica personalizada ao Cloud Load Balancing.

Esta página é destinada a administradores de identidade e conta do GKE e desenvolvedores que precisam configurar uma lógica personalizada de gerenciamento de tráfego 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. É 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.
  • GCPTrafficExtension: essa extensão insere uma lógica personalizada no Cloud Load Balancing para modificar o tráfego. Essa lógica é aplicada ao tráfego depois que o serviço é selecionado. O balanceador de carga pode adicionar ou mudar os cabeçalhos e payloads de solicitações e respostas HTTP. GCPTrafficExtension não afeta a seleção de serviços nem as políticas de segurança de serviços.

Uma extensão é anexada a um gateway e faz referência a um Service, um GCPWasmPlugin ou um googleAPIServiceName.

  • Referenciar um serviço: nesse modelo, você implanta sua lógica personalizada como um aplicativo de back-end separado, exposto como um serviço do Kubernetes. O balanceador de carga faz uma chamada para esse serviço para processar o tráfego. Essa abordagem é versátil e permite implementar uma lógica de roteamento personalizada ou realizar manipulação de tráfego, como modificação de cabeçalho ou inspeção de payload. Você faz referência a um serviço com o GCPRoutingExtension ou o GCPTrafficExtension.

  • Referencie um recurso GCPWasmPlugin: para casos de uso de alto desempenho, você pode injetar lógica personalizada escrita pelo usuário diretamente no caminho de dados do balanceador de cargaGoogle Cloud usando um módulo WebAssembly (Wasm). Você define um recurso GCPWasmPlugin que aponta para a imagem do módulo Wasm no Artifact Registry. Esse método é usado apenas com um GCPTrafficExtension e um balanceador de carga de aplicativo externo global.

  • Referenciar um serviço de API do Google: também é possível referenciar um serviço de API do Google diretamente usando o campo googleAPIServiceName em um GCPTrafficExtension.

No diagrama a seguir, o recurso GCPRoutingExtension está anexado a um gateway e faz referência a vários serviços. A extensão controla o roteamento de tráfego para os Serviços.

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 o GCPRoutingExtension funciona com gateways

No diagrama a seguir, o recurso GCPTrafficExtension está anexado a um gateway e faz referência a um serviço, um GoogleAPIServiceName ou um GCPWasmPlugin. A extensão muda os cabeçalhos e payloads de solicitações e respostas.

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

Antes de começar

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

  • Ativar 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 inicialize a gcloud CLI. 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.

Requisitos do GKE Gateway Controller

  • Seu cluster precisa usar o GKE versão 1.33 ou posterior.
  • Para usar o GCPWasmPlugin, seu cluster precisa usar o GKE versão 1.33.3 ou posterior.
  • O cluster precisa ter a API Gateway ativada.
  • Você precisa ter um recurso de gateway configurado. Esse recurso pode ser um gateway de balanceador de carga de aplicativo externo global, regional externo ou regional interno. Se você usar um recurso GCPWasmPlugin, implante apenas um gateway de balanceador de carga de aplicativo externo global.
  • Você precisa ter um recurso HTTPRoute configurado.

Restrições e limitações

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

Categoria Restrições e limitações
Balanceador de carga O GCPRoutingExtension é compatível com os seguintes balanceadores de carga:
  • Balanceador de carga de aplicativo externo regional (classe Gateway gke-l7-regional-external-managed)
  • Balanceador de carga de aplicativo interno regional(classe de gateway gke-l7-rilb)
O GCPTrafficExtension é compatível com os seguintes balanceadores de carga:
  • Balanceador de carga de aplicativo externo regional (classe Gateway gke-l7-regional-external-managed)
  • Balanceador de carga de aplicativo interno regional (classe de gateway gke-l7-rilb)
  • Balanceador de carga de aplicativo externo global (classe de gateway gke-l7-global-external-managed)
Cadeia e especificação de extensão
  • Para um GCPTrafficExtension, cada ExtensionChain pode ter no máximo três Extensions.
  • Para um GCPRoutingExtension, cada ExtensionChain é limitado a um Extension.
  • Um GCPTrafficExtensionSpec e um GCPRoutingExtensionSpec podem ter no máximo cinco ExtensionChains cada um.
Tempo e correspondência
  • O tempo limite para cada mensagem individual no stream em uma extensão precisa ser de 10 a 10.000 milissegundos. Esse limite de um segundo se aplica às 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 ao 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çalho 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 poderá conter apenas eventos RequestHeaders.
  • Para um GCPRoutingExtension, se requestBodySendMode estiver definido como FullDuplexStreamed, a lista supportedEvents poderá conter apenas eventos RequestHeaders, RequestBody e RequestTrailers.
GCPTrafficExtension
  • O campo responseBodySendMode é compatível apenas com GCPTrafficExtension.
  • O campo googleAPIServiceName é compatível apenas com GCPTrafficExtension.
  • O campo GCPWasmPlugin é compatível apenas com GCPTrafficExtension.
GCPWasmPlugin
  • As extensões com GCPWasmPlugin não são compatíveis com os seguintes campos:
    • authority
    • timeout
    • metadata
    • requestBodySendMode
    • responseBodySendMode
  • As extensões com suporte a GCPWasmPlugin só aceitam eventos RequestHeaders, RequestBody, ResponseHeaders e ResponseBody.
googleAPIServiceName e backendRef Ao referenciar um serviço que usa o backendRef em uma extensão, você precisa atender às seguintes condições:
  • Precisa 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 de backendRef ou googleAPIServiceName para um Extension.
  • É necessário definir authority se backendRef estiver definido e kind for Service.
  • Não defina authority se googleAPIServiceName estiver definido.
  • Configure requestBodySendMode para extensões usando apenas backendRef e Service.
  • Configure responseBodySendMode para extensões usando apenas backendRef e Service.

Referência a um serviço

Nas extensões de serviço, é possível se referir a um serviço que hospeda a lógica personalizada que você quer que o balanceador de carga execute. Os gateways não têm extensões de serviço por padrão.

Para configurar as extensões de serviço do GKE, siga estas etapas:

  1. Implante um serviço de callback 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.

  2. Configurar extensões de serviço: use a extensão adequada com base no tipo de balanceador de carga.

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

    2. GCPTrafficExtension para gateways externos globais, externos regionais e internos: use essa extensão para balanceadores de carga de aplicativo externos globais, externos regionais e internos regionais para realizar 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 callout de back-end

Um serviço de callout implementa lógica personalizada para extensões de serviço do 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 ações personalizadas, como manipulação de cabeçalho, transformações de payload ou roteamento de tráfego.

Para implantar um serviço que possa funcionar como uma callout para seu gateway, siga estas etapas:

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

    Para criar o secret TLS do seu serviço de callout, substitua o seguinte:

    • SECRET_NAME: o nome secreto do serviço de callout
    • path-to-cert: os caminhos dos arquivos do seu certificado
    • path-to-key: os caminhos de arquivo para sua chave
  2. Para verificar se a chave secreta foi adicionada, execute o seguinte comando:

    kubectl get secrets SECRET_NAME
    

    Substitua SECRET_NAME pelo nome do secret do seu serviço de callout.

    A saída será semelhante a esta:

    NAME            TYPE                DATA   AGE
    SECRET_NAME     kubernetes.io/tls   2      12s
    
  3. Defina 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 manifesto de amostra 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 extensões de serviço

É possível configurar um GCPRoutingExtension ou um GCPTrafficExtension para personalizar seu 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 sua HTTPRoute para incluir nomes de host ou caminhos que acionarão a extensão de roteamento.

    1. Salve o seguinte manifesto de amostra 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 seu 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 seu gateway.

    2. Aplique o manifesto de amostra 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, 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 deve 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 recursosGoogle Cloud subjacentes. A anotação networking.gke.io/lb-route-extensions confirma a vinculação do gateway ao GCPRoutingExtension.

      2. Confira o status da extensão confirmando se o GCPRoutingExtension tem um status Programmed com o motivo ProgrammingSucceeded. 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:                ProgrammingSucceeded
              Status:                True
              Type:                  Programmed
            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 Programmed com Status: True e Reason: ProgrammingSucceeded. Essas informações confirmam que a extensão foi aplicada corretamente.

  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, encontre 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 do seu gateway.

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

    2. Teste a atualização de caminho acessando 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, balanceadores de carga de aplicativo externos regionais e balanceadores de carga de aplicativo internos regionais. Use GCPTrafficExtension para implementar lógica personalizada de solicitação e resposta HTTP, roteamento sofisticado, transformações e políticas de segurança.

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

    1. Salve o seguinte manifesto de amostra 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 amostra 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 um status Programmed com o motivo ProgrammingSucceeded. Isso pode demorar alguns minutos.

      Para verificar o status da extensão de GCPTrafficExtension, execute o comando a seguir:

      kubectl describe gcptrafficextension my-traffic-extension
      

      A saída do recurso GCPTrafficExtension é semelhante a esta:

      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:                ProgrammingSucceeded
            Status:                True
            Type:                  Programmed
          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 Programmed com Status: True e Reason: ProgrammingSucceeded. Essas informações confirmam que a extensão foi aplicada com sucesso.

  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, encontre 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 do gateway.

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

    2. Teste a atualização de caminho acessando 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
      }
      

Referenciar um recurso GCPWasmPlugin

É possível injetar lógica personalizada diretamente no caminho de dados do balanceador de carga usando um GCPWasmPlugin com um GCPTrafficExtension. Esse método permite implantar recursos personalizados de gerenciamento de tráfego empacotados como um módulo Wasm.

Para configurar as extensões de serviço do GKE, siga estas etapas:

  1. Implante um GCPWasmPlugin: crie e implante uma definição de recurso personalizado (CRD) GCPWasmPlugin que contenha o código personalizado do módulo Wasm. É possível usar GCPWasmPlugin apenas com GCPTrafficExtension para a GatewayClass gke-l7-global-external-managed.

  2. Configure as extensões de serviço: use o GCPTrafficExtension para o balanceador de carga de aplicativo externo global.

Implantar um GCPWasmPlugin

O GCPWasmPlugin permite injetar lógica personalizada escrita pelo usuário diretamente no caminho de dados do balanceador de carga Google Cloud . O recurso GCPWasmPlugin aponta para a imagem do módulo Wasm no Artifact Registry, que é executada pelo balanceador de carga.

Antes de continuar com as etapas a seguir, verifique se você fez upload do seu módulo Wasm para um repositório do Artifact Registry. Para mais informações, consulte Preparar o código do plug-in.

Para implantar um recurso GCPWasmPlugin, siga estas etapas:

  1. Salve o seguinte manifesto como wasm-plugin.yaml:

    kind: GCPWasmPlugin
    apiVersion: networking.gke.io/v1
    metadata:
      name: gcp-wasm-plugin
    spec:
      versions:
      - name: wasm-plugin-version
        description: "Test wasm plugin version"
        image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main"
        weight: 1000000
      logConfig:
        enabled: true
        # Configures the sampling rate of activity logs.
        # The value of the field must be in range [0, 1e6].
        sampleRate: 1000000
        # Specifies the lowest level of logs that are exported to Cloud Logging.
        minLogLevel: INFO
    

    Observe o seguinte:

    • spec.versions.name: o nome da versão precisa ser exclusivo no recurso GCPWasmPlugin. É possível listar até 10 versões, mas apenas uma delas pode ter uma ponderação diferente de zero.
    • spec.versions.image: faz referência à imagem que contém o código do plug-in armazenado no Artifact Registry.
    • spec.versions.weight: especifica o peso da versão do plug-in. O peso precisa ser um número entre 0 e 1.000.000, incluindo esses dois valores.
    • spec.logConfig: especifica se o Cloud Logging será ativado para este plug-in. Se o valor não for especificado, o Cloud Logging será desativado por padrão.
    • spec.logConfig.sampleRate: configura a taxa de amostragem dos registros de atividade. A taxa precisa ser um número entre 0 e 1.000.000, inclusive. Se não for especificado quando o Cloud Logging estiver ativado, o valor padrão será 1,000,000 (100% das solicitações serão registradas).
    • spec.logConfig.minLogLevel: especifica o nível mais baixo de registros que são exportados para o Cloud Logging. Se o valor não for especificado quando o Cloud Logging estiver ativado, o campo será definido como INFO por padrão.
  2. Aplique o manifesto wasm-plugin.yaml:

    kubectl apply -f wasm-plugin.yaml
    
  3. Verifique se o plug-in foi implantado:

    kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-plugin
    

    O resultado será assim:

    Name:         gcp-wasm-plugin
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         GCPWasmPlugin
    Metadata:
      Creation Timestamp:  2025-08-08T19:54:18Z
      Generation:          1
      Resource Version:    44578
      UID:                 549a12c7-91d1-43ad-a406-d6157a799b79
    Spec:
      Log Config:
        Enabled: true
        Min Log Level: INFO
        Sample Rate: 1000000
      Versions:
        Description:  Test wasm plugin version
        Image:        us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main
        Name:         wasm-plugin-version
        Weight:       1000000
      Events:     <none>
    

Configurar extensões de serviço

Para adicionar lógica personalizada ao balanceador de carga de aplicativo externo global, configure um GCPTrafficExtension para usar um GCPWasmPlugin. É possível usar um GCPTrafficExtension para aproveitar 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.

Para configurar um GCPTrafficExtension para usar um GCPWasmPlugin, siga estas etapas:

  1. Defina o GCPTrafficExtension.

    1. Salve a configuração GCPTrafficExtension como gcp-traffic-extension-with-plugin.yaml:

      kind: GCPTrafficExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: gcp-traffic-extension-with-plugin
        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
            supportedEvents:
            - RequestHeaders
            - ResponseHeaders
            backendRef:
              group: "networking.gke.io"
              kind: GCPWasmPlugin
              name: gcp-wasm-plugin
      

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

    2. Aplique o manifesto de amostra ao cluster:

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

    1. Verifique a implantação GCPTrafficExtension:

      kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-plugin
      

      O resultado será assim:

      Name:         gcp-traffic-extension-with-plugin
      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:
            Backend Ref:
              Group: networking.gke.io
              Kind: GCPWasmPlugin
              Name: gcp-wasm-plugin
            Name:       ext1
            Supported Events:
              RequestHeaders
              ResponseHeaders
          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 gcp-traffic-extension-with-plugin 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/922988411345/global/addresses/test-k18j-default-external-http-2jfqxrkgd0fm
                    networking.gke.io/backend-services:
                      /projects/922988411345/global/backendServices/test-k18j-default-gw-serve404-80-8zjp3d8cqfsu, /projects/922988411345/global/backendServices...
                      networking.gke.io/certmap: store-example-com-map
                      networking.gke.io/firewalls: /projects/922988411345/global/firewalls/test-k18j-l7-default-global
                      networking.gke.io/forwarding-rules: /projects/922988411345/global/forwardingRules/test-k18j-default-external-http-wt1tl0cwi6zr
                      networking.gke.io/health-checks:
                        /projects/922988411345/global/healthChecks/test-k18j-default-gw-serve404-80-8zjp3d8cqfsu, /projects/922988411345/global/healthChecks/test-...
                      networking.gke.io/last-reconcile-time: 2025-08-08T20:27:35Z
                      networking.gke.io/lb-route-extensions:
                      networking.gke.io/lb-traffic-extensions:
                        projects/922988411345/locations/global/lbTrafficExtensions/test-k18j-default-external-http-0tdum40yts35
                      networking.gke.io/ssl-certificates:
                      networking.gke.io/target-http-proxies:
                      networking.gke.io/target-https-proxies: /projects/922988411345/global/targetHttpsProxies/test-k18j-default-external-http-jy9mc97xb5yh
                      networking.gke.io/url-maps: /projects/922988411345/global/urlMaps/test-k18j-default-external-http-jy9mc97xb5yh
                      networking.gke.io/wasm-plugin-versions:
                        projects/922988411345/locations/global/wasmPlugins/test-k18j-default-gcp-wasm-plugin-itle20jj9nyk/versions/test-k18j-wasm-plugin-version-i...
                      networking.gke.io/wasm-plugins: projects/922988411345/locations/global/wasmPlugins/test-k18j-default-gcp-wasm-plugin-itle20jj9nyk
      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
      Spec:
        Gateway Class Name:  gke-l7-global-external-managed
        Listeners:
          Allowed Routes:
            Namespaces:
              From:  Same
          Name:      https
          Port:      443
          Protocol:  HTTPS
      ...
      

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

    3. Verifique o status da extensão:

      Confirme se o GCPTrafficExtension tem um status Programmed com o motivo ProgrammingSucceeded. Isso pode demorar alguns minutos.

      kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-plugin
      

      O resultado será assim:

      Name:         gcp-traffic-extension-with-plugin
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-08-08T20:08:09Z
        Generation:          1
        Resource Version:    56528
        UID:                 1389f790-9663-45ca-ac4e-a2c082f43359
      Spec:
        Extension Chains:
          Extensions:
            Backend Ref:
              Group:  networking.gke.io
              Kind:   GCPWasmPlugin
              Name:   gcp-wasm-plugin
            Name:     ext1
            Supported Events:
              RequestHeaders
              ResponseHeaders
          Match Condition:
            Cel Expressions:
              Cel Matcher:  request.path.contains("serviceextensions")
          Name:             chain1
        Target Refs:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   external-http
      Status:
        Ancestors:
          Ancestor Ref:
            Group:      gateway.networking.k8s.io
            Kind:       Gateway
            Name:       external-http
            Namespace:  default
          Conditions:
            Last Transition Time:  2025-08-08T20:16:13Z
            Message:
            Observed Generation:   1
            Reason:                Accepted
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-08-08T20:16:13Z
            Message:
            Observed Generation:   1
            Reason:                ResolvedRefs
            Status:                True
            Type:                  ResolvedRefs
            Last Transition Time:  2025-08-08T20:16:13Z
            Message:
            Observed Generation:   1
            Reason:                ProgrammingSucceeded
            Status:                True
            Type:                  Programmed
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                  From                   Message
        ----    ------  ----                 ----                   -------
        Normal  ADD     19m                  sc-gateway-controller  default/gcp-traffic-extension-with-plugin
        Normal  SYNC    3m25s (x4 over 11m)  sc-gateway-controller  Attachment of GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
        Normal  SYNC  3m25s (x4 over 11m)  sc-gateway-controller  All the object references were able to be resolved for GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" bound to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil}
        Normal  SYNC  3m25s (x4 over 11m)  sc-gateway-controller  Programming of GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
      
    4. Verifique o status do plug-in.

      Confirme se o recurso GCPWasmPlugin tem um status Programmed com o motivo ProgrammingSucceeded. Isso pode demorar alguns minutos.

      kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-plugin
      

      O resultado será assim:

      Name:         gcp-wasm-plugin
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPWasmPlugin
      Metadata:
        Creation Timestamp:  2025-08-08T19:54:18Z
        Generation:          1
        Resource Version:    44578
        UID:                 549a12c7-91d1-43ad-a406-d6157a799b79
      Spec:
        Log Config:
          Enabled: true
          Min Log Level: INFO
          Sample Rate: 1000000
        Versions:
          Description:  Test wasm plugin version
          Image:        us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main
          Name:         wasm-plugin-version
          Weight:       1000000
      Status:
        Ancestors:
          Ancestor Ref:
            Group:      gateway.networking.k8s.io
            Kind:       Gateway
            Name:       external-http
            Namespace:  default
          Conditions:
            Last Transition Time:  2025-08-08T19:59:06Z
            Message:
            Observed Generation:   1
            Reason:                Accepted
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-08-08T19:59:06Z
            Message:
            Observed Generation:   1
            Reason:                ResolvedRefs
            Status:                True
            Type:                  ResolvedRefs
            Last Transition Time:  2025-08-08T19:59:06Z
            Message:
            Observed Generation:   1
            Reason:                ProgrammingSucceeded
            Status:                True
            Type:                  Programmed
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                 From                   Message
        ----    ------  ----                ----                   -------
        Normal  ADD     31m                 sc-gateway-controller  default/gcp-wasm-plugin
        Normal  SYNC    2m1s (x7 over 26m)  sc-gateway-controller  Attachment of WasmPlugin "default/gcp-wasm-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
        Normal  SYNC  2m1s (x7 over 26m)  sc-gateway-controller  All the object references were able to be resolved for WasmPlugin "default/gcp-wasm-plugin" bound to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil}
        Normal  SYNC  2m1s (x7 over 26m)  sc-gateway-controller  Programming of WasmPlugin "default/gcp-wasm-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
      
  3. 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, encontre 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 do gateway.

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

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

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

      A saída retorna Hello World.

Gerenciar o recurso GCPWasmPlugin

É possível atualizar o CRD GCPWasmPlugin e monitorar o plug-in.

Atualize o GCPWasmPlugin

Para atualizar um recurso GCPWasmPlugin, siga estas etapas:

  1. Faça a mudança no manifesto GCPWasmPlugin e siga as etapas descritas em Implantar um GCPWasmPlugin.

    Por exemplo, para ter duas versões do plug-in, em que uma versão está veiculando tráfego e a outra não, atualize o arquivo wasm-plugin.yaml para o seguinte:

    kind: GCPWasmPlugin
    apiVersion: networking.gke.io/v1
    metadata:
      name: gcp-wasm-plugin
    spec:
      versions:
      - name: wasm-plugin-version-v1
        description: "Serving Wasm Plugin version"
        image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main"
        weight: 1000000
      - name: wasm-plugin-version-v2
        description: "Non serving Wasm Plugin version"
        image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main"
        weight: 0
      logConfig:
        enabled: true
        sampleRate: 1000000
        minLogLevel: INFO
    

    Neste exemplo, o seguinte se aplica:

    • wasm-plugin-version-v1 tem um weight de 1000000, o que significa que ele atende a todo o tráfego.
    • wasm-plugin-version-v2 tem um weight de 0, o que significa que não veicula tráfego.
  2. Para garantir que o gateway seja atualizado, execute o seguinte comando: Esse comando pode levar alguns minutos para ser concluído:

    kubectl describe gateway GATEWAY_NAME
    

    Substitua GATEWAY_NAME pelo nome do seu gateway.

Monitorar GCPWasmPlugin

Para ver as métricas do GCPWasmPlugin no console Google Cloud , consulte Monitoramento na perspectiva de um plug-in.

Quando você chegar à etapa do guia em que precisa selecionar um valor na lista Filtro de versão do plug-in, procure o formato prefix−WASM_PLUGIN_VERSION_NAME_FROM_FILE−suffix, em que WASM_PLUGIN_VERSION_NAME_FROM_FILE é o nome da versão específica definida no arquivo de configuração GCPWasmPlugin.

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

Nesta seção, você encontra 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 "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 encontrado

O erro a seguir indica que o serviço ou a porta de 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 especificados no campo backendRef do recurso GCPTrafficExtension ou GCPRoutingExtension existem no namespace especificado.

Nenhum endpoint 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 se receber uma resposta com um erro ao enviar uma solicitação, isso pode indicar que o serviço de callout não está funcionando corretamente.

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

Código de erro 404 no payload JSON

O erro a seguir indica que o serviço de callout 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 callout está em execução, se ele está escutando na porta correta e se o serviço 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 callout 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 callout para identificar a causa do erro interno do servidor.

GCPWasmPlugin não existe

O erro a seguir indica que o recurso GCPWasmPlugin não existe no seu projeto:

Status:
  Ancestors:
    Ancestor Ref:
      Group:      gateway.networking.k8s.io
      Kind:       Gateway
      Name:       external-http
      Namespace:  default
    Conditions:
      Last Transition Time:  2025-03-06T16:27:57Z
      Message:
      Reason:                Accepted
      Status:                True
      Type:                  Accepted
      Last Transition Time:  2025-03-06T16:27:57Z
      Message:               error cause: invalid-wasm-plugin: GCPWasmPlugin default/my-wasm-plugin in GCPTrafficExtension default/my-gateway-plugin-extension does not exist
      Reason:                GCPWasmPluginNotFound
      Status:                False
      Type:                  ResolvedRefs
    Controller Name:         networking.gke.io/gateway

Para resolver esse problema, crie um GCPWasmPlugin correspondente no projeto Google Cloud ou aponte uma extensão para um GCPWasmPlugin existente.

A seguir