Implementa puertas de enlace


En esta página, se describe cómo implementar recursos de puerta de enlace de Kubernetes para el balanceo de cargas del tráfico de entrada a un solo clúster de Google Kubernetes Engine (GKE).

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 gcloud CLI, ejecuta gcloud components update para obtener la versión más reciente.

Requisitos del controlador de la puerta de enlace de GKE

  • Para Standard, la versión 1.24 de GKE o una posterior.
  • Para Autopilot, versión 1.26 de GKE o posterior.
  • Versión 407.0.0 o posterior de Google Cloud CLI.
  • La API de la puerta de enlace solo es compatible con clústeres nativos de VPC.
  • Si usas las GatewayClasses internas, debes habilitar una subred de solo proxy.
  • El clúster debe tener el complemento HttpLoadBalancing habilitado.
  • Si usas Istio, debes actualizarlo a una de las siguientes versiones:
    • 1.15.2 o una versión posterior
    • 1.14.5 o una versión posterior
    • 1.13.9 o una versión posterior.
  • Si usas una VPC compartida, en el proyecto host, debes asignar el rol Compute Network User a la cuenta de servicio de GKE para el proyecto de servicio.

Restricciones y limitaciones

  • Las GatewayClasses de GKE admiten diferentes capacidades según el balanceador de cargas que usen. Para obtener más información sobre las diferentes funciones que admite cada GatewayClass, consulta Capacidades de GatewayClass.

  • No puedes usar un FrontendConfig o un BackendConfig para configurar una puerta de enlace. Debes usar una política.

  • GKE Gateway se comporta de manera diferente a Ingress, ya que Gateway no infiere los parámetros de verificación de estado. Si el Service no muestra 200 para las solicitudes a GET / o si tienes otras verificaciones de preparación de Pods ajustadas, debes configurar una HealthCheckPolicy para tu servicio.

  • No puedes especificar un número de puerto directamente en el nombre de host (por ejemplo, web.example.com:80) para el enrutamiento de tráfico.

  • Puedes ver los recursos del balanceador de cargas que GKE crea para las puertas de enlace de la consola de Google Cloud, pero estos recursos no hacen referencia al clúster de puerta de enlace o GKE al que están conectados.

  • No puedes generar de forma automática un certificado SSL administrado por Google con las puertas de enlace, pero puedes crear y hacer referencia a un certificado SSL administrado por Google de forma manual. Para obtener más información, consulta Protege una puerta de enlace.

  • HTTPRoute es el único tipo de ruta compatible. No se admiten TCPRoutes, UDPRoutes ni TLSRoutes. Para ver una lista de los campos que admite GKE Gateway Controller, consulta Capacidades de GatewayClass.

  • Los encabezados de solicitud y respuesta personalizados con puertas de enlace o redireccionamientos de ruta de acceso y reescrituras de URL con Gateway solo están disponibles en GKE versión 1.27 o posterior.

  • Cuando se configuran encabezados de respuesta y solicitud personalizados HTTPRoute, no se admiten las siguientes variables de Google Cloud:

    • cdn_cache_id (Cloud CDN no es compatible con GKE Gateway)
    • cdn_cache_status (Cloud CDN no es compatible con GKE Gateway)
    • origin_request_header (Las políticas CORS no son compatibles con la puerta de enlace de GKE)
  • GKE Gateway no es compatible con la función de balanceo de cargas de Cloud CDN.

  • No se admiten los encabezados personalizados de TLS mutua (mTLS con GKE Gateway)

  • Las limitaciones del balanceador de cargas clásico de la aplicación de Google Cloud se aplican a la puerta de enlace de GKE con una limitación adicional:

    • No puedes configurar un encabezado de respuesta del host personalizado en el servicio de backend.
  • Los redireccionamientos y las reescrituras de las URL son mutuamente excluyentes, no puedes usar ambos filtros al mismo tiempo en las mismas reglas.

  • El redireccionamiento del tráfico a un puerto diferente no es compatible con Cloud Load Balancing. Para ver la lista de los campos que admite GKE Gateway Controller, consulta Capacidades de GatewayClass.

  • Gateway de GKE no admite comodines, expresiones regulares y URLs dinámicas.

  • Si especificas una puerta de enlace con una clase de puerta de enlace externa regional, el controlador aprovisiona una dirección IP interna en lugar de la dirección externa. Para obtener información sobre cómo usar una dirección con nombre con el balanceador de cargas de aplicaciones externo regional, consulta Implementa una puerta de enlace externa regional.

  • La puerta de enlace usa NEG independientes para aprovisionar grupos de extremos de red. Para garantizar que el controlador de la puerta de enlace concilie de forma correcta la configuración del balanceador de cargas, no puedes modificar la anotación cloud.google.com/neg para un Service que forma parte de la puerta de enlace.

  • La puerta de enlace de GKE no admite la referencia a un servicio que también hace referencia a un Ingress de GKE.

  • Cuando se configura una Gateway para aprovisionar una dirección IP, no se admite cambiar la Gateway.spec.gatewayClass. Para asegurarte de que el controlador de la puerta de enlace concilie de forma correcta el balanceador de cargas, borra la puerta de enlace existente y vuelve a implementar el manifiesto con el valor gatewayClass actualizado.

  • No se admite la anotación networking.gke.io/app-protocols. En su lugar, usa el campo appProtocol para lograr el mismo resultado.

Habilita la API de la puerta de enlace en tu clúster

Antes de usar los recursos de la puerta de enlace en GKE, tu clúster debe tener habilitada la API de la puerta de enlace.

Crea un clúster nuevo con la API de la puerta de enlace habilitada

GKE admite la API de Gateway en clústeres de Autopilot a partir de la versión 1.26 de GKE. Si creas clústeres de Autopilot nuevos en GKE 1.26 y versiones posteriores, la API de Gateway se habilita de forma predeterminada. Para los clústeres existentes en la versión 1.25 de GKE y versiones anteriores, la API Gateway está inhabilitada de forma predeterminada.

Autopilot

Crea un clúster de GKE Autopilot nuevo con la API de puerta de enlace habilitada:

  gcloud container clusters create-auto CLUSTER_NAME \
      --location=CLUSTER_LOCATION \
      --release-channel=RELEASE_CHANNEL \
      --cluster-version=VERSION

Reemplaza lo siguiente:

  • CLUSTER_NAME: el nombre del clúster
  • CLUSTER_LOCATION: Es la región o zona de Compute Engine para el clúster nuevo.
  • RELEASE_CHANNEL: Es el nombre del canal de versiones.
  • VERSION: la versión de GKE, que debe ser 1.26 o posterior. También puedes usar la marca --release-channel para seleccionar un canal de versiones. El canal de versiones debe tener una versión predeterminada 1.26 o posterior.

Standard

Con GKE Standard, la API de Gateway se controla mediante la marca --gateway-api. Puedes usar el valor estándar cuando está habilitado o inhabilitado cuando lo inhabilitas.

Crea un clúster de GKE nativo de la VPC nueva con la API de la puerta de enlace habilitada:

  gcloud container clusters create CLUSTER_NAME \
    --gateway-api=standard \
    --cluster-version=VERSION \
    --location=CLUSTER_LOCATION

