Personalizar el tráfico de GKE Gateway con extensiones de servicio


En esta página se describe cómo usa Google Kubernetes Engine (GKE) las extensiones de servicio para añadir lógica personalizada a Cloud Load Balancing.

Esta página está dirigida a administradores de identidades y cuentas de GKE, así como a desarrolladores que necesiten configurar lógica de gestión del tráfico personalizada mediante extensiones de servicio.

Antes de leer esta página, asegúrese de que conoce los siguientes conceptos:

Información general

GKE usa extensiones de servicio para añadir lógica personalizada a Cloud Load Balancing. Una extensión se adjunta a un Gateway y hace referencia a un Service o a un GoogleAPIServiceName. La GoogleAPIServiceName solo es compatible con GCPTrafficExtensions.

Puede modificar los encabezados y las cargas útiles HTTP de las solicitudes y las respuestas, o controlar el enrutamiento del tráfico, sin que esto afecte a la selección del servicio de backend ni a las políticas de seguridad. Puedes usar extensiones de servicio 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 añade lógica personalizada a Cloud Load Balancing para controlar el enrutamiento del tráfico. Se admite en el balanceador de carga de aplicaciones externo regional y en el balanceador de carga de aplicaciones interno regional.

    El recurso `GCPRoutingExtension` se adjunta a una pasarela y hace referencia a un servicio. La extensión
        controla el enrutamiento del tráfico.
    Ilustración: Cómo funciona GCPRoutingExtension con las pasarelas
  • GCPTrafficExtension: esta extensión inserta lógica personalizada en Cloud Load Balancing. Permite que un servicio de extensión cambie los encabezados y las cargas útiles de las solicitudes y las respuestas. El GCPTrafficExtension no afecta a la selección de servicios de backend ni a las políticas de seguridad de los servicios de backend.

    El recurso `GCPTrafficExtension` se adjunta a una pasarela y hace referencia a un servicio o a un `GoogleAPIServiceName`. La extensión cambia los encabezados y las cargas útiles de las solicitudes y las respuestas.
    Ilustración: Cómo funciona GCPTrafficExtension con las pasarelas

Google Cloud Compatibilidad de Service Extension con GatewayClasses

En la siguiente tabla se describe la compatibilidad de las extensiones de servicio Google Cloud con diferentes GatewayClasses:

GatewayClass GCPRoutingExtension GCPTrafficExtension
gke-l7-rilb Compatible Compatible
gke-l7-regional-external-managed Compatible Compatible
gke-l7-global-external-managed No compatible Compatible

Antes de empezar

Antes de empezar, asegúrate de que has realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la gcloud CLI, obtén la versión más reciente ejecutando gcloud components update.

Requisitos de GKE Gateway Controller

Restricciones y limitaciones

En la siguiente tabla se indican las restricciones asociadas a la configuración de las extensiones de servicio de pasarela en GKE:

Categoría Restricciones y limitaciones
Balanceador de carga El GCPRoutingExtension solo se admite en los balanceadores de carga de aplicaciones externos regionales y en los balanceadores de carga de aplicaciones internos regionales (gke-l7-regional-external-managed y gke-l7-rilb clases Gateway) y no se admite en la clase Gateway gke-l7-global-external-managed.
Cadena y especificación de la extensión
  • En un GCPTrafficExtension, cada ExtensionChain puede tener un máximo de 3 Extensions.
  • En el caso de GCPRoutingExtension, cada ExtensionChain está limitado a 1 Extension.
  • Un GCPTrafficExtensionSpec y un GCPRoutingExtensionSpec pueden tener un máximo de 5 ExtensionChains cada uno.
Tiempos y coincidencias
  • El tiempo de espera de cada mensaje del flujo de una extensión debe estar entre 10 y 1000 milisegundos. Este límite de un segundo se aplica a las extensiones de ruta y tráfico.
  • Cada MatchCondition de un ExtensionChain puede tener un máximo de 10 CELExpressions.
  • La cadena MatchCondition resultante que se envía a GCE tiene un límite de 512 caracteres.
  • La cadena CELMatcher de un CELExpression tiene una longitud máxima de 512 caracteres y debe seguir un patrón específico. No admitimos el campo BackendRefs de CELExpression.
