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 campoappProtocol
.
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 GatewayClassesgke-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
yBackendConfig
. 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ústerVERSION
: 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.
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 proxyREGION
: La región de la subred de solo proxyVPC_NETWORK_NAME
: El nombre de la red de VPC que contiene la subredCIDR_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
.
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.
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.
Implementa la puerta de enlace en tu clúster:
kubectl apply -f gateway.yaml
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.
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
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
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.
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
Implementa la HTTProute en tu clúster:
kubectl apply -f store-route.yaml
La HTTPRoute
store
está vinculada a la puerta de enlaceinternal-http
mediante la propiedadparentRefs
. Estas reglas de enrutamiento se configuran en el balanceador de cargas subyacente como se muestra en este diagrama:Estas reglas de enrutamiento procesan el tráfico HTTP de la siguiente manera:
- El tráfico a
store.example.com/de
va al objeto Servicestore-german
. - El tráfico a
store.example.com
con el encabezado HTTP"env: canary"
va al objeto Servicestore-v2
. - El tráfico restante a
store.example.com
va al objeto Servicestore-v1
.
- El tráfico a
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", <...>
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.
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.
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" }
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" }
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.
Habilita la API de administrador de certificados:
gcloud services enable certificatemanager.googleapis.com
Crea un mapa de certificados:
gcloud beta certificate-manager maps create store-example-com-map
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.
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.
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
yport: 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
.Aplica el manifiesto al clúster:
kubectl apply -f gateway.yaml
GKE puede tardar unos minutos en implementar los recursos.
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.
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
ystore-german
.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
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.
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
.Aplica el manifiesto al clúster:
kubectl apply -f store-route-external.yaml
La HTTPRoute
store
está vinculada a la puerta de enlaceexternal-http
mediante la propiedadparentRefs
. En el siguiente diagrama, se muestran las reglas de enrutamiento configuradas en el balanceador de cargas subyacente: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 Servicestore-german
. - El tráfico a
store.example.com
con el encabezado HTTP"env: canary"
se enruta al objeto Servicestore-v2
. - El tráfico restante a
store.example.com
se enruta al objeto Servicestore-v1
.
- El tráfico a
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", ...
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.
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.
Crea una VM:
gcloud cloud-shell ssh
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" }
Para probar la coincidencia de ruta de acceso, ve a la versión en alemán del objeto Service
store
enstore.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" }
Envía tráfico a la versión canary del objeto Service
store
con el encabezado HTTPenv: 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.
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
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 Servicesite-v1
.Aplica el manifiesto al clúster:
kubectl apply -f site-route-internal.yaml
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.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 |
---|---|
|
Direcciones IP privadas regionales del rango de direcciones IP del nodo principal |
|
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.
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 nuevaREGION
: 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.
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.
Aplica el manifiesto al clúster:
kubectl apply -f named-ip-gateway.yaml
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:
- Combinación de nombres de host: La coincidencia de nombres de host más larga o más específica.
- Combinación de rutas de acceso: La coincidencia de rutas de acceso más larga o más específica.
- Combinación de encabezados: La mayor cantidad de encabezados HTTP que coinciden.
- 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:
- Combinación de rutas: Las tres HTTPRoutes se conectan con la misma Gateway
internal-http
, por lo que se combinarán. - 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. - 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. - 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.
- 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?
- Obtén más información sobre el controlador de Gateway.
- Obtén más información sobre cómo configurar los recursos de la puerta de enlace mediante políticas.