En este documento se explica cómo desplegar una aplicación de muestra en dos clústeres de GKE de diferentes regiones y se muestra cómo Multi-cluster Gateway enruta el tráfico de forma inteligente cuando supera los límites de capacidad del servicio.
El balanceo de carga basado en la capacidad es una función de las pasarelas de varios clústeres que te ayuda a crear aplicaciones fiables y resistentes. Si defines la capacidad de tus servicios, puedes protegerlos de la sobrecarga y ofrecer una experiencia coherente a tus usuarios. Cuando un servicio de un clúster alcanza su capacidad, el balanceador de carga redirige automáticamente el tráfico a otro clúster con capacidad disponible. Para obtener más información sobre la gestión del tráfico, consulta Gestión del tráfico de GKE.
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 el balanceo de carga basado en la capacidad
En el ejercicio de esta sección se muestran los conceptos de balanceo de carga global y capacidad de servicio desplegando una aplicación en dos clústeres de GKE de diferentes regiones. El tráfico generado se envía a varios niveles de solicitudes por segundo (RPS) para mostrar cómo se equilibra la carga del tráfico en los clústeres y las regiones.
En el siguiente diagrama se muestra la topología que vas a implementar y cómo se desborda el tráfico entre clústeres y regiones cuando el tráfico ha superado la capacidad del servicio:
Prepara tu entorno
Sigue los pasos que se indican en el artículo Preparar el entorno para usar Gateways multiclúster.
Confirma que los recursos de GatewayClass están instalados en el clúster de configuración:
kubectl get gatewayclasses --context=gke-west-1El resultado debería ser similar al siguiente:
NAME CONTROLLER ACCEPTED AGE gke-l7-global-external-managed networking.gke.io/gateway True 16h gke-l7-global-external-managed-mc networking.gke.io/gateway True 14h gke-l7-gxlb networking.gke.io/gateway True 16h gke-l7-gxlb-mc networking.gke.io/gateway True 14h gke-l7-regional-external-managed networking.gke.io/gateway True 16h gke-l7-regional-external-managed-mc networking.gke.io/gateway True 14h gke-l7-rilb networking.gke.io/gateway True 16h gke-l7-rilb-mc networking.gke.io/gateway True 14h
Desplegar una aplicación
Despliega el servidor de la aplicación web de ejemplo en ambos clústeres:
kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/store-traffic-deploy.yaml
El resultado debería ser similar al siguiente:
namespace/store created
deployment.apps/store created
Desplegar un servicio, una pasarela y una ruta HTTP
Aplica el siguiente manifiesto
Servicea los clústeresgke-west-1ygke-east-1:cat << EOF | kubectl apply --context gke-west-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: traffic-test annotations: networking.gke.io/max-rate-per-endpoint: "10" spec: ports: - port: 8080 targetPort: 8080 name: http selector: app: store type: ClusterIP --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: traffic-test EOFcat << EOF | kubectl apply --context gke-east-1 -f - apiVersion: v1 kind: Service metadata: name: store namespace: traffic-test annotations: networking.gke.io/max-rate-per-endpoint: "10" spec: ports: - port: 8080 targetPort: 8080 name: http selector: app: store type: ClusterIP --- kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: store namespace: traffic-test EOFEl servicio se anota con
max-rate-per-endpointdefinido en 10 solicitudes por segundo. Con 2 réplicas por clúster, cada servicio tiene una capacidad de 20 RPS por clúster.Para obtener más información sobre cómo elegir un nivel de capacidad de servicio, consulta Determinar la capacidad de un servicio.
Aplica el siguiente manifiesto
Gatewayal clúster de configuración,gke-west-1en este ejemplo:cat << EOF | kubectl apply --context gke-west-1 -f - kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: store namespace: traffic-test spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - name: http protocol: HTTP port: 80 allowedRoutes: kinds: - kind: HTTPRoute EOFEl manifiesto describe una Gateway externa, global y multiclúster que implementa un balanceador de carga de aplicación externo con una dirección IP accesible públicamente.
Aplica el siguiente manifiesto
HTTPRouteal clúster de configuración,gke-west-1en este ejemplo:cat << EOF | kubectl apply --context gke-west-1 -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store namespace: traffic-test labels: gateway: store spec: parentRefs: - kind: Gateway namespace: traffic-test name: store rules: - backendRefs: - name: store group: net.gke.io kind: ServiceImport port: 8080 EOFEl manifiesto describe un HTTPRoute que configura la Gateway con una regla de enrutamiento que dirige todo el tráfico al ServiceImport de la tienda. El
storeServiceImport agrupa losstorepods de servicio de ambos clústeres y permite que el balanceador de carga los trate como un único servicio.Puedes consultar los eventos de la pasarela al cabo de unos minutos para ver si se ha terminado de implementar:
kubectl describe gateway store -n traffic-test --context gke-west-1El resultado debería ser similar al siguiente:
... Status: Addresses: Type: IPAddress Value: 34.102.159.147 Conditions: Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has deprecated this condition, do not depend on it. Observed Generation: 1 Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2023-10-12T21:40:59Z Message: Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2023-10-12T21:40:59Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reservedit for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 12m mc-gateway-controller traffic-test/store Normal SYNC 6m43s mc-gateway-controller traffic-test/store Normal UPDATE 5m40s (x4 over 12m) mc-gateway-controller traffic-test/store Normal SYNC 118s (x6 over 10m) mc-gateway-controller SYNC on traffic-test/store was a successEste resultado muestra que la pasarela se ha desplegado correctamente. Puede que el tráfico tarde unos minutos en empezar a pasar después de que se haya implementado la pasarela. Anota la dirección IP de este resultado, ya que se usará en un paso posterior.
Confirmar tráfico
Confirma que el tráfico se está enviando a la aplicación probando la dirección IP de la pasarela con un comando curl:
curl GATEWAY_IP_ADDRESS
El resultado debería ser similar al siguiente:
{
"cluster_name": "gke-west-1",
"host_header": "34.117.182.69",
"pod_name": "store-54785664b5-mxstv",
"pod_name_emoji": "👳🏿",
"project_id": "project",
"timestamp": "2021-11-01T14:06:38",
"zone": "us-west1-a"
}
En este resultado se muestran los metadatos del pod, que indican la región desde la que se ha atendido la solicitud.
Verificar el tráfico mediante pruebas de carga
Para verificar que el balanceador de carga funciona, puedes desplegar un generador de tráfico en tu clúster gke-west-1. El generador de tráfico genera tráfico en diferentes niveles de carga para demostrar la capacidad y las funciones de desbordamiento del balanceador de carga. En los siguientes pasos se muestran tres niveles de carga:
- 10 RPS, que es inferior a la capacidad del servicio de la tienda en
gke-west-1. - 30 RPS, que supera la capacidad del servicio de tienda
gke-west-1y provoca un desbordamiento del tráfico agke-east-1. - 60 RPS, que supera la capacidad de los servicios de ambos clústeres.
Configurar el panel de control
Obtén el nombre del mapa de URLs subyacente de tu Gateway:
kubectl get gateway store -n traffic-test --context=gke-west-1 -o=jsonpath="{.metadata.annotations.networking\.gke\.io/url-maps}"El resultado debería ser similar al siguiente:
/projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-traffic-test-store-armvfyupay1tEn la Google Cloud consola, ve a la página Explorador de métricas.
En Seleccionar una métrica, haga clic en CÓDIGO: MQL.
Introduce la siguiente consulta para observar las métricas de tráfico del servicio de la tienda en tus dos clústeres:
fetch https_lb_rule | metric 'loadbalancing.googleapis.com/https/backend_request_count' | filter (resource.url_map_name == 'GATEWAY_URL_MAP') | align rate(1m) | every 1m | group_by [resource.backend_scope], [value_backend_request_count_aggregate: aggregate(value.backend_request_count)]Sustituye
GATEWAY_URL_MAPpor el nombre de la asignación de URLs del paso anterior.Haz clic en Realizar una consulta. Espera al menos 5 minutos después de implementar el generador de carga de la siguiente sección para que las métricas se muestren en el gráfico.
Prueba con 10 RPS
Despliega un pod en tu clúster
gke-west-1:kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 10'Sustituye
GATEWAY_IP_ADDRESSpor la dirección IP de la puerta de enlace del paso anterior.La salida es similar a la siguiente, lo que indica que el generador de tráfico está enviando tráfico:
If you don't see a command prompt, try pressing enter.El generador de carga envía continuamente 10 RPS a la puerta de enlace. Aunque el tráfico proceda de una región de Google Cloud , el balanceador de carga lo trata como tráfico de clientes procedente de la costa oeste de EE. UU. Para simular una diversidad de clientes realista, el generador de carga envía cada solicitud HTTP como una nueva conexión TCP, lo que significa que el tráfico se distribuye de forma más uniforme entre los pods de backend.
El generador tarda hasta 5 minutos en generar tráfico para el panel de control.
Consulta tu panel de control Explorador de métricas. Aparecen dos líneas que indican la cantidad de tráfico que se balancea de carga en cada uno de los clústeres:

Deberías ver que
us-west1-arecibe aproximadamente 10 RPS de tráfico, mientras queus-east1-bno recibe tráfico. Como el generador de tráfico se ejecuta enus-west1, todo el tráfico se envía al servicio del clústergke-west-1.Detén el generador de carga con Ctrl+C y, a continuación, elimina el pod:
kubectl delete pod loadgen --context gke-west-1
Prueba con 30 RPS
Vuelve a implementar el generador de carga, pero configurado para enviar 30 RPS:
kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 30'El generador tarda hasta 5 minutos en generar tráfico para el panel de control.
Consulta tu panel de control de Cloud Ops.

Deberías ver que se envían aproximadamente 20 RPS a
us-west1-ay 10 RPS aus-east1-b. Esto indica que el servicio degke-west-1está totalmente utilizado y que se está transfiriendo un exceso de 10 RPS de tráfico al servicio degke-east-1.Detén el generador de carga con Ctrl+C y, a continuación, elimina el pod:
kubectl delete pod loadgen --context gke-west-1
Prueba con 60 RPS
Implementa el generador de carga configurado para enviar 60 RPS:
kubectl run --context gke-west-1 -i --tty --rm loadgen \ --image=cyrilbkr/httperf \ --restart=Never \ -- /bin/sh -c 'httperf \ --server=GATEWAY_IP_ADDRESS \ --hog --uri="/zone" --port 80 --wsess=100000,1,1 --rate 60'Espera 5 minutos y consulta tu panel de control de Cloud Ops. Ahora debería mostrar que ambos clústeres reciben aproximadamente 30 RPS. Como todos los servicios están sobreutilizados a nivel mundial, no hay desbordamiento de tráfico y los servicios absorben todo el tráfico que pueden.

Detén el generador de carga con Ctrl+C y, a continuación, elimina el pod:
kubectl delete pod loadgen --context gke-west-1
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 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.