En este documento se explica un ejemplo práctico para desplegar una pasarela interna multiclúster con el fin de enrutar el tráfico dentro de tu red de VPC a una aplicación que se ejecuta en dos clústeres de GKE diferentes.
Las pasarelas de varios clústeres ofrecen una forma eficaz de gestionar el tráfico de los servicios desplegados en varios clústeres de GKE. Si usas la infraestructura de balanceo de carga global de Google, puedes crear un único punto de entrada para tus aplicaciones, lo que simplifica la gestión y mejora la fiabilidad.En este tutorial, usarás una aplicación store de ejemplo para simular una situación real en la que un servicio de compras online es propiedad de equipos independientes y está gestionado por ellos, y se despliega en una flota de clústeres de GKE compartidos.
Antes de empezar
Las pasarelas multiclúster requieren cierta preparación del entorno antes de poder implementarse. Antes de continuar, sigue los pasos que se indican en el artículo Preparar el entorno para usar Gateways multiclúster:
Despliega clústeres de GKE.
Registra tus clústeres en una flota (si aún no lo has hecho).
Habilita los controladores de servicio y de pasarela de varios clústeres.
Por último, consulta las limitaciones y los problemas conocidos del controlador de Gateway de GKE antes de usarlo en tu entorno.
Desplegar una pasarela de varios clústeres interna en varias regiones
Puedes desplegar pasarelas de varios clústeres que proporcionen balanceo de carga interno de capa 7 en clústeres de GKE de varias regiones. Estas pasarelas usan gke-l7-cross-regional-internal-managed-mc GatewayClass. Esta GatewayClass aprovisiona un balanceador de carga de aplicaciones interno entre regiones gestionado por Google Cloud que habilita IPs virtuales internas a las que pueden acceder los clientes de tu red de VPC. Puedes exponer estas pasarelas mediante front-ends en las regiones que elijas. Para ello, solo tienes que usar la pasarela para solicitar direcciones en esas regiones. La dirección IP virtual interna puede ser una sola dirección IP o varias direcciones IP de distintas regiones, con una dirección IP por región especificada en la pasarela. El tráfico se dirige al clúster de GKE de backend en buen estado más cercano que pueda atender la solicitud.
Requisitos previos
Configura tu proyecto y shell configurando tu entorno
gcloudcon el ID de tu proyecto:export PROJECT_ID="YOUR_PROJECT_ID" gcloud config set project ${PROJECT_ID}Crea clústeres de GKE en diferentes regiones.
En este ejemplo se usan dos clústeres:
gke-west-1enus-west1ygke-east-1enus-east1. Asegúrate de que la API Gateway esté habilitada (--gateway-api=standard) y de que los clústeres estén registrados en una flota.gcloud container clusters create gke-west-1 \ --location=us-west1-a \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --project=${PROJECT_ID} \ --enable-fleet \ --gateway-api=standard gcloud container clusters create gke-east-1 \ --location=us-east1-c \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --project=${PROJECT_ID} \ --enable-fleet \ --gateway-api=standardCambiar el nombre de los contextos para acceder a ellos más fácilmente:
gcloud container clusters get-credentials gke-west-1 \ --location=us-west1-a \ --project=${PROJECT_ID} gcloud container clusters get-credentials gke-east-1 \ --location=us-east1-c \ --project=${PROJECT_ID} kubectl config rename-context gke_${PROJECT_ID}_us-west1-a_gke-west-1 gke-west1 kubectl config rename-context gke_${PROJECT_ID}_us-east1-c_gke-east-1 gke-east1Habilita los servicios de varios clústeres (MCS) y la entrada de varios clústeres (MCI o Gateway):
gcloud container fleet multi-cluster-services enable --project=${PROJECT_ID} # Set the config membership to one of your clusters (e.g., gke-west-1) # This cluster will be the source of truth for multi-cluster Gateway and Route resources. gcloud container fleet ingress enable \ --config-membership=projects/${PROJECT_ID}/locations/us-west1/memberships/gke-west-1 \ --project=${PROJECT_ID}Configura subredes de solo proxy. Se necesita una subred de solo proxy en cada región en la que se encuentren tus clústeres de GKE y en la que vaya a funcionar el balanceador de carga. Los balanceadores de carga de aplicación internos entre regiones requieren que el propósito de esta subred se defina como
GLOBAL_MANAGED_PROXY.# Proxy-only subnet for us-west1 gcloud compute networks subnets create us-west1-proxy-only-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=us-west1 \ --network=default \ --range=10.129.0.0/23 # Choose an appropriate unused CIDR range # Proxy-only subnet for us-east1 gcloud compute networks subnets create us-east1-proxy-only-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=us-east1 \ --network=default \ --range=10.130.0.0/23 # Choose an appropriate unused CIDR rangeSi no usas la red predeterminada, sustituye
defaultpor el nombre de tu red de VPC. Asegúrate de que los intervalos CIDR sean únicos y no se solapen.Despliega tus aplicaciones de demostración, como
store, en ambos clústeres. El archivo de ejemplostore.yamldegke-networking-recipescrea un espacio de nombresstorey una implementación.kubectl apply --context gke-west1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml kubectl apply --context gke-east1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yamlExporta los servicios de cada clúster creando recursos
ServiceyServiceExportde Kubernetes en cada clúster, lo que permite que los servicios se puedan descubrir en toda la flota. En el siguiente ejemplo se exportan un serviciostoregenérico y servicios específicos de la región (store-west-1ystore-east-1) de cada clúster, todos ellos en el espacio de nombresstore.Solicitar
gke-west1:cat << EOF | kubectl apply --context gke-west1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-west-1 # Specific to this cluster namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-west-1 # Exporting the region-specific service namespace: store EOFSolicitar
gke-east1:cat << EOF | kubectl apply --context gke-east1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: store --- apiVersion: v1 kind: Service metadata: name: store-east-1 # Specific to this cluster namespace: store spec: selector: app: store ports: - port: 8080 targetPort: 8080 --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store-east-1 # Exporting the region-specific service namespace: store EOFComprueba ServiceImports: Verifica que se hayan creado recursos
ServiceImporten cada clúster del espacio de nombresstore. La creación puede tardar unos minutos.bash kubectl get serviceimports --context gke-west1 -n store kubectl get serviceimports --context gke-east1 -n storeDeberías verstore,store-west-1ystore-east-1(o las entradas correspondientes en función de la propagación).
Configurar una pasarela interna multirregional
Define un recurso Gateway que haga referencia a gke-l7-cross-regional-internal-managed-mc GatewayClass. Aplica este manifiesto al clúster de configuración que hayas designado, como gke-west-1.
El campo spec.addresses te permite solicitar direcciones IP efímeras en regiones concretas o usar direcciones IP estáticas preasignadas.
Para usar direcciones IP efímeras, guarda el siguiente manifiesto
Gatewaycomocross-regional-gateway.yaml:# cross-regional-gateway.yaml kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: internal-cross-region-gateway namespace: store # Namespace for the Gateway resource spec: gatewayClassName: gke-l7-cross-regional-internal-managed-mc addresses: # Addresses across regions. Address value is allowed to be empty or matching # the region name. - 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: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute # Only allow HTTPRoute to attachEn la siguiente lista se definen algunos de los campos del archivo YAML anterior:
metadata.namespace: el espacio de nombres en el que se crea el recurso Gateway (por ejemplo,store).spec.gatewayClassName: el nombre de GatewayClass. Debe sergke-l7-cross-regional-internal-managed-mc.spec.listeners.allowedRoutes.kinds: los tipos de objetos Route que se pueden adjuntar, comoHTTPRoute.spec.addresses:type: networking.gke.io/ephemeral-ipv4-address/REGION: solicita una dirección IP efímera.value: especifica la región de la dirección; por ejemplo,"us-west1"o"us-east1".
Aplica el manifiesto a tu clúster de configuración. Por ejemplo,
gke-west1:kubectl apply --context gke-west1 -f cross-regional-gateway.yaml
Asociar HTTPRoutes a la Gateway
Define los recursos HTTPRoute para gestionar el enrutamiento del tráfico y aplícalos a tu clúster de configuración.
Guarda el siguiente manifiesto
HTTPRoutecomostore-route.yaml:# store-route.yaml kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store-route namespace: store labels: gateway: cross-regional-internal spec: parentRefs: - name: internal-cross-region-gateway namespace: store # Namespace where the Gateway is deployed hostnames: - "store.example.internal" # Hostname clients will use rules: - matches: # Rule for traffic to /west - path: type: PathPrefix value: /west backendRefs: - group: net.gke.io # Indicates a multi-cluster ServiceImport kind: ServiceImport name: store-west-1 # Targets the ServiceImport for the west cluster port: 8080 - matches: # Rule for traffic to /east - path: type: PathPrefix value: /east backendRefs: - group: net.gke.io kind: ServiceImport name: store-east-1 # Targets the ServiceImport for the east cluster port: 8080 - backendRefs: # Default rule for other paths (e.g., /) - group: net.gke.io kind: ServiceImport name: store # Targets the generic 'store' ServiceImport (any region) port: 8080En la siguiente lista se definen algunos de los campos del archivo YAML anterior:
spec.parentRefs: asocia esta ruta ainternal-cross-region-gatewayen el espacio de nombresstore.spec.hostnames: representa el nombre de host que usan los clientes para acceder al servicio.spec.rules: define la lógica de enrutamiento. En este ejemplo se usa el enrutamiento basado en rutas:- El tráfico de
/westse dirige a ServiceImport destore-west-1. - El tráfico de
/eastse dirige a ServiceImportstore-east-1. - El resto del tráfico, como
/, se dirige al ServiceImport genéricostore.
- El tráfico de
backendRefs:group: net.gke.ioykind: ServiceImportse dirigen a servicios de varios clústeres.
Aplica el manifiesto
HTTPRoutea tu clúster de configuración:kubectl apply --context gke-west1 -f store-route.yaml
Verificar el estado de la pasarela y la ruta
Comprueba el estado de la pasarela:
kubectl get gateway internal-cross-region-gateway -n store -o yaml --context gke-west1Busca una condición con el estado
type:Programadoand: "True". You should see IP addresses assigned in thestatus.addressesfield, corresponding to the regions you specified (e.g., one forus-west1and one forus-east1`).Comprueba el estado de HTTPRoute:
kubectl get httproute store-route -n store -o yaml --context gke-west1Busca una condición en
status.parents[].conditionscontype: Accepted(oResolvedRefs) ystatus: "True".
Confirmar tráfico
Después de asignar las direcciones IP a la pasarela, puedes probar el tráfico desde una máquina virtual cliente que esté en tu red de VPC y en una de las regiones, o en una región que pueda conectarse a la dirección IP de la pasarela.
Recupera las direcciones IP de la pasarela.
El siguiente comando intenta analizar el resultado JSON. Es posible que tengas que ajustar el
jsonpathen función de la estructura exacta.kubectl get gateway cross-region-gateway -n store --context gke-west1 -o=jsonpath="{.status.addresses[*].value}".El resultado de este comando debe incluir las IPs virtuales, como
VIP1_WESToVIP2_EAST.Envía solicitudes de prueba: Desde una VM cliente de tu VPC:
# Assuming VIP_WEST is an IP in us-west1 and VIP_EAST is an IP in us-east1 # Traffic to /west should ideally be served by gke-west-1 curl -H "host: store.example.internal" http://VIP_WEST/west curl -H "host: store.example.internal" http://VIP_EAST/west # Still targets store-west-1 due to path # Traffic to /east should ideally be served by gke-east-1 curl -H "host: store.example.internal" http://VIP_WEST/east # Still targets store-east-1 due to path curl -H "host: store.example.internal" http://VIP_EAST/east # Traffic to / (default) could be served by either cluster curl -H "host: store.example.internal" http://VIP_WEST/ curl -H "host: store.example.internal" http://VIP_EAST/La respuesta debe incluir detalles de la aplicación
storeque indiquen qué pod de backend ha servido la solicitud, comocluster_nameozone.
Usar direcciones IP estáticas
En lugar de direcciones IP efímeras, puedes usar direcciones IP internas estáticas preasignadas.
Crea direcciones IP estáticas en las regiones que quieras usar:
gcloud compute addresses create cross-region-gw-ip-west --region us-west1 --subnet default --project=${PROJECT_ID} gcloud compute addresses create cross-region-gw-ip-east --region us-east1 --subnet default --project=${PROJECT_ID}Si no usas la subred predeterminada, sustituye
defaultpor el nombre de la subred que tenga la dirección IP que quieras asignar. Estas subredes son subredes normales, no subredes de solo proxy.Actualiza el manifiesto de la pasarela modificando la sección
spec.addressesde tu archivocross-regional-gateway.yaml:# cross-regional-gateway-static-ip.yaml kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: internal-cross-region-gateway # Or a new name if deploying alongside namespace: store spec: gatewayClassName: gke-l7-cross-regional-internal-managed-mc addresses: - type: networking.gke.io/named-address-with-region # Use for named static IP value: "regions/us-west1/addresses/cross-region-gw-ip-west" - type: networking.gke.io/named-address-with-region value: "regions/us-east1/addresses/cross-region-gw-ip-east" listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRouteAplica el archivo de manifiesto de la pasarela actualizado.
kubectl apply --context gke-west1 -f cross-regional-gateway.yaml
Consideraciones especiales para subredes no predeterminadas
Ten en cuenta lo siguiente cuando uses subredes no predeterminadas:
Misma red de VPC: todos los recursos creados por el usuario, como las direcciones IP estáticas, las subredes solo proxy y los clústeres de GKE, deben residir en la misma red de VPC.
Subred de direcciones: cuando creas direcciones IP estáticas para la pasarela, se asignan desde subredes normales de las regiones especificadas.
Nombres de subredes de clústeres: cada región debe tener una subred con el mismo nombre que la subred en la que se encuentra el clúster de configuración de MCG.
- Por ejemplo, si tu clúster de configuración
gke-west-1está enprojects/YOUR_PROJECT/regions/us-west1/subnetworks/my-custom-subnet, las regiones para las que solicitas direcciones también deben tener la subredmy-custom-subnet. Si solicitas direcciones en las regionesus-east1yus-centra1, también debe haber una subred llamadamy-custom-subneten esas regiones.
- Por ejemplo, si tu clúster de configuración
Limpieza
Después de completar los ejercicios de este documento, siga estos pasos para quitar recursos y evitar que se apliquen cargos no deseados a su cuenta:
Anula el registro de los clústeres de la flota si no es necesario que estén registrados para otro propósito.
Para inhabilitar la función
multiclusterservicediscovery, sigue estos pasos:gcloud container fleet multi-cluster-services disableInhabilita la entrada de varios clústeres:
gcloud container fleet ingress disableInhabilita las APIs:
gcloud services disable \ multiclusterservicediscovery.googleapis.com \ multiclusteringress.googleapis.com \ trafficdirector.googleapis.com \ --project=PROJECT_ID
Solución de problemas
No existe una subred de solo proxy para la pasarela interna
Si aparece el siguiente evento en tu pasarela interna, significa que no existe una subred solo de proxy para esa región. Para solucionar este problema, implementa una subred solo de proxy.
generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/us-west1/targetHttpProxies/gkegw-x5vt-default-internal-http-2jzr7e3xclhj'. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.
No hay upstream en buen estado
Síntoma:
El siguiente problema puede producirse cuando crea una pasarela, pero no puede acceder a los servicios de backend (código de respuesta 503):
no healthy upstream
Motivo:
Este mensaje de error indica que el comprobador de estado no puede encontrar servicios de backend en buen estado. Es posible que tus servicios de backend estén en buen estado, pero que tengas que personalizar las comprobaciones del estado.
Solución alternativa:
Para solucionar este problema, personaliza la comprobación de estado según los requisitos de tu aplicación (por ejemplo, /health) mediante un HealthCheckPolicy.