Reemplaza lo siguiente:

  • RELEASE_CHANNEL: Es el nombre del canal de versiones.
  • CLUSTER_NAME: el nombre del clúster
  • VERSION: la versión de GKE, que debe ser 1.24 o posterior. También puedes usar la marca --release-channel para seleccionar un canal de versiones. El canal de versiones debe tener una versión predeterminada 1.24 o posterior.
  • CLUSTER_LOCATION: es la región o zona de Compute Engine para el clúster nuevo.

La marca --gateway-api=standard indica a GKE que instale las CRD v1beta1 con el clúster.

Habilita la API de la puerta de enlace en un clúster existente

Asegúrate de que la versión de tu clúster de Autopilot sea 1.26 o posterior y la versión de tu clúster Standard sea 1.24 o posterior.

Para habilitar la API de Gateway en un clúster de GKE existente (Autopilot o Standard), usa lo siguiente:

gcloud container clusters update CLUSTER_NAME \
    --location=CLUSTER_LOCATION\
    --gateway-api=standard

Reemplaza lo siguiente:

La marca --gateway-api=standard indica a GKE que instale las CRD v1beta1 con el clúster.

Verifica tu clúster

Después de crear o actualizar tu clúster, GKE Gateway Controller instala las GatewayClasses de forma automática. Es posible que el controlador tarde unos minutos en reconocer las CRDs y en instalar las GatewayClasses.

  1. Confirma que la API de Gateway esté habilitada en el plano de control de GKE:

    gcloud container clusters describe CLUSTER_NAME \
      --location=CLUSTER_LOCATION \
      --format json
    

    El resultado es similar al siguiente. Si este resultado está vacío, vuelve a ejecutar el comando de actualización del clúster.

    "networkConfig": {
      ...
      "gatewayApiConfig": {
        "channel": "CHANNEL_STANDARD"
      },
      ...
    },
    
  2. Confirma que las GatewayClasses estén instaladas en el clúster:

    kubectl get gatewayclass
    

    El resultado es similar a este:

    NAME                             CONTROLLER                  ACCEPTED   AGE
    gke-l7-global-external-managed   networking.gke.io/gateway   True       16h
    gke-l7-regional-external-managed networking.gke.io/gateway   True       16h
    gke-l7-gxlb                      networking.gke.io/gateway   True       16h
    gke-l7-rilb                      networking.gke.io/gateway   True       16h
    

Para comprender las capacidades de cada GatewayClass, consulta Capacidades de GatewayClass.

Implementa una Gateway interna

Una Gateway interna expone aplicaciones a las que solo se puede acceder desde la VPC o las redes conectadas a la VPC.

Implementa una puerta de enlace interna regional

En el siguiente ejemplo, se muestra cómo implementar una puerta de enlace interna regional que permite una comunicación eficiente y segura entre servicios dentro de una región geográfica específica.

Configura una subred de solo proxy

Debes configurar una subred de solo proxy antes de crear una puerta de enlace que use un balanceador de cargas de aplicaciones interno. Cada región de una VPC en la que uses balanceadores de cargas de aplicaciones internos debe tener una subred de solo proxy. En esta subred, se proporcionan direcciones IP internas a los proxies del balanceador de cargas.

  1. Crea una subred de solo proxy:

    gcloud compute networks subnets create SUBNET_NAME \
        --purpose=REGIONAL_MANAGED_PROXY \
        --role=ACTIVE \
        --region=COMPUTE_REGION \
        --network=VPC_NETWORK_NAME \
        --range=CIDR_RANGE
    

    Reemplaza lo siguiente:

    • SUBNET_NAME: El nombre de la subred de solo proxy
    • COMPUTE_REGION: La región de la subred de solo proxy
    • VPC_NETWORK_NAME: El nombre de la red de VPC que contiene la subred
    • CIDR_RANGE: El rango de direcciones IP principal de la subred Debes usar una máscara de subred de una longitud máxima de /26 para que al menos 64 direcciones IP estén disponibles para los proxies de la región. La máscara de subred recomendada es /23.
  2. Verifica tu subred de solo proxy:

    gcloud compute networks subnets describe SUBNET_NAME \
        --region=COMPUTE_REGION
    

    El resultado es similar a este:

    ...
    gatewayAddress: 10.1.1.1
    ipCidrRange: 10.1.1.0/24
    kind: compute#subnetwork
    name: proxy-subnet
    network: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/networks/default
    privateIpGoogleAccess: false
    privateIpv6GoogleAccess: DISABLE_GOOGLE_ACCESS
    purpose: REGIONAL_MANAGED_PROXY
    region: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION
    role: ACTIVE
    selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION/subnetworks/proxy-subnet
    state: READY
    

Crea una Gateway

Un recurso de puerta de enlace representa un plano de datos que enruta el tráfico en Kubernetes. Una puerta de enlace puede representar muchos tipos diferentes de balanceo de cargas y enrutamiento según la GatewayClass de la que deriva. Si deseas obtener más información sobre el recurso de puerta de enlace, consulta la descripción del recurso de puerta de enlace o la especificación de la API.

En este caso, el administrador del clúster de GKE quiere crear una puerta de enlace que varios equipos puedan usar para exponer sus aplicaciones de forma interna. El administrador implementa la Gateway, y los equipos de aplicaciones implementan sus rutas de forma independiente y las conectan a esta Gateway.

  1. Guarda el siguiente manifiesto de Gateway en un archivo llamado gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-http
    spec:
      gatewayClassName: gke-l7-rilb
      listeners:
      - name: http
        protocol: HTTP
        port: 80
    

    Este manifiesto incluye los siguientes campos:

    • gatewayClassName: gke-l7-rilb: especifica la GatewayClass de la que deriva esta puerta de enlace. gke-l7-rilb corresponde al balanceador de cargas de aplicaciones interno.
    • port: 80: especifica que la puerta de enlace expone solo el puerto 80 para escuchar el tráfico HTTP.
  2. Implementa la puerta de enlace en tu clúster:

    kubectl apply -f gateway.yaml
    
  3. Verifica que la puerta de enlace se haya implementado de forma correcta. La implementación de todos sus recursos puede llevar unos minutos.

    kubectl describe gateways.gateway.networking.k8s.io internal-http
    

    El resultado es similar a este:

    Name:         internal-http
    Namespace:    default
    Spec:
      Gateway Class Name:  gke-l7-rilb
      Listeners:
        Allowed Routes:
          Kinds:
            Group:  gateway.networking.k8s.io
            Kind:   HTTPRoute
          Namespaces:
            From:  Same
        Name:      http
        Port:      80
        Protocol:  HTTP
    Status:
      Addresses:
        Type:   IPAddress
        Value:  192.168.1.14
      Conditions:
        Last Transition Time:  1970-01-01T00:00:00Z
        Message:               Waiting for controller
        Reason:                NotReconciled
        Status:                False
        Type:                  Scheduled
    Events:
      Type    Reason  Age                From                       Message
      ----    ------  ----               ----                       -------
      Normal  ADD     92s                networking.gke.io/gateway  test/internal-http
      Normal  UPDATE  45s (x3 over 91s)  networking.gke.io/gateway  test/internal-http
      Normal  SYNC    45s                networking.gke.io/gateway  SYNC on test/internal-http was a success
    

    En este punto, hay una puerta de enlace implementada en tu clúster que aprovisionó un balanceador de cargas y una dirección IP. Sin embargo, la puerta de enlace no tiene rutas y, por lo tanto, no sabe cómo debe enviar tráfico a los backends. Sin rutas, todo el tráfico se dirige a un backend predeterminado, que muestra un HTTP 404. A continuación, implementarás una aplicación y rutas, que le indican a la puerta de enlace cómo llegar a los backends de aplicaciones.

