Implementa puertas de enlace

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

En esta página, se describe cómo implementar recursos de puerta de enlace de Kubernetes en Google Kubernetes Engine (GKE). Se explica cómo implementar una puerta de enlace privada y una puerta de enlace orientada a Internet para exponer aplicaciones, y se muestran algunos de los conceptos del modelo de recursos de la API de Gateway.

Por el momento, la implementación de la puerta de enlace para el balanceo de cargas de varios clústeres está disponible en vista previa. Si deseas ver cómo se implementan las puertas de enlace para el balanceo de cargas de varios clústeres, consulta Implementa puertas de enlace de varios clústeres.

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 la CLI de gcloud.

Requisitos del controlador de la puerta de enlace de GKE

  • Para Standard, la versión 1.24 de GKE o una 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.
  • No puedes usar las APIs v1alpha de puerta de enlace con Istio. Para obtener más información, consulta Puertas de enlace de Kubernetes y puertas de enlace de Istio.
  • La API de Gateway no admite la anotación networking.gke.io/app-protocols. En su lugar, usa el campo appProtocol.

Limitaciones y problemas conocidos

Se aplica la siguiente limitación:

  • 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.
  • 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 ver los recursos de puerta de enlace, HTTPRoute ni de políticas en la consola de Google Cloud. Puedes descubrir y administrar recursos de puerta de enlace mediante la API de Kubernetes.
  • 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.
  • Debes implementar una puerta de enlace en un clúster de GKE en el mismo proyecto host o de servicio. No se admiten implementaciones entre proyectos.
  • Las funciones de administración del tráfico son compatibles con los GatewayClasses internos (balanceadores de cargas HTTP(S) internos) en Google Analytics. La compatibilidad con GatewayClasses externas (balanceadores de cargas HTTP(S) externos) está disponible en vista previa con gke-l7-global-external-managed y GatewayClasses gke-l7-global-external-managed-mc.
  • 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.

Las siguientes funciones de balanceo de cargas no son compatibles con las puertas de enlace de GKE:

  • Cloud CDN.
  • Identity-Aware Proxy.
  • Google Cloud Armor.
  • Políticas de SSL.
  • Redireccionamiento HTTP a HTTPS.
  • Encabezados de respuesta y solicitud personalizados
  • Usar GKE Gateway Controller con Kubernetes en Compute Engine (Kubernetes autoadministrado)
  • Recursos FrontendConfig y BackendConfig. En su lugar, usa las Políticas de puertas de enlace.

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. La marca --gateway-api controla esta API. Puedes usar el valor standard cuando la habilitas y disabled cuando la inhabilitas.

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

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

gcloud container clusters create CLUSTER_NAME \
    --gateway-api=standard \
    --cluster-version=VERSION \
    --region=COMPUTE_REGION

Reemplaza lo siguiente:

  • 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.
  • COMPUTE_REGION: es la región de Compute Engine del clúster. Para los clústeres zonales, usa --zone=COMPUTE_ZONE.

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

Actualiza un clúster nativo de la VPC existente:

gcloud container clusters update CLUSTER_NAME \
    --gateway-api=standard \
    --region=COMPUTE_REGION

Reemplaza lo siguiente:

  • CLUSTER_NAME: es el nombre del clúster existente.
  • COMPUTE_REGION: la región de Compute Engine del clúster. Para los clústeres zonales, usa --zone=COMPUTE_ZONE.

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 CRD y en instalar las GatewayClasses.

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-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.

Configura una subred de solo proxy

Debes configurar una subred de solo proxy antes de crear una Gateway que use un balanceador de cargas de HTTP(S) interno. Cada región de una VPC en la que uses balanceadores de cargas HTTP(S) 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=REGION \
        --network=VPC_NETWORK_NAME \
        --range=CIDR_RANGE
    

    Reemplaza lo siguiente:

    • SUBNET_NAME: El nombre de la subred de solo proxy
    • 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 un tamaño máximo de /26 a fin de 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=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. Para 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 HTTP(S) regional 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, aún 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": "us-central1-a"
    }
    
  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": "us-central1-a"
    }
    
  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": "us-central1-a"
    }
    

Implementa una puerta de enlace externa

Una puerta de enlace externa expone las aplicaciones a las que se puede acceder desde Internet o redes fuera de la VPC. La implementación es similar a una implementación de puerta de enlace interna, excepto que debes proteger tus aplicaciones, ya que la Internet pública puede acceder a la puerta de enlace.

Como administrador de la plataforma, es posible que debas exponer la aplicación mediante una puerta de enlace externa. En el siguiente ejemplo, se muestra cómo exponer una aplicación de almacenamiento con varios certificados adjuntos a la puerta de enlace y agrupados en un mapa de certificados mediante el administrador de certificados y una HTTPRoute.

Crea un mapa de certificados

