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:
- Conceitos básicos de rede do GKE
- API GKE Gateway
- Controladores do GKE Gateway
- GKE GatewayClasses
- Visão geral das extensões de serviço
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.GCPTrafficExtensionnã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
GCPRoutingExtensionou oGCPTrafficExtension.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 recursoGCPWasmPluginque aponta para a imagem do módulo Wasm no Artifact Registry. Esse método é usado apenas com umGCPTrafficExtensione 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
googleAPIServiceNameem umGCPTrafficExtension.
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.
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.
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.
Ative a API Compute Engine, Network Services e Model Armor, se necessário.
Acesse Ativar acesso a APIs e siga as instruções.
Para informações detalhadas sobre os preços das extensões de serviço do Google Cloud , consulte Preços.
Revise os papéis e as permissões necessárias em Controle de acesso das extensões de serviço.
Conheça as cotas e os limites em Cotas de extensões de serviço.
Se você pretende usar correspondentes da Common Expression Language (CEL), consulte os atributos e operadores compatíveis na referência da linguagem de correspondência da CEL.
Revise as restrições e limitações das extensões de serviço.
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:
GCPTrafficExtension é compatível com os seguintes balanceadores de carga:
|
| Cadeia e especificação de extensão |
|
| Tempo e correspondência |
|
| Cabeçalho e metadados |
|
| Evento |
|
GCPTrafficExtension |
|
GCPWasmPlugin |
|
googleAPIServiceName e backendRef |
Ao referenciar um serviço que usa o backendRef em uma extensão, você precisa atender às seguintes condições:
|
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:
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.
Configurar extensões de serviço: use a extensão adequada com base no tipo de balanceador de carga.
GCPRoutingExtensionpara 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.GCPTrafficExtensionpara 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:
(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 calloutpath-to-cert: os caminhos dos arquivos do seu certificadopath-to-key: os caminhos de arquivo para sua chave
Para verificar se a chave secreta foi adicionada, execute o seguinte comando:
kubectl get secrets SECRET_NAMESubstitua
SECRET_NAMEpelo 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 12sDefina 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.
Crie um manifesto de amostra
extension-service-app.yamlcom 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: storeAplique o manifesto
extension-service-app.yaml:kubectl apply -f extension-service-app.yaml
Verifique a configuração:
Verifique se o aplicativo foi implantado:
kubectl get pod --selector app=storeDepois 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 7sVerifique se o serviço foi implantado:
kubectl get service extension-serviceA 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.
Atualize o HTTPRoute. Modifique sua HTTPRoute para incluir nomes de host ou caminhos que acionarão a extensão de roteamento.
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: 8080Substitua
GATEWAY_NAMEpelo nome do seu gateway.Aplique o manifesto
store-route.yaml:kubectl apply -f store-route.yaml
Defina o
GCPRoutingExtension.Salve a configuração
GCPRoutingExtensionno arquivo de amostragcp-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: 443Substitua
GATEWAY_NAMEpelo nome do seu gateway.Aplique o manifesto de amostra ao cluster:
kubectl apply -f gcp-routing-extension.yaml
Verifique a configuração do
GCPRoutingExtensione a vinculação dele ao gateway.Verifique a implantação
GCPRoutingExtension:kubectl describe gcproutingextension my-gateway-extensionO 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, chamadomy-gateway-extension, no namespace padrão. A saída mostra o campoSpec, que contém a definição de como a extensão deve se comportar.Verifique a vinculação do gateway:
Confirme se o
GCPRoutingExtensionestá vinculado ao gateway. Isso pode levar alguns minutos:kubectl describe gateway GATEWAY_NAMEO 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-extensionsconfirma a vinculação do gateway aoGCPRoutingExtension.Confira o status da extensão confirmando se o
GCPRoutingExtensiontem um statusProgrammedcom o motivoProgrammingSucceeded. Esse comando pode levar alguns minutos.kubectl describe gcproutingextension my-gateway-extensionO 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 successO campo
Status.Conditionsmostra uma condiçãoProgrammedcomStatus: TrueeReason: ProgrammingSucceeded. Essas informações confirmam que a extensão foi aplicada corretamente.
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.
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_NAMEpelo nome do seu gateway.Esse comando gera o endereço IP do gateway. Nos comandos a seguir, substitua
GATEWAY_IP_ADDRESSpelo endereço IP da saída.Teste a atualização de caminho acessando a versão
serviceextensionsdo serviço da loja emstore.example.com/serviceextensions:curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vO 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.
Atualize o HTTPRoute. Modifique sua HTTPRoute para incluir nomes de host ou caminhos que acionarão a extensão de tráfego.
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: 8080Substitua
GATEWAY_NAMEpelo nome do gateway, comointernal-http,external-httpouglobal-external-http.Aplique o manifesto
store-route.yamlao cluster:kubectl apply -f store-route.yaml
Defina o
GCPTrafficExtension.Salve a configuração
GCPTrafficExtensionno arquivo de amostragcp-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: 443Substitua
GATEWAY_NAMEpelo nome do gateway, comointernal-http,external-httpouglobal-external-http.Aplique o manifesto de amostra ao cluster:
kubectl apply -f gcp-traffic-extension.yaml
Verifique a configuração do
GCPTrafficExtensione a vinculação dele ao gateway.Verifique a implantação
GCPTrafficExtension:kubectl describe gcptrafficextension my-traffic-extensionO 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
GCPTrafficExtensionchamadomy-traffic-extensionno namespace padrão. Ele mostra o campoSpec, que contém a definição de como a extensão deve se comportar.Verifique a vinculação do gateway:
Confirme se o
GCPTrafficExtensionestá vinculado ao gateway. Esse comando pode levar alguns minutos para ser concluído:kubectl describe gateway GATEWAY_NAMEO 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-extensionsconfirma a vinculação.Verifique o status da extensão:
Confirme se o
GCPTrafficExtensiontem um statusProgrammedcom o motivoProgrammingSucceeded. Isso pode demorar alguns minutos.Para verificar o status da extensão de
GCPTrafficExtension, execute o comando a seguir:kubectl describe gcptrafficextension my-traffic-extensionA 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 successO campo
Status.Conditionsmostra uma condiçãoProgrammedcomStatus: TrueeReason: ProgrammingSucceeded. Essas informações confirmam que a extensão foi aplicada com sucesso.
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.
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_NAMEpelo nome do gateway.Esse comando gera o endereço IP do gateway. Nos comandos a seguir, substitua
GATEWAY_IP_ADDRESSpelo endereço IP da saída.Teste a atualização de caminho acessando a versão
serviceextensionsdo serviço da loja emstore.example.com/serviceextensions:curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vO 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:
Implante um
GCPWasmPlugin: crie e implante uma definição de recurso personalizado (CRD)GCPWasmPluginque contenha o código personalizado do módulo Wasm. É possível usarGCPWasmPluginapenas comGCPTrafficExtensionpara a GatewayClassgke-l7-global-external-managed.Configure as extensões de serviço: use o
GCPTrafficExtensionpara 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:
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: INFOObserve o seguinte:
spec.versions.name: o nome da versão precisa ser exclusivo no recursoGCPWasmPlugin. É 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 comoINFOpor padrão.
Aplique o manifesto
wasm-plugin.yaml:kubectl apply -f wasm-plugin.yamlVerifique se o plug-in foi implantado:
kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-pluginO 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:
Defina o
GCPTrafficExtension.Salve a configuração
GCPTrafficExtensioncomogcp-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-pluginSubstitua
GATEWAY_NAMEpelo nome do seu gateway, comoglobal-external-http.Aplique o manifesto de amostra ao cluster:
kubectl apply -f gcp-traffic-extension-with-plugin.yaml
Verifique a configuração do
GCPTrafficExtensione a vinculação dele ao gateway.Verifique a implantação
GCPTrafficExtension:kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-pluginO 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
GCPTrafficExtensionchamadogcp-traffic-extension-with-pluginno namespace padrão. Ele mostra o campoSpec, que contém a definição de como a extensão deve se comportar.Verifique a vinculação do gateway:
Confirme se o
GCPTrafficExtensionestá vinculado ao gateway. Esse comando pode levar alguns minutos para ser concluído:kubectl describe gateway GATEWAY_NAMEO 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-versionsenetworking.gke.io/wasm-pluginsconfirmam a vinculação.Verifique o status da extensão:
Confirme se o
GCPTrafficExtensiontem um statusProgrammedcom o motivoProgrammingSucceeded. Isso pode demorar alguns minutos.kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-pluginO 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 successVerifique o status do plug-in.
Confirme se o recurso
GCPWasmPlugintem um statusProgrammedcom o motivoProgrammingSucceeded. Isso pode demorar alguns minutos.kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-pluginO 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
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.
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_NAMEpelo nome do gateway.Esse comando gera o endereço IP do gateway. Nos comandos a seguir, substitua
GATEWAY_IP_ADDRESSpelo endereço IP da saída.Teste a atualização de caminho acessando a versão
serviceextensionsdo serviço da loja emstore.example.com/serviceextensions:curl https://store.example.com/serviceextensions --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -vA 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:
Faça a mudança no manifesto
GCPWasmPlugine siga as etapas descritas em Implantar umGCPWasmPlugin.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.yamlpara 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: INFONeste exemplo, o seguinte se aplica:
wasm-plugin-version-v1tem umweightde1000000, o que significa que ele atende a todo o tráfego.wasm-plugin-version-v2tem umweightde0, o que significa que não veicula tráfego.
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_NAMESubstitua
GATEWAY_NAMEpelo 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
- Saiba mais sobre o gateway de inferência do GKE.
- Saiba como disponibilizar um LLM com o gateway de inferência do GKE.
- Saiba como ver métricas de observabilidade.