Implementa las aplicaciones de demostración

Los equipos de aplicaciones pueden implementar sus aplicaciones y rutas independientemente de la implementación de puertas de enlace. En algunos casos, es posible que el equipo de aplicaciones también desee poseer la puerta de enlace y, luego, implementarla como un recurso dedicado a sus aplicaciones. Consulta Vinculación de rutas para ver diferentes modelos de propiedad de puertas de enlace y rutas. En este ejemplo, el equipo de la tienda implementa su aplicación y una HTTPRouter adjunta para exponer su app a través de la puerta de enlace internal-http creada en la sección anterior.

El recurso HTTPRoute tiene muchos campos configurables para la coincidencia de tráfico. Para ver una explicación de los campos de HTTPRoute, consulta la especificación de API.

  1. Implementa la aplicación de almacenamiento (implementaciones store-v1, store-v2 y store-german) en su clúster:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
    

    Esto crea tres implementaciones y tres servicios, llamados store-v1, store-v2 y store-german

  2. Confirma que la aplicación se haya implementado correctamente:

    kubectl get pod
    

    El resultado es similar al siguiente después de que se ejecuta la aplicación:

    NAME                        READY   STATUS    RESTARTS   AGE
    store-german-66dcb75977-5gr2n   1/1     Running   0          38s
    store-v1-65b47557df-jkjbm       1/1     Running   0          14m
    store-v2-6856f59f7f-sq889       1/1     Running   0          14m
    
  3. Valida que se hayan implementado los objetos Service:

    kubectl get service
    

    El resultado muestra un objeto Service para cada implementación de la tienda:

    NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    store-german   ClusterIP   10.48.3.183   <none>        8080/TCP   4s
    store-v1       ClusterIP   10.48.2.224   <none>        8080/TCP   5s
    store-v2       ClusterIP   10.48.4.48    <none>        8080/TCP   5s
    

Implementa la HTTPRoute

Los recursos de ruta definen reglas específicas del protocolo para asignar tráfico de una puerta de enlace a backends de Kubernetes. El recurso HTTPRoute realiza coincidencias y filtros de tráfico HTTP y HTTPS, y es compatible con todas las GatewayClasses gke-l7.

En esta sección, implementarás un HTTPRoute, que programa el Gateway con las reglas de enrutamiento necesarias para llegar a la aplicación de almacenamiento.

  1. Guarda el siguiente manifiesto de HTTPRoute en un archivo llamado store-route.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.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
    
  2. Implementa la HTTProute en tu clúster:

    kubectl apply -f store-route.yaml
    

    La HTTPRoute store está vinculada a la puerta de enlace internal-http mediante la propiedad parentRefs. Estas reglas de enrutamiento se configuran en el balanceador de cargas subyacente como se muestra en este diagrama:

    Las reglas de enrutamiento configuradas por la tienda de HTTPRoute

    Estas reglas de enrutamiento procesan el tráfico HTTP de la siguiente manera:

    • El tráfico a store.example.com/de va al objeto Service store-german.
    • El tráfico a store.example.com con el encabezado HTTP "env: canary" va al objeto Service store-v2.
    • El tráfico restante a store.example.com va al objeto Service store-v1.
  3. Verifica que se haya implementado la HTTPRoute:

    kubectl describe httproute store
    

    El resultado es similar a este:

    Name:         store
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  gateway.networking.k8s.io/v1beta1
    Kind:         HTTPRoute
    <...>
    Spec:
      Hostnames:
        store.example.com
      Parent Refs:
        Group:  gateway.networking.k8s.io
        Kind:   Gateway
        Name:   internal-http
      Rules:
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v1
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v2
          Port:    8080
          Weight:  1
        Matches:
          Headers:
            Name:   env
            Type:   Exact
            Value:  canary
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-german
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /de
    Status:
      Parents:
        Conditions:
          Last Transition Time:  2022-11-01T04:18:52Z
          Message:
          Reason:                Accepted
          Status:                True
          Type:                  Accepted
          Last Transition Time:  2022-11-01T04:18:52Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   internal-http
    Events:
      Type    Reason  Age                From                   Message
      ----    ------  ----               ----                   -------
      Normal  ADD     24m                sc-gateway-controller  default/store
      Normal  SYNC    16m (x4 over 23m)  sc-gateway-controller  Bind of HTTPRoute "default/store" to ParentRef {Group:       gateway.networking.k8s.io",
      <...>
    
  4. Verifica que la HTTPRoute esté vinculada a la puerta de enlace:

    kubectl describe gateway
    

    El resultado es similar a este:

    Name:         internal-http
    Namespace:    default
    Labels:       <none>
    <...>
    Status:
      Addresses:
        Type:   IPAddress
        Value:  10.128.15.203
      Conditions:
        Last Transition Time:  2022-11-01T03:47:01Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2022-11-01T03:47:01Z
        Message:
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2022-11-01T03:47:01Z
          Message:
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    http
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
          <...>
    

Envía tráfico a tu aplicación

Ahora que la puerta de enlace, la ruta y la aplicación están implementadas en el clúster, puedes pasar el tráfico a la aplicación.

  1. Recupera la dirección IP de la puerta de enlace para que puedas enviar tráfico a tu aplicación:

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

    El resultado es una dirección IP.

  2. Envía tráfico a esta dirección IP desde la shell en una instancia de máquina virtual (VM) con conectividad al clúster. Puedes crear una VM para este fin. Esto es necesario porque la puerta de enlace tiene una dirección IP interna y solo se puede acceder desde tu red de VPC. Debido a que internal-http es un balanceador de cargas regional, la shell del cliente debe estar dentro de la misma región que el clúster de GKE.

    Debido a que no eres propietario del nombre de host example.com, configura el encabezado del host de forma manual para que se pueda observar el enrutamiento de tráfico. Primero, intenta solicitar store.example.com:

    curl -H "host: store.example.com" VIP
    

    Reemplaza VIP por la dirección IP del paso anterior.

    El resultado de la app de demostración muestra información sobre la ubicación en la que se ejecuta la app:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v1-84b47c7f58-pmgmk",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:31:17",
      "zone": "ZONE_NAME"
    }
    
  3. Para probar la coincidencia de ruta de acceso, ve a la versión en alemán del servicio de almacenamiento en store.example.com/de:

    curl -H "host: store.example.com" VIP/de
    

    El resultado confirma que un pod store-german entregó la solicitud:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "Gutentag!", 
      "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal",
      "pod_name": "store-german-5cb6474c55-lq5pl", 
      "pod_name_emoji": "🧞‍♀",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:35:37",
      "zone": "ZONE_NAME"
    }
    
  4. Por último, usa el encabezado HTTP env: canary para enviar tráfico a la versión canary del servicio de almacenamiento:

    curl -H "host: store.example.com" -H "env: canary " VIP
    

    El resultado confirma que un pod store-v2 entregó la solicitud:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v2", 
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v2-5788476cbd-s9thb", 
      "pod_name_emoji": "🦰",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:38:26",
      "zone": "ZONE_NAME"
    }
    