Google recomienda que uses el administrador de certificados para administrar certificados cuando necesites 15 o más certificados por puerta de enlace o si necesitas usar certificados comodín.

También puedes proteger tu puerta de enlace externa con objetos Secret de Kubernetes o certificados SSL administrados por Google. Para obtener más información, consulta Seguridad de la puerta de enlace.

En esta sección, crearás certificados con el administrador de certificados para proteger las aplicaciones que se ejecutan en el clúster.

  1. Habilita la API de administrador de certificados:

    gcloud services enable certificatemanager.googleapis.com
    
  2. Crea un mapa de certificados:

    gcloud beta certificate-manager maps create store-example-com-map
    
  3. Carga las claves y el certificado administrado por Google en un certificado:

    gcloud beta certificate-manager certificates create store-example-com-cert \
        --certificate-file="CERTIFICATE_FILE" \
        --private-key-file="PRIVATE_KEY_FILE"
    

    Reemplaza lo siguiente:

    • CERTIFICATE_FILE: el nombre del archivo nuevo que eliges. El archivo debe tener la extensión .pem. Por ejemplo, cert.pem.
    • PRIVATE_KEY_FILE: el nombre de tu archivo de clave privada.

    Para obtener más información, consulta Crea una clave privada y un certificado.

  4. Crea una CertificateMapEntry que asigne el certificado al mapa de certificados:

    gcloud beta certificate-manager maps entries create store-example-com-map-entry \
        --map=store-example-com-map \
        --hostname=store.example.com \
        --certificates=store-example-com-cert
    

Si deseas obtener información sobre cómo proteger una puerta de enlace con otras fuentes para certificados, como objetos Secret de Kubernetes o certificados SSL, consulta Protege una puerta de enlace.

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 que usa.

Para 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 esta sección, crearás una puerta de enlace. Los equipos de aplicaciones pueden usar la puerta de enlace para exponer sus aplicaciones a Internet mediante la implementación de rutas forma independiente y su conexión segura a la puerta de enlace.

  1. Guarda el siguiente manifiesto como un archivo llamado gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: external-http
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      gatewayClassName: gke-l7-gxlb
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
    

    En este manifiesto, se describe una puerta de enlace con los siguientes campos:

    • gatewayClassName: gke-l7-gxlb: especifica la GatewayClass para esta puerta de enlace. Esta clase de puerta de enlace usa un balanceador de cargas HTTP(S) externo global (clásico).
    • protocol: HTTPS y port: 443: especifican que la puerta de enlace expone el puerto 443 para el tráfico HTTPS. Estos campos habilitan TLS.
    • networking.gke.io/certmap: store-example-com-map: especifica el nombre del mapa de certificados en el administrador de certificados.

    No hay sección TLS porque TLS se configura con el administrador de certificados mediante la anotación networking.gke.io/certmap.

  2. Aplica el manifiesto al clúster:

    kubectl apply -f gateway.yaml
    

    GKE puede tardar unos minutos en implementar los recursos.

  3. Verifica que la puerta de enlace se haya implementado de forma correcta:

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

    El resultado es similar a este:

    Spec:
      Gateway Class Name:  gke-l7-gxlb
      Listeners:
        Allowed Routes:
          Namespaces:
            From:  Same
        Name:      https
        Port:      443
        Protocol:  HTTPS
    Status:
      Addresses:
        Type:   IPAddress
        Value:  34.149.207.45
      Conditions:
        Last Transition Time:  2022-11-01T05:37:21Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2022-11-01T05:37:21Z
        Message:
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  0
        Conditions:
          Last Transition Time:  2022-11-01T05:37:21Z
          Message:
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    https
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
    Events:
      Type    Reason  Age               From                   Message
      ----    ------  ----              ----                   -------
      Normal  ADD     50s               sc-gateway-controller  default/external-http
      Normal  UPDATE  5s (x3 over 50s)  sc-gateway-controller  default/external-http
      Normal  SYNC    5s                sc-gateway-controller  SYNC on default/external-http was a success
    

    En este resultado, se muestra que la puerta de enlace implementada en tu clúster tiene un balanceador de cargas y una dirección IP pública. La puerta de enlace no tiene rutas, lo que significa que no puede enviar tráfico a los backends. Sin rutas, todo el tráfico se dirige a un backend predeterminado, que muestra una respuesta HTTP 404. En la siguiente sección, implementarás rutas, que le indican a la puerta de enlace que envíe tráfico a los backends.

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 external-http creada en la sección anterior.

Para obtener más información sobre los campos HTTPRoute, consulta la especificación de la API.

  1. Implementa la aplicación de muestra en el clúster.

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

    Esta aplicación de muestra crea tres objetos Deployment y tres objetos Service llamados store-v1, store-v2 y store-german.

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

    kubectl get pod
    

    El resultado es similar a este:

    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. Verifica que los objetos Service se hayan implementado de forma correcta:

    kubectl get service
    

    El resultado es similar a este:

    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
    

