En este documento, se te guía a través de un ejemplo práctico para implementar una puerta de enlace interna de varios clústeres que enruta el tráfico dentro de tu red de VPC a una aplicación que se ejecuta en dos clústeres de GKE diferentes.
Las Gateways de varios clústeres proporcionan una forma eficaz de administrar el tráfico de los servicios implementados en varios clústeres de GKE. Si usas la infraestructura global de balanceo de cargas de Google, puedes crear un solo punto de entrada para tus aplicaciones, lo que simplifica la administración y mejora la confiabilidad.En este instructivo, usarás una aplicación de ejemplo de store para simular una situación real en la que un servicio de compras en línea es propiedad de equipos independientes y está operado por ellos, y se implementa en una flota de clústeres de GKE compartidos.
Antes de comenzar
Las puertas de enlace de varios clústeres requieren cierta preparación del entorno antes de que puedan implementarse. Antes de continuar, sigue los pasos que se indican en Prepara tu entorno para las puertas de enlace de varios clústeres:
Implemente clústeres de GKE
Registra tus clústeres en una flota (si aún no lo hiciste).
Habilita el Service de varios clústeres y los controladores de puertas de enlace de varios clústeres.
Por último, revisa las limitaciones y los problemas conocidos del controlador de puerta de enlace de GKE antes de usarlo en tu entorno.
Implementa una puerta de enlace interna de varios clústeres en varias regiones
Puedes implementar Gateways de varios clústeres que proporcionan balanceo de cargas interno de capa 7 en clústeres de GKE en varias regiones. Estas puertas de enlace usan la GatewayClass gke-l7-cross-regional-internal-managed-mc. Esta GatewayClass aprovisiona un balanceador de cargas de aplicaciones interno entre regiones que administra Google Cloud y que habilita VIP internas a las que pueden acceder los clientes dentro de tu red de VPC. Los frontends pueden exponer estas puertas de enlace en las regiones que elijas con solo usar la puerta de enlace para solicitar direcciones en esas regiones. La VIP interna puede ser una sola dirección IP o direcciones IP en varias regiones, con una dirección IP por región especificada en la puerta de enlace. El tráfico se dirige al clúster de GKE de backend en buen estado más cercano que puede 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 de 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=standardCambia el nombre de los contextos para facilitar el acceso:
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/puerta de enlace):
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 requiere una subred de solo proxy en cada región en la que se encuentren tus clústeres de GKE y en la que operará el balanceador de cargas. Los balanceadores de cargas de aplicaciones internos entre regiones requieren que el propósito de esta subred se establezca en
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, reemplaza
defaultpor el nombre de tu red de VPC. Asegúrate de que los rangos de CIDR sean únicos y no se superpongan.Implementa tus aplicaciones de demostración, como
store, en ambos clústeres. El archivostore.yamlde ejemplo degke-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.yamlCrea recursos de
ServiceyServiceExportde Kubernetes en cada clúster para exportar los servicios, lo que hace que los servicios se puedan detectar en toda la flota. En el siguiente ejemplo, se exportan un serviciostoregenérico y servicios específicos de la región (store-west-1,store-east-1) desde cada clúster, todo dentro del espacio de nombresstore.Aplicar a
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 EOFAplicar a
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 EOFVerifica los ServiceImports: Verifica que los recursos
ServiceImportse creen en cada clúster dentro del espacio de nombresstore. La creación de los clústeres 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-1en la lista (o las entradas pertinentes según la propagación).
Configura una puerta de enlace interna multirregión
Define un recurso Gateway que haga referencia a la GatewayClass gke-l7-cross-regional-internal-managed-mc. Aplicas este manifiesto a tu clúster de configuración designado, como gke-west-1.
El campo spec.addresses te permite solicitar direcciones IP efímeras en regiones específicas o usar direcciones IP estáticas previamente asignadas.
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: Es el espacio de nombres en el que se crea el recurso de Gateway, por ejemplo,store.spec.gatewayClassName: Es el nombre de GatewayClass. Debe sergke-l7-cross-regional-internal-managed-mc.spec.listeners.allowedRoutes.kinds: Son los tipos de objetos Route que se pueden adjuntar, por ejemplo,HTTPRoute.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
Adjunta HTTPRoutes a la puerta de enlace
Define recursos de HTTPRoute para administrar 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: Adjunta esta ruta ainternal-cross-region-gatewayen el espacio de nombresstore.spec.hostnames: Representa el nombre de host que los clientes usan para acceder al servicio.spec.rules: Define la lógica de enrutamiento. En este ejemplo, se usa el enrutamiento basado en rutas de acceso:- El tráfico de
/westva a la ServiceImportstore-west-1. - El tráfico de
/eastva a la ServiceImportstore-east-1. - Todo el resto del tráfico, como
/, se dirige al objeto ServiceImport genéricostore.
- El tráfico de
backendRefs:group: net.gke.ioykind: ServiceImportsegmentan los servicios de varios clústeres.
Aplica el manifiesto de
HTTPRoutea tu clúster de configuración:kubectl apply --context gke-west1 -f store-route.yaml
Verifica el estado de la puerta de enlace y la ruta
Verifica el estado de la puerta de enlace:
kubectl get gateway internal-cross-region-gateway -n store -o yaml --context gke-west1Busca una condición con el estado
type:Programmedandstatus: "True". You should see IP addresses assigned in thestatus.addressesfield, corresponding to the regions you specified (e.g., one forus-west1and one forus-east1”).Verifica 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".
Confirma el tráfico
Después de asignar las direcciones IP a la puerta de enlace, puedes probar el tráfico desde una VM cliente que se encuentre dentro de tu red de VPC y en una de las regiones, o en una región que se pueda conectar a la dirección IP de la puerta de enlace.
Recupera las direcciones IP de la puerta de enlace.
El siguiente comando intenta analizar el resultado JSON. Es posible que debas ajustar el
jsonpathsegún 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 VIP, como
VIP1_WESToVIP2_EAST.Envía solicitudes de prueba: Desde una VM cliente en tu VPC, haz lo siguiente:
# 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 atendió la solicitud, comocluster_nameozone.
Usa direcciones IP estáticas
En lugar de direcciones IP efímeras, puedes usar direcciones IP internas estáticas asignadas previamente.
Crea direcciones IP estáticas en las regiones que deseas 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, reemplaza
defaultpor el nombre de la subred que tiene la dirección IP que deseas asignar. Estas subredes son subredes normales, no subredes de solo proxy.Actualiza el manifiesto de Gateway modificando la sección
spec.addressesen 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 manifiesto de Gateway actualizado.
kubectl apply --context gke-west1 -f cross-regional-gateway.yaml
Consideraciones especiales para las subredes no predeterminadas
Ten en cuenta las siguientes consideraciones cuando uses subredes no predeterminadas:
La misma red de VPC: Todos los recursos creados por el usuario, como las direcciones IP estáticas, las subredes de 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 puerta de enlace, se asignan desde subredes normales en las regiones especificadas.
Nombres de subredes del clúster: Cada región debe tener una subred con el mismo nombre que la subred en la que reside 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 existir una subred llamadamy-custom-subneten esas regiones.
- Por ejemplo, si tu clúster de configuración
Realiza una limpieza
Después de completar los ejercicios de este documento, sigue estos pasos para quitar los recursos a fin de prevenir cobros no deseados en tu cuenta:
Anula el registro de tus clústeres en la flota si no es necesario que estén registrados para otro propósito.
Inhabilita la función
multiclusterservicediscovery:gcloud container fleet multi-cluster-services disableInhabilitar entrada de varios clústeres
gcloud container fleet ingress disableInhabilita las API:
gcloud services disable \ multiclusterservicediscovery.googleapis.com \ multiclusteringress.googleapis.com \ trafficdirector.googleapis.com \ --project=PROJECT_ID
Soluciona problemas
No existe la subred de solo proxy para la puerta de enlace interna
Si el siguiente evento aparece en tu puerta de enlace interna, no existe una subred de solo proxy para esa región. Para resolver este problema, implementa una subred de solo 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.
Sin upstream en buen estado
Síntoma:
El siguiente problema puede ocurrir cuando creas una puerta de enlace, pero no puedes acceder a los servicios de backend (código de respuesta 503):
no healthy upstream
Motivo:
Este mensaje de error indica que el sistema de sondeo de verificación de estado no puede encontrar servicios de backend en buen estado. Es posible que tus servicios de backend estén en buen estado, pero es posible que debas personalizar las verificaciones de estado.
Solución alternativa:
Para resolver este problema, personaliza la verificación de estado según los requisitos de tu aplicación (por ejemplo, /health) mediante un HealthCheckPolicy.
¿Qué sigue?
- Obtén más información sobre el controlador de puerta de enlace.