Implementa una puerta de enlace externa regional

En el siguiente ejemplo, se muestra cómo exponer una aplicación de almacenamiento con varios certificados adjuntos a la puerta de enlace externa regional mediante certificados autoadministrados y una HTTPRoute.

Crea una subred de proxy para la puerta de enlace regional

Debes configurar una subred de solo proxy antes de crear una puerta de enlace que use un balanceador de cargas de aplicaciones externo regional. Cada región de una VPC en la que usas el balanceador de cargas de aplicaciones externo regional debe tener una subred external_managed_proxy. En esta subred, se proporcionan direcciones IP internas a los proxies del balanceador de cargas.

Crea un certificado para proteger el tráfico de tus clientes

Puedes usar un certificado emitido y validado por la autoridad certificadora (CA) o crear un certificado autofirmado. Para obtener más información sobre cómo crear un certificado, consulta Almacena un certificado en un Secret de Kubernetes.

Crea una puerta de enlace HTTP(S) regional externa

  1. Crea una dirección IP estática regional para el balanceador de cargas externo.

    gcloud compute addresses create IP_ADDRESS_NAME \
      --region=COMPUTE_REGION \
      --network-tier=STANDARD
    

    Reemplaza lo siguiente:

    • IP_ADDRESS_NAME: el nombre de la dirección IP estática nueva
    • COMPUTE_REGION: La región de Compute Engine en la que se ejecuta tu clúster
  2. Crea una puerta de enlace del balanceador de cargas de aplicaciones externo regional con un certificado autoadministrado de la siguiente manera y guarda el manifiesto como regional-gateway.yaml:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1beta1
      metadata:
        name: external-regional-http
      spec:
        gatewayClassName: gke-l7-regional-external-managed
        listeners:
        - name: https
          protocol: HTTPS
          port: 443
          tls:
            mode: Terminate
            certificateRefs:
            - name: store-example-com
        addresses:
        - type: NamedAddress
          value: IP_ADDRESS_NAME
    
  3. Aplica el manifiesto regional-gateway:

      kubectl apply -f regional-gateway.yaml
    
  4. Verifica la configuración.

      kubectl get gateway
    

    El resultado es similar a este:

    NAME            CLASS                              ADDRESS         READY   AGE
    external-http   gke-l7-regional-external-managed   35.118.32.224   True    49s
    

    Para obtener más detalles, usa un comando describe:

    kubectl describe gateway
    

    El resultado es similar a este:

    Name:         external-regional-http
    Namespace:    default
    Labels:       <none>
    ...
    Spec:
      Gateway Class Name:  gke-l7-regional-external-managed
      Listeners:
        Allowed Routes:
          Namespaces:
            From:  Same
        Name:      https
        Port:      443
        Protocol:  HTTPS
        Tls:
          Certificate Refs:
            Group:
            Kind:   Secret
            Name:   store-example-com
          Mode:     Terminate
      ...
    

Implementa la aplicación de demostración

Puedes implementar tus aplicaciones y rutas sin importar la implementación de las puertas de entrada.

Crea una HTTPRoute

Debes crear una HTTPRoute para hacer coincidir el tráfico HTTP y HTTPS y filtrarlo.

Envía tráfico a tu aplicación

Después de implementar la aplicación y crear HTTPRoutes, puedes pasar el tráfico a la aplicación.

Usa puertas de enlace compartidas

Las API de Gateway usan recursos separados, de puerta de enlace y de ruta, para implementar balanceadores de cargas y reglas de enrutamiento. Esto difiere de Ingress, que combina todo en un recurso. Cuando se divide la responsabilidad entre los recursos, la puerta de enlace permite que el balanceador de cargas y sus reglas de enrutamiento se implementen por separado y que diferentes usuarios o equipos lo implementen. Esto permite que las Gateways se conviertan en Gateways compartidas que se conectan a muchas rutas diferentes que pueden ser de total propiedad y administración de equipos independientes, incluso en diferentes espacios de nombres.

Implementa rutas en una puerta de enlace compartida

Este ejemplo se basa en la puerta de enlace internal-http implementada en Implementa una puerta de enlace interna.

En este ejemplo, el equipo del sitio implementa su aplicación, Services y una HTTPRoute para hacer coincidir el tráfico de la puerta de enlace con esos Services.

  1. Implementa la aplicación de ejemplo

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/site.yaml
    
  2. Guarda el siguiente manifiesto como un archivo llamado site-route-internal.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: site-internal
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "site.example.com"
      rules:
      - backendRefs:
        - name: site-v1
          port: 8080
    

    En este manifiesto, se describe una HTTPRouter que coincide con todo el tráfico para site.example.com y lo enruta al Service site-v1.

  3. Aplica el manifiesto al clúster:

    kubectl apply -f site-route-internal.yaml
    
  4. Verifica que la HTTPRoute esté vinculada a la puerta de enlace:

    kubectl describe httproute.gateway.networking.k8s.io site-internal
    

    El resultado es similar a este:

    Status:
      Parents:
        Conditions:
          Last Transition Time:  2023-01-09T15:05:43Z
          Message:
          Reason:                Accepted
          Status:                True
          Type:                  Accepted
          Last Transition Time:  2023-01-09T15:05:43Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   internal-http
          ...
    

    Si la condición Accepted para la puerta de enlace es True, la HTTPRoute se vinculó correctamente a la puerta de enlace. Para obtener más información sobre el campo Estado, consulta Estado de la ruta.

  5. Verifica que el tráfico a la puerta de enlace se enrute de forma correcta:

    curl -H "host: site.example.com" GATEWAY_IP_ADDRESS
    curl -H "host: store.example.com" GATEWAY_IP_ADDRESS
    

    Reemplaza GATEWAY_IP_ADDRESS por la dirección IP de la puerta de enlace.

    Debes usar una máquina virtual (VM) en la misma VPC que la puerta de enlace.

    El resultado es similar a este:

    {
      "cluster_name": "CLUSTER_NAME",
      "host_header": "site.example.com",
      "metadata": "site-v1",
      "pod_name": "site-v1-5d64fc4d7d-fz6f6",
      "pod_name_emoji": "👩🏼‍🍳",
      "project_id": "PROJECT_ID",
      "timestamp": "2022-11-02T19:07:01",
      "zone": "ZONE_NAME"
    }
    ...
    {
      "cluster_name": "CLUSTER_NAME",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "pod_name": "store-v1-6d8d58d78-vz8pn",
      "pod_name_emoji": "🧝🏻‍♂️",
      "project_id": "PROJECT_ID",
      "timestamp": "2022-11-02T19:07:01",
      "zone": "ZONE_NAME"
    }
    

