En este documento, se muestra cómo implementar un recurso de puerta de enlace de Kubernetes configurado para la transferencia de TLS para habilitar el enrutamiento basado en la indicación de nombre del servidor (SNI) en Google Kubernetes Engine (GKE). Este enfoque conserva la encriptación de extremo a extremo y la TLS mutua (mTLS) entre los clientes y los Pods de backend, admite protocolos basados en TLS que no son HTTP y conserva las direcciones IP.
Este documento está dirigido a arquitectos de Cloud, especialistas en herramientas de redes y desarrolladores que diseñan, implementan y administran redes encriptadas para cargas de trabajo en contenedores. Para obtener más información sobre los roles comunes y las tareas de ejemplo, consulta Roles y tareas comunes del usuario de GKE.
Descripción general
Además de los balanceadores de cargas de aplicaciones HTTP y HTTPS de capa 7, el controlador de puerta de enlace de GKE admite balanceadores de cargas de red de proxy de capa 4 (balanceadores de cargas de proxy TCP) configurados con transferencia de TLS.
Con la transferencia de TLS, el balanceador de cargas no finaliza ni desencripta la sesión
de TLS. En cambio, cuando un cliente inicia un protocolo de enlace TLS, el balanceador de cargas
inspecciona el mensaje ClientHello sin encriptar para leer el nombre de host de la indicación del nombre del servidor (SNI). Según este nombre de host de SNI, el balanceador de cargas enruta
el flujo de TCP encriptado sin procesar al Service de Kubernetes de backend adecuado,
en el que los Pods de tu aplicación finalizan TLS directamente.
Cuando usas la transferencia de TLS con la API de Gateway, puedes hacer lo siguiente:
- Mantén la encriptación de extremo a extremo y admite el cumplimiento de confianza cero: Mantén el tráfico completamente encriptado desde el cliente hasta el Pod de backend sin otorgar al balanceador de cargas acceso a claves privadas o datos de texto simple.
- Usa la autenticación de TLS mutua (mTLS): Autentica a los clientes directamente en la capa de aplicación del backend.
- Conserva las direcciones IPv4: Multiplexa varios servicios de TLS independientes
en distintos dominios o subdominios con una sola dirección IP y un puerto de puerta de enlace (como
443). - Admite protocolos basados en TLS que no sean HTTP: Enruta el tráfico encriptado para cargas de trabajo con estado, bases de datos, servicios de gRPC personalizados o protocolos de propiedad que se ejecutan en TLS.
GatewayClasses compatibles
Las siguientes GatewayClasses de GKE admiten objetos de escucha de transferencia de TLS y recursos TLSRoute:
gke-l7-regional-external-managedgke-l7-regional-external-managed-mcgke-l7-rilbgke-l7-rilb-mcgke-l7-cross-regional-internal-managed-mc
Para obtener una comparación completa de las capacidades de GatewayClass, consulta Capacidades de GatewayClass.
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
- Para usar Google Cloud CLI en esta tarea,
instala y, luego,
inicializa la
gcloud CLI. Si ya instalaste gcloud CLI, ejecuta el comando
gcloud components updatepara obtener la versión más reciente. Es posible que las versiones anteriores de gcloud CLI no admitan la ejecución de los comandos de este documento.
- Verifica que tengas un clúster de Autopilot o Standard existente que ejecute la versión 1.35 o posterior de GKE con la API de Gateway habilitada. Para crear un clúster, consulta Crea un clúster de Autopilot. Para habilitar la API de Gateway en un clúster existente, consulta Habilita la API de Gateway en tu clúster.
- Verifica que tengas instalada la herramienta de línea de comandos de OpenSSL. Usa esta herramienta para generar certificados TLS autofirmados para las aplicaciones de ejemplo.
Requisitos del controlador de la puerta de enlace de GKE
- La API de Gateway solo es compatible con clústeres nativos de VPC.
- Si usas las GatewayClasses regionales o entre regiones, debes habilitar una subred de solo proxy.
- El clúster debe tener el complemento
HttpLoadBalancinghabilitado. - Si usas Istio, debes actualizarlo a una de las siguientes versiones:
- 1.15.2 o una versión posterior
- 1.14.5 o una versión posterior
- 1.13.9 o una versión posterior.
- Si usas una VPC compartida, en el proyecto host, debes asignar el rol
Compute Network Usera la cuenta de servicio de GKE para el proyecto de servicio.
Restricciones y limitaciones
Cuando implementes puertas de enlace de transferencia de TLS y recursos TLSRoute, ten en cuenta las siguientes limitaciones:
- Cuando configuras el parámetro
protocol: TLSen un objeto de escucha, debes establecer de forma explícita el campotls.modeen el valorPassthrough. GKE no admite el modoTerminatepredeterminado para los objetos de escuchaTLS. - En un objeto de escucha
TLS, no configures el campocertificateRefs. La validación del certificado de cliente a nivel de puerta de enlace (el campospec.tls.frontendValidation) no se aplica a los objetos de escuchaTLS. Para usar mTLS, valida los certificados de cliente en tu backend. - Un objeto de escucha
TLSpuede compartir un puerto solo con otros objetos de escuchaTLS. No puedes configurar objetos de escuchaHTTPoHTTPSen el mismo puerto que un objeto de escuchaTLS. - En el campo
TLSRoute.spec.hostnames, debes especificar una lista de 1 a 1,024 nombres de host de SNI (nombre de host exacto o prefijo comodín, como*.example.com). Cada entrada no puede superar los 253 caracteres y no puede ser una dirección IP. - En el campo
TLSRoute.spec.rules, puedes configurar, como máximo, una regla. - Cada regla admite exactamente una entrada
backendRef. Los backends de proxy de capa 4 no admiten la división del tráfico ponderada en varios backends. - Las GatewayClasses de un solo clúster solo admiten backends de Service, y las GatewayClasses de varios clústeres solo admiten backends de ServiceImport.
- En el campo
TLSRoute.spec.rules.backendRefs, establece el campoporten un puerto declarado por el recurso Service o ServiceImport de destino, no en el puerto del contenedor. - El Service de Kubernetes de backend (incluidos los Services exportados como un
ServiceImport) al que hace referencia un recurso TLSRoute debe usar el valor
TCPpara su protocolo de puerto. - No puedes adjuntar un recurso BackendTLSPolicy, Identity-Aware Proxy o una política de seguridad de Google Cloud Armor a un backend de TLSRoute porque el controlador rechaza las configuraciones de este tipo.
- Cuando adjuntas un recurso GCPBackendPolicy a un Service o ServiceImport
al que hace referencia un recurso TLSRoute, debes establecer el campo
spec.protocolen el valorTCP(omitir el campospec.protocolse establece de forma predeterminada en el valorHTTP, que se aplica solo a los backends de HTTPRoute). Un Service o ServiceImport puede tener una políticaHTTPy una políticaTCPadjuntas al mismo tiempo. Si varias políticas con el mismo valorspec.protocolse orientan al mismo Service o ServiceImport, la política más antigua tiene prioridad y las más nuevas no se adjuntan. Un recurso GCPBackendPolicy con el campo
spec.protocolestablecido enTCPsolo admite los siguientes campos en el campospec.default(cuando se orienta a un recurso ServiceImport, puedes establecer los últimos tres campos por clúster, zona o región en el campospec.default.scopes):timeoutSecconnectionDraininglogging.enabledylogging.sampleRatesessionAffinity.type(los valores válidos sonCLIENT_IPoNONE)capacityScalerPercentbalancingMode: CONNECTIONmaxConnectionsPerEndpoint
No puedes crear una política
TCPque incluya otros campos ni una políticaHTTPque incluya campos solo deTCP(balancingMode: CONNECTIONymaxConnectionsPerEndpoint). El servidor de la API de Kubernetes rechaza la política cuando se crea. Para obtener más información, consulta Configura recursos de puerta de enlace con políticas.Si un recurso HTTPRoute y un recurso TLSRoute hacen referencia al mismo Service o ServiceImport, adjuntar un recurso HealthCheckPolicy a ese destino reemplaza las verificaciones de estado predeterminadas independientes y aplica la misma configuración de verificación de estado a los backends de ambas rutas. Para configurar las verificaciones de estado de forma independiente (como las verificaciones de estado de
HTTPpara los backends de HTTPRoute y las verificaciones de estado deSSLoTCPpara los backends de TLSRoute), crea un Service independiente para cada ruta y adjunta un recurso HealthCheckPolicy a cada Service. Ambos Services pueden seleccionar los mismos Pods.Las funciones de la capa 7 (como las reescrituras de URL, el enrutamiento basado en rutas de acceso y las transformaciones de encabezados HTTP) no se aplican a los balanceadores de cargas de proxy TCP de la capa 4.
Configura una subred de solo proxy
Una puerta de enlace regional requiere una subred de solo proxy (purpose=REGIONAL_MANAGED_PROXY)
en cada región en la que la implementes. Una subred de solo proxy entrega todos los balanceadores de cargas regionales basados en Envoy en esa región. Si tu región aún no tiene
una, consulta
Configura una subred de solo proxy.
Reserva una dirección IP estática
Antes de implementar la puerta de enlace, reserva una dirección IP estática regional para que la dirección de la puerta de enlace no cambie y puedas resolver tus nombres de host de muestra en ella. Para obtener instrucciones sobre cómo crear una dirección IP estática, consulta Crea una puerta de enlace HTTP(S) regional externa.
Implementa una puerta de enlace con objetos de escucha de transferencia de TLS
La puerta de enlace de esta sección configura dos objetos de escucha TLS que comparten el puerto
443. Cada objeto de escucha coincide con un nombre de host de SNI diferente y reenvía las conexiones
en modo de transferencia a los recursos TLSRoute adjuntos.
Guarda el siguiente manifiesto como
store-gateway.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: store-tls spec: gatewayClassName: gke-l7-regional-external-managed listeners: # Accept TLS connections for store.example.com without decrypting them. - name: store protocol: TLS port: 443 hostname: "store.example.com" tls: mode: Passthrough allowedRoutes: kinds: - kind: TLSRoute # A second listener on the same port, selected by a different SNI name. - name: store-german protocol: TLS port: 443 hostname: "store-de.example.com" tls: mode: Passthrough allowedRoutes: kinds: - kind: TLSRoute addresses: - type: NamedAddress value: IP_ADDRESS_NAMEReemplaza IP_ADDRESS_NAME por el nombre de la dirección IP estática que reservaste.
Ten en cuenta que el bloque
tlsno tiene un campocertificateRefs. En el modoPassthrough, el certificado TLS reside en los Pods de backend, en lugar de en el balanceador de cargas.Aplica el manifiesto de Gateway:
kubectl apply -f store-gateway.yamlVerifica que la puerta de enlace esté programada:
kubectl get gateway store-tlsEl aprovisionamiento del balanceador de cargas tarda unos minutos. El resultado es similar a lo siguiente:
NAME CLASS ADDRESS PROGRAMMED AGE store-tls gke-l7-regional-external-managed 35.118.32.224 True 53s
Usa una Gateway interna
Para mantener el tráfico dentro de tu red de VPC, cambia el valor del
campo gatewayClassName a gke-l7-rilb y quita el campo addresses del
manifiesto de la puerta de enlace. Luego, GKE crea un
balanceador de cargas de red del proxy interno regional y asigna una dirección IP interna de la
subred del clúster. Los pasos restantes de esta página no se modificaron. Envía tus solicitudes de prueba
desde una instancia de Compute Engine en la misma red de VPC, ya que no se puede acceder a la dirección IP interna desde Internet.
Implementa aplicaciones de TLS de muestra
En esta sección, implementarás dos implementaciones de NGINX (store-v1 y
store-german) que finalizan TLS en el puerto 8443. Cada Deployment entrega un
certificado TLS diferente y, además, informa el nombre de host de SNI que recibió, lo que
te permite verificar que el enrutamiento se haya realizado en función de la SNI.
Genera un certificado TLS autofirmado y una clave privada para cada nombre de host:
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -days 365 \ -keyout store.key -out store.crt \ -subj '/CN=store.example.com' \ -addext 'subjectAltName=DNS:store.example.com' openssl req -x509 -newkey rsa:2048 -nodes -sha256 -days 365 \ -keyout store-de.key -out store-de.crt \ -subj '/CN=store-de.example.com' \ -addext 'subjectAltName=DNS:store-de.example.com'Usa certificados de tu autoridad certificadora en producción. Los certificados autofirmados mantienen este ejemplo autónomo.
Ejecuta los siguientes comandos para almacenar cada certificado y clave en un Secret de Kubernetes:
kubectl create secret tls store-cert \ --cert=store.crt --key=store.key kubectl create secret tls store-de-cert \ --cert=store-de.crt --key=store-de.keyGuarda el siguiente manifiesto como
store-tls-app.yaml:apiVersion: v1 kind: ConfigMap metadata: name: store-nginx data: default.conf: | server { listen 8443 ssl; ssl_certificate /etc/nginx/ssl/tls.crt; ssl_certificate_key /etc/nginx/ssl/tls.key; default_type text/plain; # Report which Pod answered and which SNI name it received. return 200 "backend: $hostname\nsni: $ssl_server_name\n"; } --- apiVersion: apps/v1 kind: Deployment metadata: name: store-v1 spec: replicas: 2 selector: matchLabels: app: store-v1 template: metadata: labels: app: store-v1 spec: containers: - name: nginx image: nginx:1.27 ports: - containerPort: 8443 volumeMounts: - name: config mountPath: /etc/nginx/conf.d - name: cert mountPath: /etc/nginx/ssl readOnly: true volumes: - name: config configMap: name: store-nginx - name: cert secret: secretName: store-cert --- apiVersion: v1 kind: Service metadata: name: store-v1 spec: selector: app: store-v1 ports: - port: 443 targetPort: 8443 --- apiVersion: apps/v1 kind: Deployment metadata: name: store-german spec: replicas: 2 selector: matchLabels: app: store-german template: metadata: labels: app: store-german spec: containers: - name: nginx image: nginx:1.27 ports: - containerPort: 8443 volumeMounts: - name: config mountPath: /etc/nginx/conf.d - name: cert mountPath: /etc/nginx/ssl readOnly: true volumes: - name: config configMap: name: store-nginx - name: cert secret: secretName: store-de-cert --- apiVersion: v1 kind: Service metadata: name: store-german spec: selector: app: store-german ports: - port: 443 targetPort: 8443Los Services no necesitan un campo
appProtocol. GKE reenvía el tráfico de TLSRoute al backend como TCP, por lo que el campo no tiene efecto.Aplica el manifiesto al clúster:
kubectl apply -f store-tls-app.yamlVerifique que los pods se estén ejecutando:
kubectl get pods -l 'app in (store-v1,store-german)'El resultado es similar a lo siguiente:
NAME READY STATUS RESTARTS AGE store-german-7d9f8c5b47-2xqkd 1/1 Running 0 41s store-german-7d9f8c5b47-h6tzn 1/1 Running 0 41s store-v1-6c4b9d8f65-kp8vr 1/1 Running 0 41s store-v1-6c4b9d8f65-wm2ls 1/1 Running 0 41s
Implementa recursos TLSRoute para el enrutamiento basado en SNI
Un recurso TLSRoute se conecta a un objeto de escucha de Gateway y enruta las conexiones que coinciden con sus nombres de host a un solo Service de backend.
Guarda el siguiente manifiesto como
store-tls-routes.yaml:kind: TLSRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store spec: parentRefs: - kind: Gateway name: store-tls sectionName: store hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 443 --- kind: TLSRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store-german spec: parentRefs: - kind: Gateway name: store-tls sectionName: store-german hostnames: - "store-de.example.com" rules: - backendRefs: - name: store-german port: 443El campo
sectionNameselecciona el objeto de escucha de destino en la puerta de enlace. El campoportespecifica el puerto del Service (443), no el puerto del contenedor.Aplica el manifiesto de TLSRoute:
kubectl apply -f store-tls-routes.yamlVerifica que el controlador de Gateway haya aceptado la ruta:
kubectl get tlsroute store -o yamlEl campo
statuses similar al siguiente:status: parents: - controllerName: networking.gke.io/gateway parentRef: name: store-tls sectionName: store conditions: - type: ResolvedRefs status: "True" reason: ResolvedRefs - type: Accepted status: "True" reason: Accepted - type: Reconciled status: "True" reason: ReconciliationSucceededLa condición
Reconciledes una condición de estado específica de GKE que informa si el controlador de Gateway creó los recursos Google Cloud subyacentes.Verifica que el objeto de escucha de la puerta de enlace haya aceptado la ruta:
kubectl get gateway store-tls -o yamlCada entrada en el campo
status.listenerses similar a la siguiente:- name: store supportedKinds: - group: gateway.networking.k8s.io kind: TLSRoute attachedRoutes: 1 conditions: - type: ResolvedRefs status: "True" reason: ResolvedRefs - type: Accepted status: "True" reason: Accepted - type: Programmed status: "True" reason: Programmed
Verifica el enrutamiento del tráfico
GKE verifica el estado de un backend de transferencia de TLS completando un protocolo de enlace TLS con él. Es posible que los Pods tarden unos minutos en pasar la verificación de estado inicial.
Recupera la dirección IP de la puerta de enlace:
kubectl get gateway store-tls -o jsonpath='{.status.addresses[0].value}'Envía una solicitud a cada nombre de host y reemplaza GATEWAY_IP por la dirección IP del paso anterior:
curl --resolve store.example.com:443:GATEWAY_IP \ --cacert store.crt https://store.example.com curl --resolve store-de.example.com:443:GATEWAY_IP \ --cacert store-de.crt https://store-de.example.comCada respuesta nombra el Pod que respondió y repite el nombre de host de SNI que lo alcanzó:
backend: store-v1-6c4b9d8f65-kp8vr sni: store.example.com backend: store-german-7d9f8c5b47-2xqkd sni: store-de.example.comDebido a que cada solicitud usó un archivo de autoridad certificadora diferente y ambas se realizaron correctamente, cada backend entregó su propio certificado. El balanceador de cargas reenvió la conexión encriptada sin finalizarla.
Confirma que el enrutamiento se produce durante el protocolo de enlace TLS, antes de que el cliente envíe cualquier solicitud HTTP:
openssl s_client -connect GATEWAY_IP:443 \ -servername store-de.example.com </dev/null 2>/dev/null \ | openssl x509 -noout -subjectEn el resultado, se muestra el certificado del backend
store-german:subject=CN=store-de.example.comCambiar solo el valor de la marca
-servernamemodifica el certificado que se devuelve, lo que confirma que el balanceador de cargas seleccionó el backend solo en función de la SNI.Envía una solicitud con un nombre de host de SNI que no coincida con ningún objeto de escucha:
curl --resolve other.example.com:443:GATEWAY_IP \ https://other.example.comLa conexión se cierra porque ningún objeto de escucha en el puerto
443coincide con el nombre de host de SNIother.example.com.
Configura la capacidad de conexión del backend
Para los Services de GKE a los que hacen referencia los recursos de TLSRoute, el
controlador de Gateway de GKE configura un servicio de backend
de TCP con el modo de balanceo CONNECTION
y establece el valor predeterminado del campo maxConnectionsPerEndpoint
en 100,000,000 (1e8).
Debido a que el controlador de Gateway no puede determinar de forma automática el límite de conexiones
simultáneas de un contenedor, puedes usar un recurso GCPBackendPolicy para anular
el valor predeterminado del campo maxConnectionsPerEndpoint (de 1 a
1,000,000,000). Para determinar el límite de conexiones óptimo para tus Pods
de backend, evalúa lo siguiente:
- Límites de software: Verifica la configuración del servidor o de la aplicación, como
la directiva
MaxRequestWorkersde Apache, la configuración deworker_processes * worker_connectionsde NGINX, el atributomaxConnectionsde Tomcat o los límites del grupo de conexiones de la base de datos. - Pruebas de carga: Aumenta de forma gradual las conexiones simultáneas en un Pod aislado mientras supervisas la CPU, la memoria, la latencia y los límites de sockets o descriptores de archivos.
Aplica una GCPBackendPolicy personalizada
Para anular el valor predeterminado del campo maxConnectionsPerEndpoint en un Service de backend de TLSRoute, adjunta un recurso GCPBackendPolicy con el campo spec.protocol establecido en TCP y el campo balancingMode establecido en CONNECTION:
Guarda el siguiente manifiesto como
backend-policy.yaml:apiVersion: networking.gke.io/v1 kind: GCPBackendPolicy metadata: name: store-v1-backend-policy spec: protocol: TCP default: balancingMode: CONNECTION maxConnectionsPerEndpoint: 1000 targetRef: group: "" kind: Service name: store-v1Aplica la política:
kubectl apply -f backend-policy.yaml
Para obtener más información sobre cómo configurar las políticas de backend, consulta Configura los recursos de Gateway con políticas.
Configura verificaciones de estado para la transferencia de TLS
De forma predeterminada, para los servicios de backend asociados con los recursos de TLSRoute
de transferencia de TLS, el controlador de Gateway de GKE aprovisiona automáticamente
una verificación de estado del tipo SSL.
Controla la ausencia de extensiones de SNI de los agentes de sondeo
Cuando configures verificaciones de estado para backends de transferencia de TLS, debes tener en cuenta cómo interactúan los sistemas de sondeo de verificación de estado de Google Cloud con los extremos de TLS.
Si tus aplicaciones de backend requieren un nombre de host de SNI válido para completar un protocolo de enlace TLS, las verificaciones de estado de SSL predeterminadas fallarán. Para resolver este problema, usa uno de los siguientes enfoques:
- Configura certificados de resguardo: Configura tu servidor de backend o Pod para que entregue un certificado TLS de resguardo predeterminado cuando llegue una conexión TLS sin una extensión de SNI.
- Usa verificaciones de estado de TCP con HealthCheckPolicy: Adjunta un
recurso HealthCheckPolicy (con el campo
config.typeconfigurado comoTCP) a tu Service para verificar la conectividad del puerto TCP sin procesar y evitar el protocolo de enlace TLS.
Aplica una HealthCheckPolicy personalizada
Para configurar parámetros de verificación de estado personalizados o cambiar a la verificación de estado de TCP, usa un recurso HealthCheckPolicy:
Guarda el siguiente manifiesto como
health-check-policy.yaml:apiVersion: networking.gke.io/v1 kind: HealthCheckPolicy metadata: name: store-health-check spec: default: checkIntervalSec: 10 timeoutSec: 5 healthyThreshold: 2 unhealthyThreshold: 3 config: type: TCP tcpHealthCheck: port: 8443 targetRef: group: "" kind: Service name: store-serviceAplica la política:
kubectl apply -f health-check-policy.yaml
Para obtener más información sobre cómo configurar las verificaciones de estado, consulta Configura los recursos de la puerta de enlace con políticas.
Configuración avanzada
En esta sección, se describen los patrones de enrutamiento avanzados, las configuraciones multiusuario y las implementaciones de varios clústeres compatibles con las puertas de enlace de transferencia de TLS y los recursos TLSRoute.
Coincidencia de nombre de host con comodín
Los recursos TLSRoute admiten la coincidencia de prefijos comodín para los nombres de host y siguen reglas de prioridad deterministas cuando varias rutas coinciden con el mismo tráfico entrante.
Guarda el siguiente manifiesto para definir una TLSRoute comodín:
apiVersion: gateway.networking.k8s.io/v1
kind: TLSRoute
metadata:
name: wildcard-tls-route
spec:
parentRefs:
- name: store-tls
sectionName: store
hostnames:
- "*.example.com"
rules:
- backendRefs:
- name: store-v1
port: 443
Reglas de precedencia y resolución de conflictos
Cuando varios recursos TLSRoute se conectan al mismo objeto de escucha de Gateway y reclaman nombres de host superpuestos o idénticos, el controlador de Gateway de GKE resuelve los conflictos con la misma especificidad de nombre de host y las mismas reglas de marca de tiempo de creación que otras rutas de Gateway:
- Las coincidencias exactas de nombres de host (como
store.example.com) tienen prioridad sobre las coincidencias con comodines (como*.example.com), y las coincidencias con comodines más largas tienen prioridad sobre las coincidencias con comodines más amplias (como*.com). - Si dos o más recursos TLSRoute declaran exactamente el mismo nombre de host, la ruta
con la marca de tiempo de creación más antigua (
metadata.creationTimestamp) tiene prioridad. Si las marcas de tiempo de creación coinciden, el identificador<namespace>/<name>lexicográficamente más pequeño desempata. El controlador de Gateway no acepta rutas en conflicto, que informan una condiciónAccepted: Falsecon el motivoConflicted.
Para obtener más información sobre la prioridad de rutas, consulta Combinación, prioridad y validación de rutas.
Enrutamiento entre espacios de nombres con ReferenceGrant
En entornos multiusuario, un equipo de plataforma centralizado puede administrar la
puerta de enlace en un espacio de nombres de infraestructura (como gateway-infra), mientras que
los equipos de aplicaciones administran los recursos TLSRoute y Service en los espacios de nombres de los desarrolladores (como store-ns).
En el objeto de escucha de la puerta de enlace, permite rutas de todos los espacios de nombres (o de los espacios de nombres seleccionados):
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: shared-tls-gateway namespace: gateway-infra spec: gatewayClassName: gke-l7-regional-external-managed listeners: - name: tls-passthrough protocol: TLS port: 443 tls: mode: Passthrough allowedRoutes: namespaces: from: All kinds: - kind: TLSRouteEn el espacio de nombres de la aplicación (
store-ns), crea un recurso ReferenceGrant que permita que la puerta de enlace en el espacio de nombresgateway-infrahaga referencia al recurso TLSRoute o Service:apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: allow-gateway-infra namespace: store-ns spec: from: - group: gateway.networking.k8s.io kind: Gateway namespace: gateway-infra to: - group: "" kind: ServiceEn el espacio de nombres de la aplicación (
store-ns), crea el recurso TLSRoute que hace referencia a la puerta de enlace compartida:apiVersion: gateway.networking.k8s.io/v1 kind: TLSRoute metadata: name: store-tls-route namespace: store-ns spec: parentRefs: - name: shared-tls-gateway namespace: gateway-infra sectionName: tls-passthrough hostnames: - "store.example.com" rules: - backendRefs: - name: store-service port: 443
Puerta de enlace de transferencia de TLS de varios clústeres
Puedes implementar puertas de enlace de varios clústeres con transferencia de TLS en varios clústeres de GKE de una flota:
- Usa una GatewayClass de varios clústeres compatible
(
gke-l7-regional-external-managed-mc,gke-l7-rilb-mcogke-l7-cross-regional-internal-managed-mc). - Exporta tu Service de backend a toda la flota con un recurso ServiceExport.
En tu recurso TLSRoute, haz referencia al backend de varios clústeres con un recurso ServiceImport:
apiVersion: gateway.networking.k8s.io/v1 kind: TLSRoute metadata: name: mc-store-tls-route spec: parentRefs: - name: mc-tls-gateway sectionName: tls-passthrough hostnames: - "store.example.com" rules: - backendRefs: - group: net.gke.io kind: ServiceImport name: store-service port: 443
Varias direcciones IP en Gateways de varios clústeres
Cuando implementas Gateways de varios clústeres interregionales (como cuando usas la
GatewayClass gke-l7-cross-regional-internal-managed-mc), puedes definir
varias direcciones IP en el campo spec.addresses para exponer una VIP interna
en diferentes regiones.
Cuando configuras varias direcciones IP en una sola puerta de enlace, el controlador de puerta de enlace de GKE traduce cada dirección IP en una regla de reenvío independiente. Al mismo tiempo, el controlador hace referencia a un proxy de destino compartido y vuelve a usar la misma configuración de enrutamiento subyacente. El controlador no multiplica los recursos de TLSRoute subyacentes por la cantidad de direcciones IP, lo que ayuda a evitar la duplicación de rutas y el agotamiento de la cuota.
En el siguiente ejemplo, se muestra una puerta de enlace de varios clústeres configurada con direcciones IP efímeras en dos regiones:
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: internal-cross-region-tls-gateway
spec:
gatewayClassName: gke-l7-cross-regional-internal-managed-mc
addresses:
- type: networking.gke.io/ephemeral-ipv4-address/us-west1
value: "us-west1"
- type: networking.gke.io/ephemeral-ipv4-address/us-east1
value: "us-east1"
listeners:
- name: tls-passthrough
protocol: TLS
port: 443
tls:
mode: Passthrough
allowedRoutes:
kinds:
- kind: TLSRoute
Para obtener más información sobre cómo implementar Gateways internas de varios clústeres, consulta Implementa una Gateway interna de varios clústeres.
Unión de conexiones HTTP
Según RFC 7540 (Sección 9.1.1), los navegadores web y los clientes HTTP/2 pueden volver a usar una conexión TLS establecida para varias solicitudes si se cumplen las dos condiciones siguientes:
- Los nombres de host de destino se resuelven en la misma dirección IP.
- El certificado TLS presentado por el servidor es autoritativo para ambos nombres de host.
Por ejemplo, un certificado puede abarcar varios nombres de host cuando usas certificados comodín, como
*.example.com, o nombres alternativos de sujeto (SAN) de varios dominios.
Debido a que un balanceador de cargas de proxy TCP de capa 4 no inspecciona los encabezados de la solicitud HTTP después del protocolo de enlace TLS inicial, el balanceador de cargas reenvía las solicitudes unidas a través de la conexión existente al Pod de backend que coincidió inicialmente.
Para evitar problemas de fusión de conexiones, haz lo siguiente:
- Usa certificados TLS distintos que no se superpongan: No compartas certificados comodín ni identidades de SAN comunes en diferentes servicios de backend multiplexados detrás de la misma dirección IP de la puerta de enlace.
- Retorna HTTP 421 Misdirected Request: Configura tus servidores HTTPS
de backend para que verifiquen el encabezado HTTP
:authority(oHost). Si el host solicitado no coincide con el dominio esperado del servidor, devuelve un código de estadoHTTP 421 Misdirected Request, que solicita al cliente que abra una conexión nueva. - Habilita el marco ORIGIN de HTTP/2: Adopta la compatibilidad con el marco ORIGIN de RFC 8336 en tus servidores de origen y declara de forma explícita qué nombres de host son válidos para la reutilización de conexiones.
Realiza una limpieza
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que usaste en esta página, bórralos:
Borra los recursos TLSRoute:
kubectl delete tlsroute store store-germanBorra el recurso de Gateway:
kubectl delete gateway store-tlsBorra los recursos de Deployment, Service y Secret de ejemplo:
kubectl delete -f store-tls-app.yaml kubectl delete secret store-cert store-de-cert
¿Qué sigue?
- Obtén más información sobre las capacidades de GatewayClass.
- Obtén más información sobre la seguridad de Gateway.
- Obtén más información para configurar los recursos de la puerta de enlace con políticas.