Crea una 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 una HTTPRouter, que configura la puerta de enlace con reglas de enrutamiento necesarias para llegar a la aplicación de muestra.

  1. Guarda el siguiente manifiesto como un archivo llamado store-route-external.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store-external
    spec:
      parentRefs:
      - kind: Gateway
        name: external-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
    

    En este manifiesto, se describe una HTTPRouter que hace referencia a la puerta de enlace external-http.

  2. Aplica el manifiesto al clúster:

    kubectl apply -f store-route-external.yaml
    

    La HTTPRoute store está vinculada a la puerta de enlace external-http mediante la propiedad parentRefs. En el siguiente diagrama, se muestran las reglas de enrutamiento configuradas en el balanceador de cargas subyacente:

    Las reglas de enrutamiento configuradas por la tienda de HTTPRoute

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

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

    kubectl describe httproute store-external
    

    El resultado es similar a este:

    Name:         store-external
    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:   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
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /de
    Status:
      Parents:
        Conditions:
          Last Transition Time:  2022-11-01T05:42:31Z
          Message:
          Reason:                Accepted
          Status:                True
          Type:                  Accepted
          Last Transition Time:  2022-11-01T05:43:18Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   external-http
    Events:
      Type     Reason  Age    From                   Message
      ----     ------  ----   ----                   -------
      Normal   ADD     2m48s  sc-gateway-controller  default/store-external
      Normal  SYNC  61s (x3 over 2m27s)  sc-gateway-controller  Bind of HTTPRoute "default/store-external" to ParentRef Group:       "gateway.networking.k8s.io",
      ...
    
  4. Verifica que la HTTPRoute esté vinculada a la puerta de enlace:

    kubectl describe gateway external-http
    

    El resultado es similar a este:

    Name:         external-http
    Namespace:    default
    Labels:       <none>
    <...>
    Status:
      Addresses:
        Type:   IPAddress
        Value:  34.149.207.45
      Conditions:
        Last Transition Time:  2022-11-01T05:37:21Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2022-11-01T05:43:18Z
        Message:
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2022-11-01T05:43:18Z
          Message:
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    https
        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. Obtén la dirección IP de la puerta de enlace:

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

    El resultado es una dirección IP.

  2. Crea una VM:

    gcloud cloud-shell ssh
    
  3. Envía tráfico a la dirección IP de la puerta de enlace desde la VM. Debes configurar el encabezado del host de forma manual porque no eres propietario del nombre de host example.com.

    curl -H "host: store.example.com" https://GATEWAY_IP_ADDRESS --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

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

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

    {
      "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-09-25T13:31:17",
      "zone": "us-central1-a"
    }
    
  4. Para probar la coincidencia de ruta de acceso, ve a la versión en alemán del objeto Service store en store.example.com/de:

    curl -H "host: store.example.com" https://GATEWAY_IP_ADDRESS/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

    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-09-25T13:35:37",
      "zone": "us-central1-a"
    }
    
  5. Envía tráfico a la versión canary del objeto Service store con el encabezado HTTP env: canary:

    curl -H "host: store.example.com" -H "env: canary " https://GATEWAY_IP_ADDRESS/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

    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-09-25T13:38:26",
      "zone": "us-central1-a"
    }
    

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 Aceptada 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": "us-central1-a"
    }
    ...
    {
      "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": "us-central1-a"
    }
    

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
  • gke-l7-rilb-rc
  • Direcciones IP privadas regionales del rango de direcciones IP del nodo principal
  • gke-l7-gxlb
  • gke-l7-gxlb-mc
  • gke-l7-global-external-managed
  • gke-l7-global-external-managed-mc
  • Direcciones IP públicas globales de los rangos de IP públicas 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 para una puerta de enlace global o regional:

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

      Reemplaza lo siguiente:

      • IP_ADDRESS_NAME: el nombre de la dirección IP estática nueva
      • REGION: para las puertas de enlace regionales, es la región de Compute Engine en la que se ejecuta el clúster. Esta marca no es necesaria para las puertas de enlace globales externas.
      • SUBNET: la subred de la dirección IP. Esta marca no es necesaria para las puertas de enlace globales externas.
      • 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
      

    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 combinarán.
    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 superpondrán cuando uses 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
    $ kubectl get gtw
    NAME                        CLASS
    multi-cluster-gateway       gke-l7-gxlb-mc
    
    $ kubectl get gateway.networking.x-k8s.io
    NAME                        CLASS
    multi-cluster-gateway       gke-l7-gxlb-mc
    
    # 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 para la puerta de enlace interna

    El siguiente problema puede ocurrir cuando creas una puerta de enlace interna:

    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 and active subnetwork is required in the same region and VPC as the forwarding rule.
    

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

    ¿Qué sigue?