En esta página, se describe cómo Google Kubernetes Engine (GKE) usa Service Extensions para agregar lógica personalizada a Cloud Load Balancing.
Esta página está dirigida a los administradores de cuentas y de identidades de GKE, y a los desarrolladores que necesitan configurar lógica personalizada de administración del tráfico con Service Extensions.
Antes de leer esta página, asegúrate de estar familiarizado con los siguientes temas:
- Conceptos básicos de redes de GKE
- API de GKE Gateway
- Controladores de GKE Gateway
- GatewayClasses de GKE
- Descripción general de las Extensiones del servicio
Descripción general
GKE usa Service Extensions para agregar lógica personalizada a Cloud Load Balancing. Puedes usar Service Extensions para tareas como la división avanzada del tráfico, la autenticación personalizada o el registro de solicitudes.
El controlador de GKE Gateway admite las siguientes extensiones de servicio:
- GCPRoutingExtension: Esta extensión agrega lógica personalizada a Cloud Load Balancing para controlar el enrutamiento del tráfico.
- GCPTrafficExtension: Esta extensión inserta lógica personalizada en Cloud Load Balancing para modificar el tráfico. Esta lógica se aplica al tráfico después de que se selecciona el servicio. El balanceador de cargas puede agregar o cambiar los encabezados y las cargas útiles de las solicitudes y respuestas HTTP. GCPTrafficExtension no afecta la selección de servicios ni las políticas de seguridad de los servicios.
- GCPEdgeExtension: Esta extensión te permite influir en la selección del servicio de backend y en las claves de caché de Cloud CDN modificando los encabezados de la solicitud. Solo se admite para los balanceadores de cargas administrados externos globales.
- GCPAuthzExtension: Esta extensión te permite delegar decisiones de autorización a un motor de autorización personalizado o de terceros (como un firewall de aplicación web externo) o a Identity-Aware Proxy. Esta extensión se usa con un recurso GCPAuthzPolicy, que aplica el control de acceso al tráfico que ingresa a la puerta de enlace y dicta cuándo debe ocurrir la llamada externa a la extensión.
Una extensión se adjunta a una puerta de enlace. En el caso de una puerta de enlace de un solo clúster, la extensión hace referencia a un recurso Service, un recurso GCPWasmPlugin o un recurso GoogleAPIServiceName. En el caso de una puerta de enlace de varios clústeres, la extensión hace referencia a un recurso ServiceImport o a un recurso GoogleAPIServiceName.
Hacer referencia a un recurso Service o a un recurso ServiceImport: En este modelo, implementas tu lógica personalizada como una aplicación de backend independiente, expuesta como un Service de Kubernetes. El balanceador de cargas realiza una llamada externa a este servicio para procesar el tráfico. Este enfoque es versátil y te permite implementar lógica de enrutamiento personalizada o manipular el tráfico, como modificar encabezados o inspeccionar cargas útiles.
Haz referencia a un recurso de GCPWasmPlugin: Para casos de uso de alto rendimiento, puedes insertar lógica personalizada escrita por el usuario directamente en la ruta de datos del balanceador de cargasCloud de Confiance by S3NS con un módulo de WebAssembly (Wasm). Defines un recurso GCPWasmPlugin que apunta a la imagen de tu módulo Wasm en Artifact Registry. Este método solo se usa con los recursos de GCPTrafficExtension y GCPEdgeExtension, y con un balanceador de cargas de aplicaciones externo global.
Hacer referencia a un servicio de la API de Google: También puedes hacer referencia a un servicio de la API de Google directamente usando el campo
googleAPIServiceNamedentro de un GCPTrafficExtension o GCPAuthzExtension.
En el siguiente diagrama, el recurso GCPRoutingExtension se adjunta a una puerta de enlace y hace referencia a varios servicios. La extensión controla el enrutamiento del tráfico a los Servicios.
En el siguiente diagrama, el recurso GCPTrafficExtension está adjunto a una puerta de enlace y hace referencia a un servicio, a un GoogleAPIServiceName o a un GCPWasmPlugin. La extensión cambia los encabezados y las cargas útiles de las solicitudes y respuestas.
Antes de comenzar
Antes de comenzar, asegúrate de haber realizado las siguientes tareas:
- Habilita la API de Google Kubernetes Engine. Habilitar la API de Google Kubernetes Engine
- Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste la gcloud CLI, ejecuta el comando
gcloud components updatepara obtener la versión más reciente. Es posible que las versiones anteriores de gcloud CLI no admitan la ejecución de los comandos que se indican en este documento.
Habilita la API de Compute Engine, la API de Network Services y la API de Model Armor si es necesario.
Ve a Habilita el acceso a las APIs y sigue las instrucciones.
Para obtener información detallada sobre los precios de Cloud de ConfianceService Extensions, consulta Precios.
Revisa los roles y permisos necesarios en Control de acceso a Service Extensions.
Familiarízate con las cuotas y los límites en Cuotas de Service Extensions.
Si planeas usar comparadores de Common Expression Language (CEL), revisa los atributos y operadores admitidos en la referencia del lenguaje de comparadores de CEL.
Revisa las restricciones y limitaciones de las extensiones de servicio.
Requisitos del controlador de la puerta de enlace de GKE
- Tu clúster debe usar la versión 1.33 de GKE o una posterior.
- Para usar GCPWasmPlugin, tu clúster debe usar la versión 1.33.3 de GKE o una posterior.
- Para usar el recurso ServiceImport, tu clúster debe usar la versión 1.24.3 de GKE o una posterior.
- Debes tener un recurso de Gateway configurado para una puerta de enlace interna de varios clústeres. Este recurso puede ser un balanceador de cargas de aplicaciones externo global, un balanceador de cargas de aplicaciones interno entre regiones, un balanceador de cargas de aplicaciones externo regional o una puerta de enlace del balanceador de cargas de aplicaciones interno regional.
- Tu clúster debe tener habilitada la API de Gateway.
- Debes tener un recurso de Gateway configurado. Este recurso puede ser un balanceador de cargas de aplicaciones externo global, un balanceador de cargas de aplicaciones externo regional o una puerta de enlace del balanceador de cargas de aplicaciones interno regional. Si usas un recurso GCPWasmPlugin, solo debes implementar una puerta de enlace del balanceador de cargas de aplicaciones externo global.
- Debes tener configurado un recurso HTTPRoute.
Restricciones y limitaciones
En la siguiente tabla, se enumeran las restricciones asociadas con la configuración de las extensiones de Gateway Service en GKE:
| Categoría | Restricciones y limitaciones |
|---|---|
| Balanceador de cargas |
La extensión GCPRoutingExtension es compatible con los siguientes balanceadores de cargas:
gke-l7-global-external-managed).
|
| Cadena y especificación de la extensión |
|
| Tiempo de espera |
|
| MatchCondition |
|
| Encabezado |
|
| Metadatos |
|
| Evento |
|
| RequestBodySendMode |
|
| ResponseBodySendMode |
|
| Referencias de recursos |
|
| GCPWasmPlugin |
|
| GCPAuthzPolicy y GCPAuthzExtension |
|
googleAPIServiceName |
|
backendRef |
Cuando haces referencia a un Servicio que usa backendRef en una extensión, debes cumplir con las siguientes condiciones:
|
observabilityMode |
El campo observabilityMode se puede establecer en el Extension con las siguientes limitaciones:
|
Referencia a un servicio
En Service Extensions, puedes hacer referencia a un servicio que aloja la lógica personalizada que deseas que ejecute el balanceador de cargas. Las puertas de enlace no tienen Service Extensions de forma predeterminada.
Para configurar las extensiones de servicio de GKE, sigue estos pasos:
Implementa un servicio de devolución de llamada de backend: Crea un servicio de Kubernetes que represente el servicio de backend para la ejecución de lógica personalizada. El balanceador de cargas invoca este servicio.
Configura Service Extensions: Usa la extensión adecuada según el tipo de balanceador de cargas.
GCPRoutingExtension para Gateways regionales: Usa esta extensión para el balanceador de cargas de aplicaciones externo regional y el balanceador de cargas de aplicaciones interno regional para implementar lógica de enrutamiento personalizada dentro de la región.
GCPTrafficExtension para puertas de enlace externas globales, externas regionales e internas: Usa esta extensión para el balanceador de cargas de aplicaciones externo global, el balanceador de cargas de aplicaciones externo regional y el balanceador de cargas de aplicaciones interno regional para realizar la manipulación del tráfico, como la modificación de encabezados o la inspección de cargas útiles, en varios tipos de balanceadores de cargas.
Implementa un servicio de llamada externa de backend
Un servicio de devolución de llamada implementa lógica personalizada para las extensiones de servicio de Gateway en GKE. La puerta de enlace invoca estas aplicaciones de backend, según las configuraciones de GCPTrafficExtension o GCPRoutingExtension, para modificar o enrutar el tráfico.
Implementas un servicio de llamada para agregar lógica personalizada a tu puerta de enlace. Este servicio independiente controla el procesamiento personalizado, como la manipulación de encabezados, las transformaciones de cargas útiles o el enrutamiento del tráfico.
Para implementar un servicio que pueda funcionar como un texto destacado para tu puerta de enlace, sigue estos pasos:
(Opcional) Crea un secreto para TLS: Este comando crea un secreto de Kubernetes de tipo TLS que contiene tu certificado TLS y tu clave privada.
Para crear el secreto de TLS para tu servicio de devolución de llamada, reemplaza lo siguiente:
SECRET_NAME: El nombre secreto de tu servicio de texto destacadopath-to-cert: las rutas de acceso a tu certificadopath-to-key: Las rutas de acceso a tu clave
Para verificar que se haya agregado el secreto, ejecuta el siguiente comando:
kubectl get secrets SECRET_NAMEReemplaza
SECRET_NAMEpor el nombre secreto de tu servicio de llamada.El resultado debería ser similar al siguiente ejemplo:
NAME TYPE DATA AGE SECRET_NAME kubernetes.io/tls 2 12sDefine los recursos de Deployment y Service.
Debes definir lo siguiente:
- Deployment: Para administrar los Pods de la aplicación que contienen la lógica personalizada de tus Service Extensions.
- Service: Para exponer los pods de la aplicación que administra la Deployment como un servicio de red.
Crea un manifiesto de muestra
extension-service-app.yamlque tenga definiciones de Deployment y Service: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:public-image-e42d951 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_PATH 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: storeReemplaza lo siguiente:
POD_NAME: es el nombre del Pod.SECRET_NAME: Es el nombre secreto de tu servicio de texto destacado.TLS_SERVER_CERT_PATH: Es la ruta de acceso al certificado del servidor TLS dentro del Pod.TLS_SERVER_PRIVKEY: Es la ruta de acceso a la clave privada del servidor TLS dentro del Pod.
Aplica el manifiesto
extension-service-app.yaml:kubectl apply -f extension-service-app.yaml
Verifica la configuración:
Verifica que la aplicación se haya implementado:
kubectl get pod --selector app=storeDespués de que la aplicación comienza a ejecutarse, el resultado es similar al siguiente:
NAME READY STATUS RESTARTS AGE extension-service-app-85f466bc9b-b5mf4 1/1 Running 0 7sVerifica que se haya implementado el servicio:
kubectl get service extension-serviceEl resultado es similar al siguiente, que muestra un objeto Service para cada Deployment de la tienda:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE extension-service ClusterIP 34.118.225.9 <none> 443/TCP 2m40s
Configura las extensiones de servicio
Puedes configurar un GCPRoutingExtension o un GCPTrafficExtension para personalizar tu flujo de tráfico.
Configura GCPRoutingExtension para las puertas de enlace regionales
Puedes redirigir el tráfico con un GCPRoutingExtension. Para configurar un GCPRoutingExtension, actualiza el HTTPRoute para especificar las solicitudes del host service-extensions.com.
Actualiza HTTPRoute. Modifica tu HTTPRoute para incluir nombres de host o rutas de acceso que activarán la extensión de enrutamiento.
Guarda el siguiente manifiesto de muestra como el archivo
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: 8080Reemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.Aplica el manifiesto
store-route.yaml:kubectl apply -f store-route.yaml
Define el GCPRoutingExtension.
Guarda la configuración de GCPRoutingExtension en el archivo
gcp-routing-extension.yamlde muestra: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: 443Reemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.Aplica el manifiesto de muestra a tu clúster:
kubectl apply -f gcp-routing-extension.yaml
Verifica la configuración de GCPRoutingExtension y su vinculación a Gateway.
Verifica la implementación de GCPRoutingExtension:
kubectl describe gcproutingextension my-gateway-extensionEl resultado es similar a lo siguiente:
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>El resultado muestra los detalles de GCPRoutingExtension, que se llama
my-gateway-extension, dentro del espacio de nombres predeterminado. El resultado muestra el campoSpec, que contiene la definición de cómo debe comportarse la extensión.Verifica la vinculación de la puerta de enlace:
Confirma que la extensión GCPRoutingExtension esté vinculada a la puerta de enlace. Esto puede tardar algunos minutos:
kubectl describe gateway GATEWAY_NAMEReemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.El resultado es similar a lo siguiente:
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 ...El resultado muestra las anotaciones que GKE usa para almacenar los vínculos entre la puerta de enlace y los recursos deCloud de Confiance subyacentes. La anotación
networking.gke.io/lb-route-extensionsconfirma la vinculación de la puerta de enlace a GCPRoutingExtension.Verifica el estado de la extensión. Para ello, confirma que GCPRoutingExtension tiene un estado
Programmedcon el motivoProgrammingSucceeded. Este comando podría tardar unos minutos.kubectl describe gcproutingextension my-gateway-extensionEl resultado es similar a lo siguiente:
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 successEl campo
Status.Conditionsmuestra una condiciónProgrammedconStatus: TrueyReason: ProgrammingSucceeded. Esta información confirma que la extensión se aplicó correctamente.
Envía tráfico a tu aplicación.
Después de implementar la puerta de enlace, la ruta y la aplicación en el clúster, puedes pasar el tráfico a la aplicación.
Para acceder a tu aplicación, debes encontrar la dirección IP de tu puerta de enlace.
En tu terminal, usa el siguiente comando:
kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"Reemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.Este comando genera la dirección IP de la puerta de enlace. En los comandos de seguimiento, reemplaza
GATEWAY_IP_ADDRESSpor la dirección IP del resultado.Para probar la actualización de la ruta de acceso, ve a la versión
serviceextensionsdel servicio de almacenamiento enstore.example.com/serviceextensions:curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vEl resultado es similar a lo siguiente:
{ "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" }
Configura GCPTrafficExtension
Puedes usar un GCPTrafficExtension para usar capacidades avanzadas de administración del tráfico en tu entorno de Cloud de Confiance . Puedes configurar esta extensión en los balanceadores de cargas de aplicaciones externos globales, los balanceadores de cargas de aplicaciones externos regionales y los balanceadores de cargas de aplicaciones internos regionales. Puedes usar GCPTrafficExtension para implementar lógica personalizada de solicitud y respuesta HTTP, enrutamiento sofisticado, transformaciones y políticas de seguridad.
Actualiza HTTPRoute. Modifica tu HTTPRoute para incluir nombres de host o rutas de acceso que activarán la extensión de tráfico.
Guarda el siguiente manifiesto de muestra como el archivo
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: 8080Reemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace, comointernal-http,external-httpoglobal-external-http.Aplica el manifiesto
store-route.yamla tu clúster:kubectl apply -f store-route.yaml
Define el GCPTrafficExtension.
Guarda la configuración de GCPTrafficExtension en el archivo
gcp-traffic-extension.yamlde muestra: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 supportedEvents: - RequestHeaders - RequestBody - ResponseHeaders - ResponseBodyReemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace, comointernal-http,external-httpoglobal-external-http.Aplica el manifiesto de muestra a tu clúster:
kubectl apply -f gcp-traffic-extension.yaml
Verifica la configuración de GCPTrafficExtension y su vinculación con la puerta de enlace.
Verifica la implementación de GCPTrafficExtension:
kubectl describe gcptrafficextension my-traffic-extensionEl resultado es similar a lo siguiente:
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>En el resultado, se muestran los detalles de la extensión GCPTrafficExtension llamada
my-traffic-extensiondentro del espacio de nombres predeterminado. Muestra el campoSpec, que contiene la definición de cómo debe comportarse la extensión.Verifica la vinculación de la puerta de enlace:
Confirma que GCPTrafficExtension esté vinculada a la puerta de enlace. Este comando puede tardar unos minutos en completarse:
kubectl describe gateway GATEWAY_NAMEEl resultado es similar a lo siguiente:
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 ...El resultado muestra las anotaciones que GKE usa para almacenar los vínculos entre la puerta de enlace y los recursos Cloud de Confiance subyacentes. La anotación
networking.gke.io/lb-traffic-extensionsconfirma la vinculación.Verifica el estado de la extensión:
Para verificar el estado de la extensión de GCPTrafficExtension, ejecuta el siguiente comando:
kubectl describe gcptrafficextension my-traffic-extensionConfirma que GCPTrafficExtension tenga el estado
Programmedcon el motivoProgrammingSucceeded. Este comando puede tardar unos minutos en completarse.El resultado del recurso GCPTrafficExtension es similar al siguiente:
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 successEl campo
Status.Conditionsmuestra una condiciónProgrammedconStatus: TrueyReason: ProgrammingSucceeded. Esta información confirma que la extensión se aplicó correctamente.
Envía tráfico a tu aplicación.
Después de implementar la puerta de enlace, la ruta y la aplicación en el clúster, puedes pasar el tráfico a la aplicación.
Para acceder a tu aplicación, debes encontrar la dirección IP de tu puerta de enlace.
En tu terminal, usa el siguiente comando:
kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"Reemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.Este comando genera la dirección IP de la puerta de enlace. En los comandos de seguimiento, reemplaza
GATEWAY_IP_ADDRESSpor la dirección IP del resultado.Para probar la actualización de la ruta de acceso, ve a la versión
serviceextensionsdel servicio de almacenamiento enstore.example.com/serviceextensions:curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vEl resultado es similar a lo siguiente:
{ * 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 }
Configura el recurso GCPAuthzExtension
Puedes usar una extensión GCPAuthzExtension con una política GCPAuthzPolicy para aplicar decisiones de autorización complejas delegándolas a un servicio externo o a Identity-Aware Proxy (IAP).
Define GCPAuthzExtension:
Puedes configurar GCPAuthzExtension para que haga referencia a un servicio de extensión personalizado o a IAP como un servicio de llamada externa.
Opción 1: Haz referencia a un servicio de extensión personalizado
- Guarda la configuración de GCPAuthzExtension en el archivo
gcp-authz-extension.yamlde muestra:
apiVersion: networking.gke.io/v1 kind: GCPAuthzExtension metadata: name: my-authz-ext namespace: default spec: backendRef: kind: Service name: "${authz-service}" forwardHeaders: - Authorization failOpen: false timeout: "0.1s" wireFormat: EXT_PROC_GRPCEn el ejemplo anterior,
"${authz-service}"es un servicio de extensión que debe estar presente en el mismo espacio de nombres que GCPAuthzPolicy.- Aplica el manifiesto
kubectl apply -f gcp-authz-extension.yaml- Guarda la configuración de GCPAuthzExtension en el archivo
Opción 2: Haz referencia a la IAP como un servicio de llamada personalizado
También puedes configurar IAP como un servicio de llamada personalizado especificando
iap.googleapis.comen el campogoogleAPIServiceName:- Guarda la configuración de GCPAuthzExtension en el archivo
authz-extension-iap.yamlde muestra:
apiVersion: networking.gke.io/v1 kind: GCPAuthzExtension metadata: name: my-authz-ext-iap namespace: default spec: googleAPIServiceName: iap.googleapis.com timeout: 50ms failOpen: false- Aplica el manifiesto
kubectl apply -f authz-extension-iap.yaml- Guarda la configuración de GCPAuthzExtension en el archivo
Define el objeto GCPAuthzPolicy:
La política de GCPAuthzPolicy se dirige a la puerta de enlace y especifica la acción que se debe realizar en el tráfico coincidente:
Configura una política de autorización de
CUSTOM:La acción
CUSTOMdelega la decisión de autorización a la extensión que creaste en el paso anterior.Guarda el siguiente manifiesto en
gcp-authz-policy.yaml:apiVersion: networking.gke.io/v1 kind: GCPAuthzPolicy metadata: name: my-gateway-authz namespace: default spec: enforcementLevel: L7 targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: "GATEWAY_NAME" rules: - from: sources: - principals: - principal_selector: CLIENT_CERT_URI_SANS principal: exact: "spiffee://cluster.local/ns1/pod1" - to: operations: - paths: - exact: "/api/secure-endpoint" action: CUSTOM customProvider: authzExtension: extensionRefs: - group: networking.gke.io kind: GCPAuthzExtension name: my-authz-extReemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.Aplica el manifiesto
kubectl apply -f gcp-authz-policy.yaml
Cómo hacer referencia a un recurso de GCPWasmPlugin
Puedes insertar lógica personalizada directamente en la ruta de datos del balanceador de cargas con un GCPWasmPlugin con un GCPTrafficExtension o un GCPEdgeExtension. Este método te permite implementar capacidades personalizadas de administración del tráfico empaquetadas como un módulo de Wasm.
Para configurar las extensiones de servicio de GKE, sigue estos pasos:
Implementa un GCPWasmPlugin: Crea e implementa una CustomResourceDefinition (CRD) de GCPWasmPlugin que contenga el código personalizado para tu módulo Wasm. Puedes usar GCPWasmPlugin con GCPTrafficExtension o GCPEdgeExtension para la GatewayClass de
gke-l7-global-external-managed.Configura extensiones de servicio: Configura una de las siguientes extensiones con GCPWasmPlugin:
Implementa un GCPWasmPlugin
El GCPWasmPlugin te permite insertar lógica personalizada escrita por el usuario directamente en la ruta de datos del balanceador de cargas Cloud de Confiance . El recurso GCPWasmPlugin apunta a la imagen del módulo de Wasm en Artifact Registry, que luego ejecuta el balanceador de cargas.
Antes de continuar con los siguientes pasos, asegúrate de haber subido tu módulo de Wasm a un repositorio de Artifact Registry. Para obtener más información, consulta Prepara el código del complemento.
Para implementar un recurso de GCPWasmPlugin, completa los siguientes pasos:
Guarda el siguiente manifiesto 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: INFOTen en cuenta lo siguiente:
spec.versions.name: El nombre de la versión debe ser único dentro del recurso GCPWasmPlugin. Puedes enumerar hasta 10 versiones, y solo una de ellas debe tener un peso distinto de cero.spec.versions.image: Hace referencia a la imagen que contiene el código del complemento almacenado en Artifact Registry.spec.versions.weight: Especifica el peso de la versión del complemento. El peso debe ser un número entre 0 y 1,000,000, inclusive.spec.logConfig: Especifica si se debe habilitar Cloud Logging para este complemento. Si no se especifica el valor, Cloud Logging se inhabilita de forma predeterminada.spec.logConfig.sampleRate: Configura la tasa de muestreo de los registros de actividad. La tasa debe ser un número entre 0 y 1,000,000, inclusive. Si no se especifica cuando Cloud Logging está habilitado, el valor predeterminado es1,000,000(se registra el 100% de las solicitudes).spec.logConfig.minLogLevel: Especifica el nivel más bajo de registros que se exportan a Cloud Logging. Si no se especifica el valor cuando se habilita Cloud Logging, el campo se establece enINFOde forma predeterminada.
Aplica el manifiesto
wasm-plugin.yaml:kubectl apply -f wasm-plugin.yamlVerifica que se haya implementado el complemento:
kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-pluginEl resultado es similar a lo siguiente:
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>
Configura GCPTrafficExtension
Para agregar lógica personalizada a tu balanceador de cargas de aplicaciones externo global, puedes configurar un GCPTrafficExtension para que use un GCPWasmPlugin. Puedes usar un GCPTrafficExtension para aprovechar las capacidades avanzadas de administración del tráfico en tu entorno de Cloud de Confiance . Puedes configurar esta extensión en todos los balanceadores de cargas de aplicaciones externos globales.
Para configurar un GCPTrafficExtension para que use un GCPWasmPlugin, completa los siguientes pasos:
Define el GCPTrafficExtension.
Guarda la configuración de 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-pluginReemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace, comoglobal-external-http.Aplica el manifiesto de muestra a tu clúster:
kubectl apply -f gcp-traffic-extension-with-plugin.yaml
Verifica la configuración de GCPTrafficExtension y su vinculación con la puerta de enlace.
Verifica la implementación de GCPTrafficExtension:
kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-pluginEl resultado es similar a lo siguiente:
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>Reemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.En el resultado, se muestran los detalles de la extensión GCPTrafficExtension llamada
gcp-traffic-extension-with-plugindentro del espacio de nombres predeterminado. Se muestra el campoSpec, que contiene la definición de cómo debe comportarse la extensión.Verifica la vinculación de la puerta de enlace:
Confirma que GCPTrafficExtension esté vinculada a la puerta de enlace. Este comando puede tardar unos minutos en completarse:
kubectl describe gateway GATEWAY_NAMEReemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.El resultado es similar a lo siguiente:
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 ...El resultado muestra las anotaciones que GKE usa para almacenar los vínculos entre la puerta de enlace y los recursos Cloud de Confiancesubyacentes. Las anotaciones
networking.gke.io/lb-traffic-extensions,networking.gke.io/wasm-plugin-versionsynetworking.gke.io/wasm-pluginsconfirman la vinculación.Verifica el estado de la extensión:
Confirma que GCPTrafficExtension tenga el estado
Programmedcon el motivoProgrammingSucceeded. Este comando puede tardar unos minutos en completarse.kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-pluginEl resultado es similar a lo siguiente:
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 successVerifica el estado del complemento.
Confirma que el recurso GCPWasmPlugin tenga el estado
Programmedcon el motivoProgrammingSucceeded. Este comando puede tardar unos minutos en completarse.kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-pluginEl resultado es similar a lo siguiente:
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
Envía tráfico a tu aplicación.
Después de implementar la puerta de enlace, la ruta y la aplicación en el clúster, puedes pasar el tráfico a la aplicación.
Para acceder a tu aplicación, debes encontrar la dirección IP de tu puerta de enlace.
En tu terminal, usa el siguiente comando:
kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"Reemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.Este comando genera la dirección IP de la puerta de enlace. En los comandos de seguimiento, reemplaza
GATEWAY_IP_ADDRESSpor la dirección IP del resultado.Para probar la actualización de la ruta de acceso, ve a la versión
serviceextensionsdel servicio de almacenamiento enstore.example.com/serviceextensions:curl https://store.example.com/serviceextensions --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -vEl resultado devuelve
Hello World.
Configura GCPEdgeExtension con GCPWasmPlugin
Para agregar lógica personalizada a tu balanceador de cargas de aplicaciones externo global con un módulo de WebAssembly (Wasm), configura un GCPEdgeExtension que haga referencia a GCPWasmPlugin.
Guarda el siguiente manifiesto de GCPEdgeExtension como
gcp-edge-extension-with-plugin.yaml:kind: GCPEdgeExtension apiVersion: networking.gke.io/v1 metadata: name: gcp-edge-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.startsWith("/serviceextensions") extensions: - name: ext1 supportedEvents: - RequestHeaders backendRef: group: "networking.gke.io" kind: GCPWasmPlugin name: gcp-wasm-pluginReemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.Aplica el manifiesto al clúster:
kubectl apply -f gcp-edge-extension-with-plugin.yamlVerifica la configuración de GCPEdgeExtension y su vinculación a la puerta de enlace:
Verifica el estado de la extensión:
Para verificar el estado de la extensión de GCPEdgeExtension, ejecuta el siguiente comando:
kubectl describe gcpedgeextensions.networking.gke.io gcp-edge-extension-with-pluginConfirma que GCPEdgeExtension tenga el estado
Programmedcon el motivoProgrammingSucceeded. Este comando puede tardar unos minutos en completarse.Verifica la vinculación de la puerta de enlace:
Ejecuta el comando siguiente:
kubectl describe gateway GATEWAY_NAMEReemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.Confirma que GCPEdgeExtension esté vinculada a la puerta de enlace. Este comando puede tardar unos minutos en completarse. El resultado incluye la anotación
networking.gke.io/lb-edge-extensions, que confirma la vinculación entre la puerta de enlace y la extensión perimetral.
Envía tráfico a la extensión
Después de implementar tu puerta de enlace y GCPEdgeExtension, prueba la lógica de enrutamiento enviando tráfico a tu aplicación.
Para acceder a tu aplicación, obtén la dirección IP de tu puerta de enlace:
kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"El resultado es la dirección IP de la puerta de enlace. En los siguientes comandos, reemplaza
GATEWAY_IP_ADDRESSpor la dirección IP del resultado.Envía una solicitud a la URL base:
curl http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vLa puerta de enlace enruta la solicitud al servicio predeterminado, como
store-v1.Envía una solicitud a la ruta de acceso especificada en tu celMatcher, como
/serviceextensions:curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vLa extensión activa el complemento de Wasm, que enruta la solicitud al servicio secundario, como
store-v2.
Administra el recurso de GCPWasmPlugin
Puedes actualizar el CRD de GCPWasmPlugin y supervisar el complemento.
Actualiza el complemento GCPWasmPlugin
Para actualizar un recurso de GCPWasmPlugin, sigue estos pasos:
Realiza el cambio en el manifiesto de tu GCPWasmPlugin y sigue los pasos que se describen en Implementa un GCPWasmPlugin.
Por ejemplo, para tener dos versiones del complemento, en las que una versión publica anuncios y la otra no, actualiza tu archivo
wasm-plugin.yamlde la siguiente manera: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: INFOEn este ejemplo, se aplica lo siguiente:
wasm-plugin-version-v1tiene unweightde1000000, lo que significa que entrega todo el tráfico.wasm-plugin-version-v2tiene unweightde0, lo que significa que no publica ningún tráfico.
Para asegurarte de que la puerta de enlace se actualizó, ejecuta el siguiente comando. Este comando puede tardar unos minutos en completarse:
kubectl describe gateway GATEWAY_NAMEReemplaza
GATEWAY_NAMEpor el nombre de tu puerta de enlace.
Supervisa GCPWasmPlugin
Para ver las métricas de GCPWasmPlugin en la consola de Cloud de Confiance , consulta Supervisión desde la perspectiva de los complementos.
Cuando llegues al paso de la guía en el que debes seleccionar un valor de la lista Filtro de versión del complemento, busca el formato prefix−WASM_PLUGIN_VERSION_NAME_FROM_FILE−suffix, en el que WASM_PLUGIN_VERSION_NAME_FROM_FILE es el nombre específico de la versión que definiste en el archivo de configuración de GCPWasmPlugin.
Soluciona problemas relacionados con las extensiones de tráfico en Gateways
En esta sección, se proporcionan sugerencias para solucionar problemas relacionados con la configuración de extensiones de tráfico en las puertas de enlace.
No se encontró la puerta de enlace
El siguiente error indica que no existe el recurso de Gateway especificado en el campo targetRefs del recurso de GCPTrafficExtension, GCPRoutingExtension o GCPEdgeExtension:
error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.gatewayRef: gateway "my-gateway" not found in namespace "default"
Para resolver este problema, asegúrate de que el recurso de Gateway especificado en el campo targetRefs del recurso GCPTrafficExtension o GCPRoutingExtension exista en el espacio de nombres especificado.
No se encontró el servicio o el puerto de servicio
El siguiente error indica que no existe el puerto de Service o Service especificado en el campo backendRef del recurso GCPTrafficExtension o GCPRoutingExtension:
error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: service "callout-service" not found in namespace "default"
Para resolver este problema, asegúrate de que el Service y el puerto del Service especificados en el campo backendRef del recurso GCPTrafficExtension o GCPRoutingExtension existan en el espacio de nombres especificado.
No hay extremos de red en el NEG.
El siguiente error indica que no hay extremos de red en el NEG asociados con el Service especificado en el campo backendRef del recurso GCPTrafficExtension o GCPRoutingExtension:
error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: no network endpoints found for service "callout-service"
Para resolver este problema, asegúrate de que el servicio especificado en el campo backendRef del recurso GCPTrafficExtension o GCPRoutingExtension tenga extremos de red.
No hay respuesta o se responde con un error cuando se envía la solicitud
Si no recibes una respuesta o si recibes una respuesta con un error cuando envías una solicitud, es posible que el servicio de llamada no esté funcionando correctamente.
Para resolver este problema, revisa los registros del servicio de texto destacado en busca de errores.
Código de error 404 en la carga útil de JSON
El siguiente error indica que no se encontró el servicio de texto destacado o que no responde a la solicitud:
{
"error": {
"code": 404,
"message": "Requested entity was not found.",
"status": "NOT_FOUND"
}
}
Para resolver este problema, asegúrate de que el servicio de llamadas esté en ejecución, de que esté escuchando en el puerto correcto y de que el servicio esté configurado correctamente en el recurso GCPTrafficExtension o GCPRoutingExtension.
Código de error 500 en la carga útil de JSON
El siguiente error indica que el servicio de texto destacado está experimentando un error interno del servidor:
{
"error": {
"code": 500,
"message": "Internal server error.",
"status": "INTERNAL"
}
}
Para resolver este problema, revisa los registros del servicio de texto destacado para identificar la causa del error interno del servidor.
GCPWasmPlugin no existe
El siguiente error indica que el recurso GCPWasmPlugin no existe en tu proyecto para tu GCPTrafficExtension o GCPEdgeExtension:
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 este problema, crea un GCPWasmPlugin correspondiente en el proyecto Cloud de Confiance o dirige una extensión a un GCPWasmPlugin existente.
¿Qué sigue?
- Obtén más información sobre la puerta de enlace de inferencia de GKE.
- Obtén más información para entregar un LLM con GKE Inference Gateway.
- Obtén más información para ver las métricas de observabilidad.