Encabezado y metadatos
  • La lista ForwardHeaders de un Extension puede contener un máximo de 50 nombres de encabezado HTTP.
  • El mapa Metadata de un Extension puede tener un máximo de 16 propiedades.
  • Las claves del mapa Metadata deben tener entre 1 y 63 caracteres.
  • Los valores del mapa Metadata deben tener entre 1 y 1023 caracteres.
Evento
  • En el caso de GCPRoutingExtension, si no se define requestBodySendMode, la lista supportedEvents solo puede contener eventos RequestHeaders.
  • En el caso de GCPRoutingExtension, si requestBodySendMode tiene el valor FullDuplexStreamed, la lista supportedEvents solo puede contener eventos RequestHeaders, RequestBody y RequestTrailers.
GCPTrafficExtension
  • El campo responseBodySendMode solo se admite en GCPTrafficExtension.
  • El campo googleAPIServiceName solo se admite en GCPTrafficExtension.
googleAPIServiceName y backendRef Cuando hagas referencia a un Servicio que use la backendRef en una extensión, debes cumplir las siguientes condiciones:
  • Debe usar HTTP2 como appProtocol.
  • Debe estar en el mismo espacio de nombres que la extensión y la pasarela a la que hace referencia la extensión.
  • No se puede usar IAP.
  • No se pueden usar políticas de seguridad de Google Cloud Armor (campo securityPolicy de GCPBackendPolicyConfig.
  • No se puede usar Cloud CDN.
  • Debe definir exactamente uno de los valores backendRef o googleAPIServiceName para un Extension.
  • Debe definir authority si se ha definido backendRef.
  • Debe definir authority si se ha definido googleAPIServiceName.
  • Configura requestBodySendMode para las extensiones usando solo backendRef.
  • Configura responseBodySendMode para las extensiones usando solo backendRef.

Configurar extensiones de servicio de GKE

Puedes personalizar el enrutamiento del tráfico, modificar las cargas útiles de las solicitudes o respuestas e integrarte con servicios externos configurando las extensiones de servicio de GKE. Las pasarelas no tienen extensiones de servicio de forma predeterminada.

Para configurar las extensiones de servicio de GKE, sigue estos pasos:

  1. Despliega una pasarela: para configurar una extensión de servicio de GKE, primero debes desplegar una pasarela, que dirige el tráfico externo a tu clúster. Puede ser un balanceador de carga de aplicación externo global, un balanceador de carga de aplicación externo regional o una pasarela de balanceador de carga de aplicación interno regional.

    Para obtener más información sobre cómo implementar pasarelas, consulta Implementar pasarelas.

  2. Desplegar un servicio 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 carga invoca este servicio.

  3. Configura las extensiones de servicio: configura las extensiones de servicio adecuadas en función del tipo y los requisitos de tu balanceador de carga.

    1. GCPRoutingExtension para las pasarelas regionales: usa esta extensión para los balanceadores de carga de aplicación externos regionales y los balanceadores de carga de aplicación internos regionales para implementar lógica de enrutamiento personalizada en la región.

    2. GCPTrafficExtension para las pasarelas externas globales, externas regionales e internas: usa esta extensión para los balanceadores de carga de aplicación externos globales, los balanceadores de carga de aplicación externos regionales y los balanceadores de carga de aplicación internos regionales para manipular el tráfico, como modificar encabezados o inspeccionar cargas útiles, en varios tipos de balanceadores de carga.

Implementar un servicio de llamada de backend

Un servicio de texto destacado implementa lógica personalizada para las extensiones de servicio de Gateway en GKE. La pasarela invoca estas aplicaciones backend en función de las configuraciones GCPTrafficExtension o GCPRoutingExtension para modificar o enrutar el tráfico.

Implementa un servicio de llamadas para añadir lógica personalizada a tu pasarela. Este servicio independiente gestiona el procesamiento personalizado, como la manipulación de encabezados, las transformaciones de cargas útiles o el enrutamiento del tráfico.

Para implementar un servicio backend que pueda funcionar como texto destacado de tu pasarela, sigue estos pasos:

  1. (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 de tu servicio de llamadas, sustituye lo siguiente:

    • SECRET_NAME: el nombre secreto de tu servicio de llamada
    • path-to-cert: las rutas de archivo de tu certificado
    • path-to-key: las rutas de archivo de tu clave
  2. Para verificar que se ha añadido el secreto, ejecuta el siguiente comando:

    kubectl get secrets SECRET_NAME
    

    Sustituye SECRET_NAME por el nombre secreto de tu servicio de llamada.

    La salida debería ser similar a la siguiente:

    NAME            TYPE                DATA   AGE
    SECRET_NAME     kubernetes.io/tls   2      12s
    
  3. Define los recursos de Deployment y Service.

    Debes definir lo siguiente:

    • Despliegue: para gestionar los pods de aplicaciones que contienen la lógica personalizada de tus extensiones de servicio.
    • Servicio: para exponer los pods de la aplicación que gestiona el Deployment como servicio de red.
    1. Crea un archivo de manifiesto de ejemplo extension-service-app.yaml que tenga las siguientes definiciones: 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:main
              ports:
              - containerPort: 8080
              - containerPort: 443
              volumeMounts:
              - name: certs
                mountPath: "/etc/certs/"
                readOnly: true
              env:
              - name: POD_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: NAMESPACE
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.namespace
              - name: TLS_SERVER_CERT
                value: "/etc/certs/path-to-cert"
              - name: TLS_SERVER_PRIVKEY
                value: "/etc/certs/path-to-key"
                resources:
                requests:
                  cpu: 10m
            volumes:
            - name: certs
              secret:
                secretName: SECRET_NAME
                optional: false
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: extension-service
      spec:
        ports:
        - port: 443
          targetPort: 443
          appProtocol: HTTP2
        selector:
          app: store
      
    2. Aplica el manifiesto extension-service-app.yaml:

      kubectl apply -f extension-service-app.yaml
      
  4. Verifica tu configuración:

    1. Verifica que la aplicación se haya implementado:

      kubectl get pod --selector app=store
      

      Una vez que la aplicación empieza a ejecutarse, el resultado es similar al siguiente:

      NAME                                     READY   STATUS    RESTARTS   AGE
      extension-service-app-85f466bc9b-b5mf4   1/1     Running   0          7s
      
    2. Comprueba que el servicio se haya implementado:

      kubectl get service extension-service
      

      El resultado es similar al siguiente, que muestra un servicio para cada implementación de la tienda:

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

Configurar las extensiones de servicio

Puedes configurar un GCPRoutingExtension o un GCPTrafficExtension para personalizar el flujo de tráfico.

Configura el GCPRoutingExtension para las pasarelas regionales

Puedes redirigir el tráfico mediante un GCPRoutingExtension. Para configurar un GCPRoutingExtension, actualiza HTTPRoute para especificar las solicitudes del host service-extensions.com.

  1. Actualiza HTTPRoute. Modifica tu HTTPRoute para incluir nombres de host o rutas que activen la extensión de enrutamiento.

    1. Guarda el siguiente archivo de manifiesto de ejemplo como 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: 8080
      

      Sustituye GATEWAY_NAME por el nombre de tu pasarela.

    2. Aplica el manifiesto store-route.yaml:

      kubectl apply -f store-route.yaml
      
  2. Define el GCPRoutingExtension.

    1. Guarda la configuración de GCPRoutingExtension en el archivo de ejemplo: gcp-routing-extension.yaml

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

      Sustituye GATEWAY_NAME por el nombre de tu pasarela.

    2. Aplica el manifiesto de ejemplo a tu clúster:

      kubectl apply -f gcp-routing-extension.yaml
      
  3. Verifica la configuración del GCPRoutingExtension y su vinculación con la pasarela.

    1. Comprueba el despliegue de GCPRoutingExtension:

      kubectl describe gcproutingextension my-gateway-extension
      

      El resultado debería ser similar al 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>
      

      En la salida se muestran los detalles del GCPRoutingExtension, que se llama my-gateway-extension, en el espacio de nombres predeterminado. El resultado muestra el campo Spec, que contiene la definición de cómo debe comportarse la extensión.

    2. Verifica el enlace de la pasarela:

      1. Comprueba que el GCPRoutingExtension esté vinculado a la pasarela. Este proceso puede tardar unos minutos:

        kubectl describe gateway GATEWAY_NAME
        

        El resultado debería ser similar al 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 usa GKE para almacenar los enlaces entre la Gateway y los recursosGoogle Cloud subyacentes. La anotación networking.gke.io/lb-route-extensions confirma la vinculación de la pasarela con GCPRoutingExtension.

      2. Comprueba el estado de la extensión confirmando que GCPRoutingExtension tiene el estado Reconciled con el motivo ReconciliationSucceeded. Este comando puede tardar unos minutos.

        kubectl describe gcproutingextension my-gateway-extension
        

        El resultado debería ser similar al 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:                ReconciliationSucceeded
              Status:                True
              Type:                  Reconciled
            Controller Name:         networking.gke.io/gateway
        Events:
          Type    Reason  Age                From                   Message
          ----    ------  ----               ----                   -------
          Normal  ADD     2m31s              sc-gateway-controller  default/my-gateway-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
          Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
        

        El campo Status.Conditions muestra una condición Reconciled con Status: True y Reason: ReconciliationSucceeded.

        Verdadero y motivo: ReconciliationSucceeded. Esta información confirma que la extensión se ha aplicado correctamente.

  4. Envía tráfico a tu aplicación.

    Una vez que se hayan desplegado la pasarela, la ruta y la aplicación en tu clúster, podrás enviar tráfico a tu aplicación.

    1. Para acceder a tu aplicación, debes encontrar la dirección IP de tu Gateway.

      En el terminal, usa el siguiente comando:

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

      Sustituye GATEWAY_NAME por el nombre de tu pasarela.

      Este comando muestra la dirección IP de la pasarela. En los comandos posteriores, sustituye GATEWAY_IP_ADDRESS por la dirección IP de la salida.

    2. Prueba la actualización de la ruta. Para ello, ve a la versión serviceextensions del servicio de tienda en store.example.com/serviceextensions:

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

      El resultado debería ser similar al 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"
      }
      

Configurar el GCPTrafficExtension

Puedes usar un GCPTrafficExtension para usar funciones avanzadas de gestión del tráfico en tu Google Cloud entorno. Puedes configurar esta extensión en balanceadores de carga de aplicación externos globales, balanceadores de carga de aplicación externos regionales y balanceadores de carga de aplicación internos regionales. Puedes usar GCPTrafficExtension para implementar lógica de solicitud y respuesta personalizada, enrutamiento sofisticado, transformaciones y políticas de seguridad.

  1. Actualiza HTTPRoute. Modifica tu HTTPRoute para incluir nombres de host o rutas que activen la extensión de tráfico.

    1. Guarda el siguiente archivo de manifiesto de ejemplo como 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: 8080
      

      Sustituye GATEWAY_NAME por el nombre de tu pasarela, como internal-http, external-http o global-external-http.

    2. Aplica el manifiesto store-route.yaml a tu clúster:

      kubectl apply -f store-route.yaml
      
  2. Define el GCPTrafficExtension.

    1. Guarda la configuración de GCPTrafficExtension en el archivo de ejemplo: gcp-traffic-extension.yaml

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

      Sustituye GATEWAY_NAME por el nombre de tu pasarela, como internal-http, external-http o global-external-http.

    2. Aplica el manifiesto de ejemplo a tu clúster:

      kubectl apply -f gcp-traffic-extension.yaml
      
  3. Verifica la configuración del GCPTrafficExtension y su vinculación con la pasarela.

    1. Comprueba el despliegue de GCPTrafficExtension:

      kubectl describe gcptrafficextension my-traffic-extension
      

      El resultado debería ser 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:  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 la salida se muestran los detalles del GCPTrafficExtension llamado my-traffic-extension en el espacio de nombres predeterminado. Se muestra el campo Spec, que contiene la definición de cómo debe comportarse la extensión.

    2. Verifica el enlace de la pasarela:

      Comprueba que el GCPTrafficExtension esté vinculado a la pasarela. Este comando puede tardar unos minutos en completarse:

      kubectl describe gateway GATEWAY_NAME
      

      El resultado debería ser similar al 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 usa GKE para almacenar los enlaces entre la Gateway y los recursos subyacentes de Google Cloud . La anotación networking.gke.io/lb-traffic-extensions confirma el enlace.

    3. Comprueba el estado de la extensión:

      Confirma que el elemento GCPTrafficExtension tiene el estado Reconciled con el motivo ReconciliationSucceeded. Este comando puede tardar unos minutos en completarse.

      kubectl describe gcptrafficextension my-traffic-extension
      

      El resultado debería ser 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:                ReconciliationSucceeded
            Status:                True
            Type:                  Reconciled
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                From                   Message
        ----    ------  ----               ----                   -------
        Normal  ADD     2m31s              sc-gateway-controller  default/my-traffic-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPTrafficExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
        Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPTrafficExtension "default/my-traffic-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
      

      El campo Status.Conditions muestra una condición Reconciled con Status: True y Reason: ReconciliationSucceeded. Esta información confirma que la extensión se ha aplicado correctamente.

  4. Envía tráfico a tu aplicación.

    Una vez que se hayan desplegado la pasarela, la ruta y la aplicación en tu clúster, podrás enviar tráfico a tu aplicación.

    1. Para acceder a tu aplicación, debes encontrar la dirección IP de tu Gateway.

      En el terminal, usa el siguiente comando:

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

      Sustituye GATEWAY_NAME por el nombre de tu pasarela.

      Este comando muestra la dirección IP de la pasarela. En los comandos posteriores, sustituye GATEWAY_IP_ADDRESS por la dirección IP de la salida.

    2. Prueba la actualización de la ruta. Para ello, ve a la versión serviceextensions del servicio de tienda en store.example.com/serviceextensions:

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

      El resultado debería ser similar al 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
      }
      