Configura el backend predeterminado de Gateway

Todas las GatewayClasses de gke-l7-* muestran HTTP 404 en tráfico sin igual. Puedes configurar el backend predeterminado con una Route predeterminada explícita que envíe tráfico sin coincidencia a un servicio proporcionado por el usuario.

La siguiente HTTPRoute es un ejemplo de cómo personalizar el backend predeterminado. Si aplicas una HTTPRoute similar a la siguiente, tiene prioridad sobre el backend predeterminado implícito:

kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: custom-default-backend
spec:
  parentRefs:
  - kind: Gateway
    name: my-internal-gateway
  rules:
  - backendRefs:
    - name: my-custom-default-backend-service
      port: 8080

Esta HTTPRoute coincide con todo el tráfico de una puerta de enlace en particular. Solo puedes tener una de esas reglas para cada Gateway; de lo contrario, se aplican las reglas y se aplica el orden de prioridad.

Puedes usar un backend predeterminado para evitar que alguien cree un backend de ruta predeterminado que enrute todo el tráfico de Gateway. Una HTTPRoute explícita siempre tiene prioridad sobre las HTTPRoutes nuevas con reglas de enrutamiento en conflicto.

Configura una dirección IP estática para una puerta de enlace

Cada puerta de enlace tiene una dirección IP que usa para escuchar el tráfico. Si no especificas una dirección IP en la puerta de enlace, el controlador de puerta de enlace proporcionará una dirección IP de forma automática. También puedes crear una dirección IP estática para que la dirección IP exista de forma independiente del ciclo de vida de la puerta de enlace.

Después de implementar una puerta de enlace, su dirección IP se muestra en el campo de estado:

kind: Gateway
...
status:
  addresses:
    - value: 10.15.32.3

Según la GatewayClass, la dirección IP se asigna desde las siguientes subredes:

GatewayClasses Grupo de direcciones IP predeterminado
  • gke-l7-rilb
  • Direcciones IP privadas regionales del rango de direcciones IPv4/IPv6 del nodo principal
  • gke-l7-regional-external-managed
  • Direcciones IP públicas regionales de los rangos de IPv4/IPv6 externos regionales de Google
  • gke-l7-global-external-managed
  • gke-l7-global-external-managed-mc
  • gke-l7-gxlb
  • gke-l7-gxlb-mc
  • Direcciones IP públicas globales de los rangos IPv4/IPv6 externos globales de Google

    El campo addresses.NamedAddress te permite especificar una dirección IP independiente de la puerta de enlace. Puedes crear un recurso de dirección IP estática antes de la implementación de la puerta de enlace y de que la NamedAddress haga referencia al recurso. Puedes volver a usar la dirección IP estática incluso si se borra la puerta de enlace.

    Usa una dirección IP con nombre

    Para configurar una dirección IP, especifica una NamedAddress. Debes aprovisionar una dirección IP estática antes de crear una puerta de enlace.

    1. Crea un recurso de dirección IP estática:

      gcloud compute addresses create IP_ADDRESS_NAME \
          --purpose=SHARED_LOADBALANCER_VIP \
          --region=COMPUTE_REGION \
          --subnet=SUBNET \
          --project=PROJECT_ID
      

      Reemplaza lo siguiente:

      • IP_ADDRESS_NAME: el nombre de la dirección IP estática nueva
      • COMPUTE_REGION: para las puertas de enlace regionales, es la región de Compute Engine en la que se ejecuta el clúster.
      • SUBNET: la subred de la dirección IP.
      • PROJECT_ID: es el proyecto en el que se ejecuta tu clúster de GKE.
    2. Guarda el siguiente manifiesto como un archivo llamado named-ip-gateway.yaml:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1beta1
      metadata:
        name: internal-http
      spec:
        gatewayClassName: gke-l7-rilb
        listeners:
        - name: http
          protocol: HTTP
          port: 80
        addresses:
        - type: NamedAddress
          value: IP_ADDRESS_NAME
      

      En este manifiesto, se describe una puerta de enlace que hace referencia a la dirección IP con nombre.

    3. Aplica el manifiesto al clúster:

      kubectl apply -f named-ip-gateway.yaml
      
    4. Verifica la dirección IP de la puerta de enlace:

      kubectl describe gateway internal-http
      

      El resultado es similar a este:

      Name:         internal-http
      Namespace:    default
      Labels:       <none>
      ...
      Spec:
        Addresses:
          Type:              NamedAddress
          Value:             IP_ADDRESS_NAME
        Gateway Class Name:  gke-l7-rilb
        Listeners:
          Allowed Routes:
            Namespaces:
              From:  Same
          Name:      http
          Port:      80
          Protocol:  HTTP
      Status:
        Addresses:
          Type:   IPAddress
          Value:  10.15.32.103
      

    Configurar redireccionamientos de HTTP a HTTPS

    Cloud Load Balancing ofrece funcionalidad de redireccionamiento de HTTP a HTTPS. Un balanceador de cargas de aplicaciones externo redirecciona las solicitudes HTTP sin encriptar a un balanceador de cargas HTTPS que use la misma dirección IP. Cuando creas una puerta de enlace con redireccionamientos HTTP a HTTPS habilitados, automáticamente se crean ambos balanceadores de cargas. Las solicitudes a la dirección IP externa de la puerta de enlace en el puerto 80 se redireccionan de manera automática a la misma dirección IP externa en el puerto 443.

    De forma predeterminada, los redireccionamientos HTTP a HTTPS no se definen en la puerta de enlace.

    Para redireccionar el tráfico HTTP a HTTPS, configura una puerta de enlace que controle el tráfico HTTP y HTTPS. Si inhabilitas HTTP o HTTPS, la puerta de enlace no redirecciona el tráfico.

    En los siguientes ejemplos, se muestra cómo puedes usar el redireccionamiento de HTTP a HTTPS como un medio para garantizar que el tráfico de los clientes que se dirigen a tus aplicaciones web siempre se redireccione a una página segura.

    Configura redireccionamientos de ruta y reescrituras de URL

    Los redireccionamientos de ruta de acceso implican redireccionar una solicitud entrante de una ruta de URL a otra. Los redireccionamientos de ruta de acceso te permiten cambiar la estructura de la URL cuando necesitas manejar URL desactualizadas u obsoletas.

    Las reescrituras de URL ayudan a modificar la URL entrante antes de procesarla en el servidor. Te permite cambiar la estructura o el formato de la URL sin cambiar realmente el contenido subyacente o la estructura del archivo. La reescritura de URL es beneficiosa para crear URL fáciles de usar y optimizar con SEO y que además son fáciles de recordar y comprender. De forma predeterminada, los redireccionamientos de ruta y las reescrituras de URL no están configurados. Debes configurar de forma explícita esos redireccionamientos o reescrituras mediante un filtro en tu HTTPRoute.

    GKE Gateway admite redireccionamientos de rutas de acceso y reescrituras de URL. Para obtener más información, consulta la página Redireccionamientos y reescrituras de rutas de acceso HTTP.

    Configura redireccionamientos de rutas de acceso

    Puedes configurar redireccionamientos de ruta de acceso para reemplazar toda la ruta de acceso o solo un prefijo en la URL.

    Reemplazar toda la ruta de acceso

    1. Para reemplazar una ruta de acceso completa, configura un filtro en una HTTPRoute que reemplace cualquier URL que contenga el prefijo /any-path en la ruta de URL por el valor estricto /new-path.

    2. Crea un manifiesto HTTPRoute de la siguiente manera y asígnale el nombre store.yaml:

        apiVersion: gateway.networking.k8s.io/v1beta1
        kind: HTTPRoute
        metadata:
          name: store
        spec:
          parentRefs:
            - kind: Gateway
              name: external-http
          hostnames:
          - store.example.com
          rules:
          - matches:
            - path:
                type: PathPrefix
                value: /any-path
            filters:
            - type: RequestRedirect
              requestRedirect:
                path:
                  type: ReplaceFullPath
                  replaceFullPath: /new-path
                statusCode: 302
      

      Por ejemplo, este manifiesto establece una regla de enrutamiento para una HTTPRoute de la siguiente manera: cualquier ruta a la URL https://store.example.com/any-path/... se debería redireccionar a una ubicación nueva, https://store.example.com/new-path/ (estricta).

    3. Aplica el manifiesto

      kubectl apply -f store.yaml
      

    Esta regla de enrutamiento sigue una regla de redireccionamiento estricta, lo que significa que el navegador no intenta almacenar en caché el redireccionamiento. En su lugar, redirecciona a la versión más reciente.

    Reemplaza solo un prefijo

    1. Para reemplazar solo un prefijo, configura un filtro en una HTTPRoute que reemplace cualquier URL que contenga el prefijo /any-prefix en la ruta de URL por el valor estricto /new-prefix.

    2. Crea un manifiesto HTTPRoute de la siguiente manera y asígnale el nombre store.yaml:

      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        parentRefs:
          - kind: Gateway
            name: external-http
        hostnames:
        - store.example.com
        rules:
        - matches:
            - path:
                type: PathPrefix
                value: /any-prefix
          filters:
          - type: RequestRedirect
            requestRedirect:
              path:
                type: ReplacePrefixMatch
                replacePrefixMatch: /new-prefix
              statusCode: 302
      

      Por ejemplo, este manifiesto establece una regla de enrutamiento para una HTTPRoute de la siguiente manera: cualquier ruta a la URL https://store.example.com/any-path/v1/... se debe redireccionar a una ubicación nueva, https://store.example.com/new-path/v1/... (solamente).

    3. Aplica el manifiesto

        kubectl apply -f store.yaml
      

    Esta regla de enrutamiento sigue la única regla de redireccionamiento, lo que garantiza que el navegador siempre te redireccione a la misma página deseada.

    Configura reescrituras de URL

    Configura las reescrituras de URL para cambiar la forma en que se muestra una URL a los usuarios. Puedes usar las reescrituras de URL para que las URL sean más fáciles de usar, mejorar la SEO o redireccionar a los usuarios a una página nueva.

    Vuelve a escribir todo el nombre de host

    Para reescribir todo el nombre de host, ejecuta el siguiente comando:

    1. Configura un filtro en una HTTPRoute que le indique a la puerta de enlace que reemplace la información de Host en el encabezado de la solicitud de www.example.com a store.example.com antes de reenviar la solicitud al servicio de backend.

    2. Crea un manifiesto HTTPRoute de la siguiente manera y asígnale el nombre www.yaml:

        apiVersion: gateway.networking.k8s.io/v1beta1
        kind: HTTPRoute
        metadata:
          name: www
        spec:
          parentRefs:
            - kind: Gateway
              name: external-http
          hostnames:
          - www.example.com
          rules:
          - filters:
            - type: URLRewrite
              urlRewrite:
                hostname: store.example.com
            backendRefs:
            - name: store-v1
              port: 8080
      

      Por ejemplo, con la configuración anterior, cualquier solicitud a https://www.example.com se reenvía al servicio de backend con el encabezado Host: store.example.com, en lugar de Host: www.example.com.

    3. Aplica el manifiesto

        kubectl apply -f www.yaml
      

    Vuelve a escribir con modificadores de ruta

    Puedes combinar las reescrituras con modificadores de ruta para proporcionar modificaciones avanzadas de URL y de ruta de acceso antes de retransmitir la solicitud al servicio de backend.

    Para volver a escribir con modificadores de ruta, haz lo siguiente:

    1. Configura un filtro en una HTTPRoute que le indique a la puerta de enlace que reemplace la información de “Host” en el encabezado de la solicitud de www.example.com a store.example.com y reemplace el valor /store por / antes de reenviar la solicitud al servicio de backend.

    2. Crea un manifiesto HTTPRoute de la siguiente manera y asígnale el nombre www.yaml:

        apiVersion: gateway.networking.k8s.io/v1beta1
        kind: HTTPRoute
        metadata:
          name: www
        spec:
          parentRefs:
            - kind: Gateway
              name: external-http
          hostnames:
          - www.example.com
          rules:
          - matches:
            - path:
                type: PathPrefix
                value: /store
            filters:
            - type: URLRewrite
              urlRewrite:
                hostname: store.example.com
                path:
                  type: ReplacePrefixMatch
                  replacePrefixMatch: /de
            backendRefs:
            - name: store-german
              port: 8080
      

      Por ejemplo, con la configuración anterior, cualquier solicitud a https://www.example.com/store/... se reenvía al servicio de backend con Host: store.example.com en el encabezado de la solicitud (en lugar de Host: www.example.com) y /store se reescribe como /de.

    3. Aplica el manifiesto

      kubectl apply -f www.yaml
      

    Verifica la configuración

    Sigue estos pasos para verificar que el filtro se haya aplicado después de crear tu HTTPRoute con reescritura de URL o filtros de redireccionamientos de ruta:

    kubectl get httproute www -o yaml
    

    El resultado es similar a este:

      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: HTTPRoute
      metadata:
        annotations:
          kubectl.kubernetes.io/last-applied-configuration: |
            {"apiVersion":"gateway.networking.k8s.io/v1beta1","kind":"HTTPRoute","metadata":{"annotations":{},"name":"www","namespace":"default"},"spec":{"hostnames":["www.example.com"],"parentRefs":[{"kind":"Gateway","name":"external-http"}],"rules":[{"backendRefs":[{"name":"store-german","port":8080}],"filters":[{"type":"URLRewrite","urlRewrite":{"hostname":"store.example.com","path":{"replacePrefixMatch":"/de","type":"ReplacePrefixMatch"}}}],"matches":[{"path":{"type":"PathPrefix","value":"/store"}}]}]}}
        creationTimestamp: "2023-06-22T01:00:42Z"
        generation: 3
        name: www
        namespace: default
        resourceVersion: "51268631"
        uid: e516493e-806d-44d6-ae0d-1c9ff25682cf
      spec:
        hostnames:
        - www.example.com
        parentRefs:
        - group: gateway.networking.k8s.io
          kind: Gateway
          name: external-http
        rules:
        - backendRefs:
          - group: ""
            kind: Service
            name: store-german
            port: 8080
            weight: 1
          filters:
          - type: URLRewrite
            urlRewrite:
              hostname: store.example.com
              path:
                replacePrefixMatch: /de
                type: ReplacePrefixMatch
          matches:
          - path:
              type: PathPrefix
              value: /store
      status:
        parents:
        - conditions:
          - lastTransitionTime: "2023-06-22T01:11:26Z"
            message: ""
            observedGeneration: 2
            reason: Accepted
            status: "True"
            type: Accepted
          - lastTransitionTime: "2023-06-22T01:11:26Z"
            message: ""
            observedGeneration: 2
            reason: ReconciliationSucceeded
            status: "True"
            type: Reconciled
          controllerName: networking.gke.io/gateway
          parentRef:
            group: gateway.networking.k8s.io
            kind: Gateway
            name: external-http
    
    

    Para obtener más detalles, usa un comando describe:

    kubectl describe httproute
    

    Configura encabezados personalizados de solicitud y respuesta

    Los encabezados de solicitud y respuesta personalizados te permiten especificar encabezados adicionales para las solicitudes y respuestas HTTP(S). Según la información que detecte el balanceador de cargas, estos encabezados pueden incluir la siguiente información:

    • Latencia para el cliente
    • Ubicación geográfica de la dirección IP del cliente
    • Parámetros de la conexión TLS

    De forma predeterminada, no hay encabezados personalizados agregados a la solicitud enviada o recibida desde o hacia tus servicios de backend, debes configurar encabezados personalizados de manera explícita con un filtro en tu HTTPRoute.

    Para configurar encabezados personalizados, agrega una sección de filtro en las reglas de HTTPRoute de la siguiente manera:

    Configura encabezados de solicitud personalizados

    Crea un manifiesto HTTPRoute con un filtro RequestHeaderModifier y guárdalo como http-route-request.yaml:

      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        <...>
        rules:
            filters:
              - type: RequestHeaderModifier
                requestHeaderModifier:
                  <...>
    

    Aplica el manifiesto

      kubectl apply -f http-route-request.yaml
    

    Configura encabezados de respuesta personalizados

    Crea un manifiesto HTTPRoute con un filtro ResponseHeaderModifier y guárdalo como http-route-response.yaml:

    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: HTTPRoute
    metadata:
      name: store
    spec:
      <...>
      rules:
          filters:
            - type: ResponseHeaderModifier
              responseHeaderModifier:
                <...>
    

    Aplica el manifiesto

      kubectl apply -f http-route-response.yaml
    

    Puedes agregar, configurar y quitar encabezados como se describe en la implementación de la API de Gateway. Puedes configurar tu HTTPRoute con un encabezado personalizado mediante las variables compatibles de Google Cloud.

    Ejemplo 1:

    Para configurar una HTTPRoute que agregue información de la ubicación del cliente a la solicitud HTTP antes de enviarla al servicio de backend, crea un manifiesto HTTPRoute y asígnale el nombre external-http-request.yaml:

      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        parentRefs:
          - kind: Gateway
            name: external-http
        hostnames:
        - store.example.com
        rules:
          - matches:
            - path:
                type: PathPrefix
                value: /fr
            filters:
              - type: RequestHeaderModifier
                requestHeaderModifier:
                  add:
                    - name: X-Client-Geo-Location
                      value: "{client_region},{client_city}"
            backendRefs:
              - name: store-french
                port: 8080
    

    Por ejemplo, para los clientes ubicados en Estrasburgo, Francia, la puerta de enlace agrega un encabezado como X-Client-Geo-Location:FR,Strasbourg.

    Ejemplo 2:

    Para configurar una HTTPRoute que agregue un encabezado de respuesta personalizado a fin de admitir HTTP con Seguridad de Transporte Estricta, crea un manifiesto HTTPRoute y asígnale el nombre external-http-response.yaml:

      apiVersion: gateway.networking.k8s.io/v1beta1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        parentRefs:
          - kind: Gateway
            name: external-http
        hostnames:
        - store.example.com
        rules:
          - matches:
            - path:
                type: PathPrefix
                value: /de
            filters:
              - type: ResponseHeaderModifier
                responseHeaderModifier:
                  add:
                    - name: Strict-Transport-Security
                      value: max-age=63072000
            backendRefs:
              - name: store-german
                port: 8080
    

    Verifica la configuración

    1. Para verificar la configuración después de configurar encabezados de solicitud y respuesta personalizados, haz lo siguiente:

        kubectl get httproute
      

      El resultado es similar a este:

        NAME    HOSTNAMES               AGE
        store   ["store.example.com"]   4d23h
      
    2. Para obtener más detalles, usa el comando describe:

        kubectl describe httproute
      

      El resultado es similar a este:

        Name:         store
        Namespace:    default
        Labels:       <none>
        Annotations:  <none>
        API Version:  gateway.networking.k8s.io/v1beta1
        Kind:         HTTPRoute
        Metadata:
          Creation Timestamp:  2023-05-27T00:51:01Z
          Generation:          5
          Resource Version:    25418887
          UID:                 2e07a1b8-420b-41b4-acd1-cecbfcd39f42
        Spec:
          Hostnames:
            store.example.com
          Parent Refs:
            Group:  gateway.networking.k8s.io
            Kind:   Gateway
            Name:   external-http
          Rules:
            Backend Refs:
              Group:
              Kind:    Service
              Name:    store-v1
              Port:    8080
              Weight:  1
            Matches:
              Path:
                Type:   PathPrefix
                Value:  /
            Backend Refs:
              Group:
              Kind:    Service
              Name:    store-v2
              Port:    8080
              Weight:  1
            Matches:
              Headers:
                Name:   env
                Type:   Exact
                Value:  canary
              Path:
                Type:   PathPrefix
                Value:  /
            Backend Refs:
              Group:
              Kind:    Service
              Name:    store-german
              Port:    8080
              Weight:  1
            Filters:
              Request Header Modifier:
                Add:
                  Name:   X-Client-Geo-Location
                  Value:  {client_region},{client_city}
              Type:       RequestHeaderModifier
            Matches:
              Path:
                Type:   PathPrefix
                Value:  /de
        Status:
          <...>
      

    Estado de la ruta

    Los recursos HTTPRoute emiten condiciones y eventos para ayudar a los usuarios a comprender si una HTTPRoute se vinculó correctamente a una o más puertas de enlace o si se rechazó.

    Condiciones de HTTPRoute

    Las condiciones de HTTPRoute indican el estado de la ruta y las puertas de enlace a las que está vinculada. Debido a que una ruta se puede vincular a varias puertas de enlace, esta es una lista de puertas de enlace y las condiciones individuales entre la ruta y cada puerta de enlace.

    • Accepted=True indica que la HTTPRoute está vinculada correctamente a una puerta de enlace.
    • Accepted=False indica que la HTTPRoute se rechazó para vincularse con esta puerta de enlace.

    Si no hay puertas de enlace enumeradas en el encabezado Gateway bindings, es posible que tus selectores de etiquetas de HTTPRoute y de etiquetas de puerta de enlace no coincidan. Esto puede ocurrir si ninguna puerta de enlace selecciona la ruta.

    Eventos de HTTPRouter

    Los eventos HTTPRoute proporcionan detalles sobre el estado de HTTPRoute. Los eventos se agrupan por los siguientes motivos:

    • Los eventos ADD se activan mediante un recurso que se agrega.
    • Los eventos UPDATE se activan mediante un recurso que se actualiza.
    • Los eventos SYNC se activan mediante una conciliación periódica.

    Combinación, prioridad y validación de rutas

    Prioridad de ruta

    La API de Gateway define reglas de prioridad estrictas que indican cómo el tráfico coincide con las rutas que tienen reglas de enrutamiento superpuestas. La prioridad entre dos HTTPRoutes superpuestas es la siguiente:

    1. Combinación de nombres de host: La coincidencia de nombres de host más larga o más específica.
    2. Combinación de rutas de acceso: La coincidencia de rutas de acceso más larga o más específica.
    3. Combinación de encabezados: La mayor cantidad de encabezados HTTP que coinciden.
    4. Conflicto: Si las tres reglas anteriores no establecen prioridad, la prioridad va al recurso HTTPRouter con la marca de tiempo más antigua.

    Combinación de rutas

    Para las GatewayClasses gke-l7, todas las HTTPRouters de una puerta de enlace determinada se combinan en el mismo recurso de mapa de URL. La manera en que las HTTPRoutes se combinan depende del tipo de superposición entre las HTTPRoutes. La HTTPRoute del ejemplo anterior se puede dividir en tres HTTPRoutes diferentes para ilustrar la combinación y la prioridad de rutas:

    1. Combinación de rutas: Las tres HTTPRoutes se conectan con la misma Gateway internal-http, por lo que se combinan.
    2. Combinación de nombres de host: Las tres rutas coinciden para store.example.com, por lo que se combinan sus reglas de nombre de host.
    3. Combinación de rutas: tore-german-route tiene una ruta de acceso /de más específica, por lo que no se combina más. store-v1-route y store-v2-route también coinciden en la misma ruta /*, por lo que se combinan en la ruta.
    4. Combinación de encabezados: store-v2-route tiene un conjunto más específico de coincidencias de encabezados HTTP que store-v1-route, por lo que no se combinan más.
    5. Conflicto: Debido a que las Routes se pueden combinar en el nombre de host, la ruta de acceso y los encabezados, no hay conflictos, y todas las reglas de enrutamiento se aplicarán al tráfico.

    La única HTTPRoute que se usa en el ejemplo anterior es equivalente a estas tres rutas separadas:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store-v1-route
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - backendRefs:
        - kind: Service
          name: store-v1
          port: 8080
    ---
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store-v2-route
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - matches:
        - headers:
          - type: Exact
            name: env
            value: canary
        backendRefs:
        - kind: Service
          name: store-v2
          port: 8080
    ---
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store-german-route
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /de
        backendRefs:
        - kind: Service
          name: store-german
          port: 8080
    

    Puertas de enlace de Kubernetes y puertas de enlace de Istio

    Ten en cuenta que la API de Kubernetes Gateway y la API de Istio tienen un recurso llamado Gateway. Si bien realizan funciones similares, no son el mismo recurso. Si usas Istio y la API de Gateway en el mismo clúster de Kubernetes, estos nombres se superponen cuando usas kubectl en la línea de comandos. kubectl get gateway puede mostrar los recursos de la puerta de enlace de Kubernetes y no los de la puerta de enlace de Istio, o viceversa.

    $ kubectl api-resources
    NAME       SHORTNAMES   APIGROUP                       NAMESPACED   KIND
    gateways   gw           networking.istio.io/v1beta1    true         Gateway
    gateways   gtw          networking.k8s.io/v1beta1      true         Gateway
    

    Si usas Istio y actualizas a GKE 1.20 y versiones posteriores, se recomienda comenzar a usar el nombre corto del recurso de Gateway o especificar el grupo de API. El nombre corto de una puerta de enlace de Kubernetes es gtw, y el nombre corto de una puerta de enlace de Istio es gw. Los siguientes comandos muestran los recursos de puerta de enlace de Kubernetes y de puerta de enlace de Istio, respectivamente.

    # Kubernetes Gateway
    # Istio Gateway
    $ kubectl get gw
    NAME               AGE
    bookinfo-gateway   64m
    
    $ kubectl get gateway.networking.istio.io
    NAME               AGE
    bookinfo-gateway   64m
    

    Soluciona problemas

    Falta la subred de solo proxy en la región

    Síntoma:

    El siguiente problema puede ocurrir cuando creas una puerta de enlace regional (interna o externa):

    generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/[REGION_NAME]/targetHttpProxies/gkegw-x5vt-default-internal-http-[ID]'. A reserved managed proxy subnetwork with purpose REGIONAL_MANAGED_PROXY is required.
    

    Motivo:

    Este mensaje de error indica que no existe una subred de solo proxy en la región de la puerta de enlace.

    Solución alternativa:

    Para resolver este problema, configura una subred de solo proxy.

    La subred de solo proxy ya existe en la región con el propósito incorrecto

    Síntoma:

    El siguiente problema puede ocurrir cuando creas una subred de solo proxy para la puerta de enlace regional (interna o externa):

    ERROR: (gcloud.compute.networks.subnets.create) Could not fetch resource:
     - The resource 'projects/[PROJECT_NAME]/regions/[REGION_NAME]/subnetworks/[PROXY_ONLY_SUBNET_NAME]' already exists
    

    Motivo:

    Este mensaje de error indica que intentaste crear una subred de solo proxy regional en una región que ya tiene una subred de solo proxy.

    Solución alternativa:

    Para resolver este problema, sigue estos pasos:

    1. Comprueba que ya exista una subred de solo proxy en la región y verifica que tenga el propósito correcto:

      1. Enumera tus subredes para descubrir cuál es la subred de solo proxy en la región:

        gcloud compute networks subnets list --regions=COMPUTE_REGION
        

        Reemplaza COMPUTE_REGION por la región de Compute Engine en la que quieres crear la puerta de enlace regional.

      2. Describe la subred de solo proxy en la región para encontrar su propósito:

        gcloud compute networks subnets describe PROXY_ONLY_SUBNET \
            --region COMPUTE_REGION | grep -E 'name|purpose'
        

        Reemplaza PROXY_ONLY_SUBNET por la subred de solo proxy.

      La puerta de enlace de GKE solo admite subredes de solo proxy REGIONAL_MANAGED_PROXY para puertas de enlace regionales (internas o regionales).

    2. Si la subred de solo proxy existente en la región se creó con un propósito INTERNAL_HTTPS_LOAD_BALANCER, migra su propósito a REGIONAL_MANAGED_PROXY.

    ¿Qué sigue?