Solucionar problemas de extensiones de tráfico en pasarelas

En esta sección se ofrecen consejos para solucionar problemas al configurar extensiones de tráfico en gateways.

Pasarela no encontrada

El siguiente error indica que el recurso Gateway especificado en el campo targetRefs del recurso GCPTrafficExtension o GCPRoutingExtension no existe:

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

Para resolver este problema, asegúrese de que el recurso Gateway especificado en el campo targetRefs del recurso GCPTrafficExtension o GCPRoutingExtension exista en el espacio de nombres especificado.

No se ha encontrado el servicio o el puerto de servicio

El siguiente error indica que el servicio o el puerto de servicio especificado en el campo backendRef del recurso GCPTrafficExtension o GCPRoutingExtension no existe:

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

Para resolver este problema, asegúrese de que el servicio y el puerto de servicio especificados en el campo backendRef del recurso GCPTrafficExtension o GCPRoutingExtension existen en el espacio de nombres especificado.

No hay endpoints de red en el NEG

El siguiente error indica que no hay endpoints de red en el NEG asociados al servicio 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 solucionar este problema, asegúrese de que el servicio especificado en el campo backendRef del recurso GCPTrafficExtension o GCPRoutingExtension tenga endpoints de red.

No se recibe ninguna respuesta o se recibe una respuesta con un error al enviar la solicitud

Si no recibes una respuesta o recibes una respuesta con un error al enviar una solicitud, puede que el servicio de llamada no esté funcionando correctamente.

Para solucionar este problema, comprueba si hay errores en los registros del servicio de llamada.

Código de error 404 en la carga útil de JSON

El siguiente error indica que no se ha encontrado el servicio de llamada 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 llamada esté en ejecución, de que esté escuchando en el puerto correcto y de que 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 llamada está experimentando un error de servidor interno:

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

Para solucionar este problema, consulta los registros del servicio de llamada para identificar la causa del error interno del servidor.

Siguientes pasos