Implementa puertas de enlace de varios clústeres


En esta página, se describe cómo implementar recursos de puerta de enlace de Kubernetes para el balanceo de cargas del tráfico de entrada en varios clústeres de Google Kubernetes Engine (GKE) (o flota). Antes de implementar puertas de enlace de varios clústeres, consulta Habilita las puertas de enlace de varios clústeres para preparar tu entorno.

Para implementar puertas de enlace con el balanceo de cargas del tráfico de entrada en un solo clúster de GKE, consulta Implementa puertas de enlace.

Puertas de enlace de varios clústeres

Una puerta de enlace de varios clústeres es un recurso de las puertas de enlace que balancea las cargas del tráfico en varios clústeres de Kubernetes. En GKE, las GatewayClasses gke-l7-global-external-managed-mc, gke-l7-regional-external-managed-mc, gke-l7-rilb-mc y gke-l7-gxlb-mc implementan puertas de enlace de varios clústeres que proporcionan enrutamiento HTTP, división de tráfico, duplicación de tráfico, conmutación por error basada en el estado y más en diferentes clústeres de GKE, espacios de nombres de Kubernetes y en diferentes regiones. Con las puertas de enlace de varios clústeres, la administración de herramientas de redes de aplicaciones en varios clústeres y equipos es fácil, segura y escalable para los administradores de infraestructura.

Una puerta de enlace de varios clústeres es un recurso de puerta de enlace que balancea las cargas del tráfico en varios clústeres de Kubernetes.

En esta página, se presentan tres ejemplos para enseñarte a implementar puertas de enlace de varios clústeres con el controlador de puerta de enlace de GKE:

  • Ejemplo 1: Una puerta de enlace externa de varios clústeres que proporciona balanceo de cargas en dos clústeres de GKE para el tráfico de Internet.
  • Ejemplo 2: Una puerta de enlace privada de capa 7 entre regiones.
  • Ejemplo 3: División del tráfico azul-verde basada en peso y duplicación de tráfico en dos clústeres de GKE para el tráfico de VPC interno.
  • Ejemplo 4: Una puerta de enlace basada en la capacidad para balancear las cargas de solicitudes a diferentes backends según su capacidad máxima.

En cada uno de los ejemplos, se usarán las mismas aplicaciones de tienda y sitio para modelar una situación real en la que equipos diferentes controlan y administran un servicio de compras en línea y un servicio de sitio web que a su vez están implementados en una flota de clústeres de GKE compartidos. En cada uno de los ejemplos, se destacan diferentes topologías y casos de uso habilitados por puertas de enlace de varios clústeres.

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 en Habilita puertas de enlace de varios clústeres:

  1. Implemente clústeres de GKE

  2. Registra tus clústeres en una flota.

  3. Habilita el Service de varios clústeres y los controladores de puertas de enlace de varios clústeres.

Por último, revisa el controlador de puerta de enlace de GKE Vista previa de las limitaciones y problemas conocidos antes de usarlo en tu entorno.

Puerta de enlace externa, varios clústeres y varias regiones

En este instructivo, crearás una puerta de enlace externa de varios clústeres con la que se entrega tráfico externo en una aplicación que se ejecuta en dos clústeres de GKE.

store.example.com se implementa en dos clústeres de GKE y se expone a Internet a través de una puerta de enlace de varios clústeres.

En los siguientes pasos, haz lo siguiente:

  1. Implementa la aplicación store de muestra en los clústeres gke-west-1 y gke-east-1.
  2. Configura los servicios en cada clúster que se exportará a tu flota (servicios de varios clústeres).
  3. Implementa una puerta de enlace externa de varios clústeres y una HTTPRoute en tu clúster de configuración (gke-west-1).

Después de implementar la aplicación y los recursos de las puertas de enlace, puedes controlar el tráfico en los dos clústeres de GKE con el enrutamiento basado en rutas de acceso:

  • Las solicitudes a /west se enrutan a los Pods store en el clúster gke-west-1.
  • Las solicitudes a /east se enrutan a los Pods store en el clúster gke-east-1.
  • Las solicitudes a cualquier otra ruta de acceso se enrutan a cualquiera de los clústeres, según su estado, capacidad y proximidad al cliente solicitante.

Implementa la aplicación de demostración

  1. Crea la implementación store y el espacio de nombres en los tres clústeres que se implementaron en Habilita puertas de enlace de varios clústeres:

    kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    kubectl apply --context gke-east-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store.yaml
    

    Implementa los siguientes recursos en cada clúster:

    namespace/store created
    deployment.apps/store created
    

    En todos los ejemplos de esta página, se usa la app implementada en este paso. Asegúrate de que la app se implemente en los tres clústeres antes de probar cualquiera de los pasos restantes. En este ejemplo, solo se usan los clústeres gke-west-1 y gke-east-1, y gke-west-2 se usa en otro ejemplo.

Service de varios clústeres

Los servicios son la forma en que los Pods se exponen a los clientes. Debido a que el controlador de puertas de enlace de GKE usa el balanceo de cargas nativo del contenedor, no usa el balanceo de cargas de ClusterIP o Kubernetes para llegar a los Pods. El tráfico se envía directamente desde el balanceador de cargas a las direcciones IP del Pod. Sin embargo, los objetos de Service desempeñan una función crítica como un identificador lógico para la agrupación de Pods.

Los servicios de varios clústeres (MCS) son un estándar de API para los Services que abarcan clústeres y a través de su controlador de GKE se ofrece un descubrimiento de servicios en clústeres de GKE. El controlador de la puerta de enlace de varios clústeres usa recursos de la API de MCS para agrupar Pods en un Service que se pueda dirigir a varios profesionales o a través de ellos.

La API de Services de varios clústeres define los siguientes recursos personalizados:

  • ServiceExports asigna a un Service de Kubernetes mediante la exportación de los extremos de ese Service a todos los clústeres registrados en la flota. Cuando un Service tiene una ServiceExport correspondiente, significa que se puede abordar con una puerta de enlace de varios clústeres.
  • Con el controlador de Service de varios clústeres se genera ServiceImports de forma automática. ServiceExport y ServiceImport vienen en pares. Si existe una ServiceExport en la flota, se crea una ServiceImport correspondiente para permitir que se acceda al Service asignado a ServiceExport desde todos los clústeres.

La exportación de Services funciona de la siguiente manera. Existe un Service de almacenamiento en gke-west-1 que selecciona un grupo de Pods en ese clúster. Se crea una ServiceExport en el clúster que permite que se pueda acceder a los Pods en gke-west-1 desde los otros clústeres de la flota. ServiceExport se asignará a los Services que tengan el mismo nombre y el mismo espacio de nombres que el recurso de ServiceExport y los expondrá.

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

En el siguiente diagrama, se muestra lo que sucede después de implementar una ServiceExport. Si existe un par Service y ServiceExport, el controlador de Service de varios clústeres implementa una ServiceImport correspondiente en cada clúster de GKE de la flota. ServiceImport es la representación local del Service store en cada clúster. Esto permite que el client Pod en gke-east-1 use ClusterIP o los Service sin interfaz gráfica para llegar a los store Pods en gke-west-1 Cuando se usan de esta manera, los Service de varios clústeres proporcionan un balanceo de cargas este-oeste entre clústeres sin necesidad de un Service LoadBalancer interno. Si deseas usar los Service de varios clústeres para el balanceo de cargas de clúster a clúster, consulta Configura Service de varios clústeres.

Los Services de varios clústeres exportan Services entre clústeres que permiten la comunicación de clúster a clúster

Las puertas de enlace de varios clústeres también usan ServiceImports, pero no para el balanceo de cargas de clúster a clúster. En cambio, las puerta de enlace usan ServiceImports como identificadores lógicos para un Service que existe en otro clúster o que se extiende a varios clústeres. La siguiente HTTPRoute hace referencia a una ServiceImport en lugar de un recurso de Service. Si se hace referencia a una ServiceImport, esto indica que reenvía el tráfico a un grupo de Pods de backend que se ejecutan en uno o más clústeres.

kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: store-route
  namespace: store
  labels:
    gateway: multi-cluster-gateway
spec:
  parentRefs:
  - kind: Gateway
    namespace: store
    name: external-http
  hostnames:
  - "store.example.com"
  rules:
  - backendRefs:
    - group: net.gke.io
      kind: ServiceImport
      name: store
      port: 8080

En el siguiente diagrama, se muestra cómo la HTTPRoute enruta el tráfico store.example.com a los Pods store en gke-west-1 y gke-east-1. El balanceador de cargas los trata como un grupo de backends. Si los Pods de uno de los clústeres se encuentran en mal estado, son inaccesibles o no tienen capacidad de tráfico, la carga de tráfico se balancea a los Pods restantes en el otro clúster. Los clústeres nuevos se pueden agregar o quitar con el Service store y ServiceExport. Esto agregará o quitará con transparencia los Pods de backend sin ningún cambio explícito en la configuración del enrutamiento.

Recurso de MCS

Exporta Services

En este punto, la aplicación se ejecuta en ambos clústeres. A continuación, deberás exponer las aplicaciones y exportarlas mediante la implementación de objetos Service y ServiceExports en cada clúster.

  1. Aplica el siguiente manifiesto al clúster gke-west-1 para crear tus Services y servicios y exportaciones de store y store-west-1:

    cat << EOF | kubectl apply --context gke-west-1 -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
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store-west-1
      namespace: store
    EOF
    
  2. Aplica el siguiente manifiesto al clúster gke-east-1 para crear tus Services y servicios y exportaciones de store y store-east-1:

    cat << EOF | kubectl apply --context gke-east-1 -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
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store-east-1
      namespace: store
    EOF
    
  3. Verifica que se hayan creado las ServiceExports correctas en el clúster.

    kubectl get serviceexports --context CLUSTER_NAME --namespace store
    

    Reemplaza CLUSTER_NAME por gke-west-1 y gke-east-1. El resultado debe parecerse al siguiente:

    # gke-west-1
    NAME           AGE
    store          2m40s
    store-west-1   2m40s
    
    # gke-east-1
    NAME           AGE
    store          2m25s
    store-east-1   2m25s
    

    Esto demuestra que el Service store contiene Pods store en ambos clústeres, mientras que los Service store-west-1 y store-east-1 solo contienen Pods store en sus clústeres respectivos. Estos Service superpuestos se usan para apuntar a los Pods en varios clústeres o en un subconjunto de Pods en un solo clúster.

  4. Después de unos minutos, verifica que el controlador de Services de varios clústeres haya creado de forma automática el ServiceImports adjunto en todos los clústeres de la flota.

    kubectl get serviceimports --context CLUSTER_NAME --namespace store
    

    Reemplaza CLUSTER_NAME por gke-west-1 y gke-east-1. El resultado debe parecerse al siguiente:

    # gke-west-1
    NAME           TYPE           IP                  AGE
    store          ClusterSetIP   ["10.112.31.15"]    6m54s
    store-east-1   ClusterSetIP   ["10.112.26.235"]   5m49s
    store-west-1   ClusterSetIP   ["10.112.16.112"]   6m54s
    
    # gke-east-1
    NAME           TYPE           IP                  AGE
    store          ClusterSetIP   ["10.72.28.226"]    5d10h
    store-east-1   ClusterSetIP   ["10.72.19.177"]    5d10h
    store-west-1   ClusterSetIP   ["10.72.28.68"]     4h32m
    

    Esto demuestra que se puede acceder a los tres Services desde ambos clústeres en la flota. Sin embargo, debido a que solo hay un clúster de configuración activo por flota, solo puedes implementar puertas de enlace y HTTPRouters que hagan referencia a estas ServiceImports en gke-west-1. Cuando una HTTPRouter en el clúster de configuración hace referencia a estas ServiceImports como backends, la puerta de enlace puede reenviar tráfico a estos servicios sin importar desde qué clúster se exporten.

Implementa la puerta de enlace y HTTPRouter

Una vez que se implementaron las aplicaciones, puedes configurar una puerta de enlace con la GatewayClass gke-l7-global-external-managed-mc. Con esta puerta de enlace se crea un balanceador de cargas de aplicaciones externo configurado para distribuir el tráfico entre los clústeres de destino.

  1. Aplica el siguiente manifiesto Gateway al clúster de configuración, gke-west-1 en este ejemplo:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: external-http
      namespace: store
    spec:
      gatewayClassName: gke-l7-global-external-managed-mc
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    EOF
    

    A través de esta configuración de puerta de enlace se implementan recursos externos del balanceador de cargas de aplicaciones con la siguiente convención de nombres: gkemcg1-NAMESPACE-GATEWAY_NAME-HASH.

    Los recursos predeterminados creados con esta configuración son los siguientes:

    • 1 Balanceador de cargas: gkemcg1-store-external-http-HASH
    • 1 Dirección IP pública: gkemcg1-store-external-http-HASH
    • 1 Regla de reenvío: gkemcg1-store-external-http-HASH
    • 2 Servicios de backend:
      • Configuración predeterminada 404 de servicio de backend gkemcg1-store-gw-serve404-HASH
      • Configuración predeterminada 500 de servicio de backend gkemcg1-store-gw-serve500-HASH
    • 1 Verificación de estado
      • Verificación de estado 404 predeterminada: gkemcg1-store-gw-serve404-HASH
    • 0 reglas de enrutamiento (el mapa de URL está vacío)

    En esta etapa, cualquier solicitud a GATEWAY_IP:80 dará como resultado una página predeterminada que muestra el siguiente mensaje: fault filter abort.

  2. Aplica el siguiente manifiesto HTTPRoute al clúster de configuración, gke-west-1 en este ejemplo:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: public-store-route
      namespace: store
      labels:
        gateway: external-http
    spec:
      hostnames:
      - "store.example.com"
      parentRefs:
      - name: external-http
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /west
        backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store-west-1
          port: 8080
      - matches:
        - path:
            type: PathPrefix
            value: /east
        backendRefs:
          - group: net.gke.io
            kind: ServiceImport
            name: store-east-1
            port: 8080
      - backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store
          port: 8080
    EOF
    

    En esta etapa, cualquier solicitud a GATEWAY_IP:80 dará como resultado una página predeterminada que muestra el siguiente mensaje: fault filter abort.

    Una vez implementada, esta HTTPRoute configurará el siguiente comportamiento de enrutamiento:

    • Las solicitudes a /west se enrutan a los Pods store en el clúster gke-west-1, ya que los Pods que selecciona la ServiceExport store-west-1 solo existen en el clúster gke-west-1.
    • Las solicitudes a /east se enrutan a los Pods store en el clúster gke-east-1, porque los Pods que selecciona la ServiceExport store-east-1 solo existen en el clúster gke-east-1.
    • Las solicitudes a cualquier otra ruta de acceso se enrutan en store los Pods en cualquiera de los clústeres, según su estado, capacidad y proximidad al cliente solicitante.
    • Las solicitudes a GATEWAY_IP:80 generarán una página predeterminada que muestra el siguiente mensaje: fault filter abort.

    El HTTPRoute permite el enrutamiento a diferentes subconjuntos de clústeres mediante servicios superpuestos

    Ten en cuenta que si todos los Pods en un clúster determinado están en mal estado (o no existen), el tráfico al Service store solo se enviará a los clústeres que en realidad tengan Pods store. La existencia de una ServiceExport y un Service en un clúster determinado no garantiza que el tráfico se envíe a ese clúster. Los Pods deben existir y responder de manera afirmativa a la verificación de estado del balanceador de cargas. De lo contrario, el balanceador de cargas solo enviará tráfico a Pods store en buen estado en otros clústeres.

    Se crean recursos nuevos con esta configuración:

    • 3 Servicios de backend
      • El storeservicio de backendgkemcg1-store-store-8080-HASH
      • El store-east-1servicio de backendgkemcg1-store-store-east-1-8080-HASH
      • El store-west-1servicio de backendgkemcg1-store-store-west-1-8080-HASH
    • 3 Verificaciones de estado (
        )
      • La storeverificación de estado gkemcg1-store-store-8080-HASH
      • La store-east-1verificación de estado gkemcg1-store-store-east-1-8080-HASH
      • La store-west-1verificación de estado gkemcg1-store-store-west-1-8080-HASH
    • 1 regla de enrutamiento en el URLmap:
      • La store.example.comregla de enrutamiento:
      • 1 Host: store.example.com
      • Varios matchRules para enrutar a los nuevos servicios de backend

En el siguiente diagrama, se muestran los recursos que implementaste en ambos clústeres. Debido a que gke-west-1 es el clúster de configuración de puerta de enlace, es el clúster en el que el controlador de puerta de enlace observa nuestras puerta de enlace, HTTPRoutes y ServiceImports. Cada clúster tiene una ServiceImport store y otra ServiceImport específica para ese clúster. Ambos apuntan a los mismos Pods. Esto permite que HTTPRoute especifique con exactitud dónde debe ir el tráfico: a los Pods store en un clúster específico o a los Pods store en todos los clústeres.

Este es el modelo de recursos de los Services de las puertas de enlace y de varios clústeres en ambos clústeres

Ten en cuenta que este es un modelo de recursos lógico, no una descripción del flujo de tráfico. La ruta de tráfico va directamente del balanceador de cargas a los Pods de backend y no tiene relación directa con el clúster que es el clúster de configuración.

Valida la implementación

Ahora puedes emitir solicitudes a nuestra puerta de enlace de varios clústeres y distribuir el tráfico entre varios clústeres de GKE.

  1. Verifica que la puerta de enlace y la HTTPRoute se hayan implementado de forma correcta inspeccionando del estado y los eventos de la puerta de enlace.

    kubectl describe gateways.gateway.networking.k8s.io external-http --context gke-west-1 --namespace store
    

    El resultado debería ser similar al siguiente:

    Name:         external-http
    Namespace:    store
    Labels:       <none>
    Annotations:  networking.gke.io/addresses: /projects/PROJECT_NUMBER/global/addresses/gkemcg1-store-external-http-laup24msshu4
                  networking.gke.io/backend-services:
                    /projects/PROJECT_NUMBER/global/backendServices/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/backendServices/gke...
                  networking.gke.io/firewalls: /projects/PROJECT_NUMBER/global/firewalls/gkemcg1-l7-default-global
                  networking.gke.io/forwarding-rules: /projects/PROJECT_NUMBER/global/forwardingRules/gkemcg1-store-external-http-a5et3e3itxsv
                  networking.gke.io/health-checks:
                    /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-store-gw-serve404-80-n65xmts4xvw2, /projects/PROJECT_NUMBER/global/healthChecks/gkemcg1-s...
                  networking.gke.io/last-reconcile-time: 2023-10-12T17:54:24Z
                  networking.gke.io/ssl-certificates:
                  networking.gke.io/target-http-proxies: /projects/PROJECT_NUMBER/global/targetHttpProxies/gkemcg1-store-external-http-94oqhkftu5yz
                  networking.gke.io/target-https-proxies:
                  networking.gke.io/url-maps: /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-store-external-http-94oqhkftu5yz
    API Version:  gateway.networking.k8s.io/v1beta1
    Kind:         Gateway
    Metadata:
      Creation Timestamp:  2023-10-12T06:59:32Z
      Finalizers:
        gateway.finalizer.networking.gke.io
      Generation:        1
      Resource Version:  467057
      UID:               1dcb188e-2917-404f-9945-5f3c2e907b4c
    Spec:
      Gateway Class Name:  gke-l7-global-external-managed-mc
      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:  34.36.127.249
      Conditions:
        Last Transition Time:  2023-10-12T07:00:41Z
        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-12T07:00:41Z
        Message:
        Observed Generation:   1
        Reason:                Accepted
        Status:                True
        Type:                  Accepted
        Last Transition Time:  2023-10-12T07:00:41Z
        Message:
        Observed Generation:   1
        Reason:                Programmed
        Status:                True
        Type:                  Programmed
        Last Transition Time:  2023-10-12T07:00:41Z
        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-12T07:00:41Z
          Message:
          Observed Generation:   1
          Reason:                Programmed
          Status:                True
          Type:                  Programmed
          Last Transition Time:  2023-10-12T07:00:41Z
          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  UPDATE  35m (x4 over 10h)      mc-gateway-controller  store/external-http
      Normal  SYNC    4m22s (x216 over 10h)  mc-gateway-controller  SYNC on store/external-http was a success
    
  2. Una vez que la puerta de enlace se implementó correctamente, recupera la dirección IP externa de la puerta de enlace external-http.

    kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
    

    Reemplaza VIP en los siguientes pasos por la dirección IP que recibas como resultado.

  3. Envía tráfico a la ruta raíz del dominio. Esto balancea las cargas del tráfico a la ServiceImport store, que se encuentra en los clústeres gke-west-1 y gke-east-1. El balanceador de cargas envía tu tráfico a la región más cercana a ti y es posible que no veas respuestas de la otra región.

    curl -H "host: store.example.com" http://VIP
    

    El resultado confirma que el Pod entregó la solicitud desde el clúster gke-east-1:

    {
      "cluster_name": "gke-east-1",
      "zone": "us-east1-b",
      "host_header": "store.example.com",
      "node_name": "gke-gke-east-1-default-pool-7aa30992-t2lp.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-dg22z",
      "pod_name_emoji": "⏭",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:32:51"
    }
    
  4. A continuación, envía el tráfico a la ruta /west. Esto enruta el tráfico a la ServiceImport store-west-1, que solo tiene Pods en ejecución en el clúster gke-west-1. Un objeto ServiceImport específico del clúster, como store-west-1, permite que el propietario de una aplicación envíe tráfico de forma explícita a un clúster específico, en lugar de permitir que el balanceador de cargas tome la decisión.

    curl -H "host: store.example.com" http://VIP/west
    

    El resultado confirma que el Pod entregó la solicitud desde el clúster gke-west-1:

    {
      "cluster_name": "gke-west-1", 
      "zone": "us-west1-a", 
      "host_header": "store.example.com",
      "node_name": "gke-gke-west-1-default-pool-65059399-2f41.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-d25m5",
      "pod_name_emoji": "🍾",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:39:15",
    }
    
  5. Por último, envía tráfico a la ruta /east.

    curl -H "host: store.example.com" http://VIP/east
    

    El resultado confirma que el Pod entregó la solicitud desde el clúster gke-east-1:

    {
      "cluster_name": "gke-east-1",
      "zone": "us-east1-b",
      "host_header": "store.example.com",
      "node_name": "gke-gke-east-1-default-pool-7aa30992-7j7z.c.agmsb-k8s.internal",
      "pod_name": "store-5f5b954888-hz6mw",
      "pod_name_emoji": "🧜🏾",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-06-01T17:40:48"
    }
    

Implementa una puerta de enlace interna de varios clústeres en varias regiones

Puedes implementar puertas de enlace de varios clústeres que proporcionen balanceo de cargas interno de la 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 VIPs internos a los que pueden acceder los clientes dentro de tu red de VPC. Los frontends pueden exponer estas puertas de enlace en las regiones que elijas, simplemente con 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 que se especifica en la puerta de enlace. El tráfico se dirige al clúster de GKE de backend en buen estado más cercano que pueda entregar la solicitud.

Antes de comenzar

  1. Configura tu proyecto y shell configurando tu entorno gcloud con el ID de tu proyecto:

    export PROJECT_ID="YOUR_PROJECT_ID"
    gcloud config set project ${PROJECT_ID}
    
  2. Crear clústeres de GKE en diferentes regiones

    En este ejemplo, se usan dos clústeres: gke-west-1 en us-west1 y gke-east-1 en us-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=standard
    

    Cambia 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-east1
    
  3. Habilita 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}
    
  4. Configura subredes de solo proxy. Se requiere una subred de solo proxy en cada región donde se encuentran tus clústeres de GKE y donde operará el balanceador de cargas. El balanceador de cargas de aplicaciones interno entre regiones requiere 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 range
    

    Si no usas la red predeterminada, reemplaza default por el nombre de tu red de VPC. Asegúrate de que los rangos CIDR sean únicos y no se superpongan.

  5. Implementa tus aplicaciones de demostración, como store, en ambos clústeres. El archivo store.yaml de ejemplo de gke-networking-recipes crea un espacio de nombres store y 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.yaml
    
  6. Para exportar servicios desde cada clúster, crea recursos Service y ServiceExport de Kubernetes en cada clúster, lo que permite que los servicios sean detectables en toda la flota. En el siguiente ejemplo, se exporta un servicio store genérico y servicios específicos de la región (store-west-1, store-east-1) de cada clúster, todo dentro del espacio de nombres store.

    Aplica 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
    EOF
    

    Aplica 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
    EOF
    
  7. Verifica ServiceImports: Verifica que se creen recursos ServiceImport en cada clúster dentro del espacio de nombres store. Es posible que tarden unos minutos en crearse. bash kubectl get serviceimports --context gke-west1 -n store kubectl get serviceimports --context gke-east1 -n store Deberías ver store, store-west-1 y store-east-1 en la lista (o las entradas relevantes 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 preasignadas.

  1. Para usar direcciones IP efímeras, guarda el siguiente manifiesto Gateway como cross-regional-gateway.yaml:

    # cross-regional-gateway.yaml
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    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 attach
    

    En 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 la puerta de enlace, por ejemplo, store.
    • spec.gatewayClassName: Es el nombre de GatewayClass. Debe ser gke-l7-cross-regional-internal-managed-mc.
    • spec.listeners.allowedRoutes.kinds: Son los tipos de objetos de ruta 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".
  2. 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 HTTPRoute para administrar el enrutamiento del tráfico y aplicarlos a tu clúster de configuración.

  1. Guarda el siguiente manifiesto HTTPRoute como store-route.yaml:

    # store-route.yaml
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    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: 8080
    

    En la siguiente lista, se definen algunos de los campos del archivo YAML anterior:

    • spec.parentRefs: Conecta esta ruta a cross-region-gateway en el espacio de nombres store.
    • 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 la ruta:
      • El tráfico de /west va a ServiceImport de store-west-1.
      • El tráfico de /east va a ServiceImport de store-east-1.
      • El resto del tráfico, como /, se dirige al ServiceImport genérico store.
    • backendRefs:
      • group: net.gke.io y kind: ServiceImport se orientan a servicios de varios clústeres.
  2. Aplica el manifiesto de HTTPRoute a 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

  1. Verifica el estado de la puerta de enlace:

    kubectl get gateway cross-region-gateway -n store -o yaml --context gke-west1
    

    Busca una condición con el estado type:Programadaand: "True". You should see IP addresses assigned in thestatus.addressesfield, corresponding to the regions you specified (e.g., one forus-west1and one forus-east1`).

  2. Verifica el estado de HTTPRoute:

    kubectl get httproute store-route -n store -o yaml --context gke-west1
    

    Busca una condición en status.parents[].conditions con type: Accepted (o ResolvedRefs) y status: "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 pueda conectarse a la dirección IP de la puerta de enlace.

  1. Recupera las direcciones IP de la puerta de enlace.

    El siguiente comando intenta analizar el resultado JSON. Es posible que debas ajustar el jsonpath segú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 los VIP, como VIP1_WEST o VIP2_EAST.

  2. Envía solicitudes de prueba: Desde una VM de cliente en 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 store que indiquen qué pod de backend entregó la solicitud, como cluster_name o zone.

Usa direcciones IP estáticas

En lugar de direcciones IP efímeras, puedes usar direcciones IP internas estáticas preasignadas.

  1. 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 default por el nombre de la subred que tiene la dirección IP que deseas asignar. Estas subredes son subredes normales, no subredes de solo proxy.

  2. Para actualizar el manifiesto de la puerta de enlace, modifica la sección spec.addresses en el archivo cross-regional-gateway.yaml:

    # cross-regional-gateway-static-ip.yaml
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    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-west1/addresses/cross-region-gw-ip-east"
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    
  3. Aplica el manifiesto de la puerta de enlace actualizado.

    kubectl apply --context gke-west1 -f cross-regional-gateway.yaml
    

Consideraciones especiales para subredes que no son predeterminadas

Ten en cuenta las siguientes consideraciones cuando uses subredes no predeterminadas:

  • 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 de clústeres: Cada región debe tener una subred que tenga 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 de gke-west-1 está en projects/YOUR_PROJECT/regions/us-west1/subnetworks/my-custom-subnet, las regiones para las que solicitas direcciones también deben tener la subred my-custom-subnet. Si solicitas direcciones en las regiones us-east1 y us-centra1, también debe existir una subred llamada my-custom-subnet en esas regiones.

Enrutamiento azul-verde y de varios clústeres con puerta de enlace

Las GatewayClasses gke-l7-global-external-managed-*, gke-l7-regional-external-managed-* y gke-l7-rilb-* tienen muchas capacidades avanzadas de enrutamiento de tráfico, que incluyen la división del tráfico, la coincidencia del encabezado, la manipulación del encabezado, la duplicación de tráfico y mucho más. En este ejemplo, demostrarás cómo usar la división de tráfico basada en la ponderación para controlar de forma explícita la proporción de tráfico en dos clústeres de GKE.

En este ejemplo, se explican algunos pasos realistas que seguiría un propietario del servicio para trasladar o expandir su aplicación a un clúster de GKE nuevo. El objetivo de las implementaciones azul-verde es reducir el riesgo mediante varios pasos de validación que confirman que el clúster nuevo funciona de forma correcta. En este ejemplo, se explican cuatro etapas de implementación:

  1. 100%-versión canary basada en encabezados: Usa el enrutamiento de encabezado HTTP para enviar solo tráfico sintético o de prueba al clúster nuevo.
  2. 100%-duplicación del tráfico: Duplica el tráfico de usuario al clúster de versión canary. Esto prueba la capacidad del clúster de versión canary mediante la copia del 100% del tráfico de usuario en este clúster.
  3. 90%-10%: Versión canary de una división del tráfico del 10% para exponer lentamente el clúster nuevo al tráfico en vivo.
  4. 0%-100%: Adopta una migración de sistemas completa al clúster nuevo con la opción de volver a la anterior si se observan errores.

División del tráfico azul-verde en dos clústeres de GKE

Este ejemplo es similar al anterior, excepto que implementa una puerta de enlace de varios clústeres interna en su lugar. De esta manera, se implementa un balanceador de cargas de aplicaciones interno al que solo se puede acceder de forma privada desde la VPC. Usarás los clústeres y la misma aplicación que implementaste en los pasos anteriores, con la excepción de que los implementarás a través de una puerta de enlace diferente.

Requisitos previos

El siguiente ejemplo se basa en algunos de los pasos de Implementa una puerta de enlace de varios clústeres externa. Antes de continuar con este ejemplo, asegúrate de haber realizado los siguientes pasos:

  1. Habilitar puertas de enlace de varios clústeres

  2. Implementa una aplicación de demostración

    En este ejemplo, se usan los clústeres gke-west-1 y gke-west-2 que ya configuraste. Estos clústeres están en la misma región porque GatewayClass gke-l7-rilb-mc es regional y solo admite backends de clúster en la misma región.

  3. Implementa el Service y las ServiceExports necesarios en cada clúster. Si implementaste Services y ServiceExports del ejemplo anterior, ya implementaste algunos de estos.

    kubectl apply --context gke-west-1 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-1-service.yaml
    kubectl apply --context gke-west-2 -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/multi-cluster-gateway/store-west-2-service.yaml
    

    Implementa un conjunto similar de recursos en cada clúster:

    service/store created
    serviceexport.net.gke.io/store created
    service/store-west-2 created
    serviceexport.net.gke.io/store-west-2 created
    

Configura una subred de solo proxy

Si aún no lo has hecho, configura una subred de solo proxy para cada región en la que implementes puertas de enlace einternas. Esta subred se usa para proporcionar direcciones IP internas a los proxies de balanceador de cargas y debe configurarse solo con un --purpose configurado como REGIONAL_MANAGED_PROXY.

Debes crear una subred de solo proxy antes de crear puertas de enlace con las que se administren los balanceadores de cargas de aplicaciones internos. Cada región de una red de nube privada virtual (VPC) en la que uses balanceadores de cargas de aplicaciones internos debe tener una subred de solo proxy.

Con el comando gcloud compute networks subnets create, se 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 proxy
  • REGION: La región de la subred de solo proxy
  • VPC_NETWORK_NAME: El nombre de la red de VPC que contiene la subred
  • CIDR_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.

Implementa la Gateway

La siguiente puerta de enlace se crea a partir de la puerta de enlace gke-l7-rilb-mc, que es una puerta de enlace interna regional que solo puede apuntar a clústeres de GKE en la misma región.

  1. Aplica el siguiente manifiesto Gateway al clúster de configuración, gke-west-1 en este ejemplo:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-http
      namespace: store
    spec:
      gatewayClassName: gke-l7-rilb-mc
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    EOF
    
  2. Verifica que la puerta de enlace haya aparecido correctamente. Puedes filtrar solo los eventos de esta puerta de enlace con el siguiente comando:

    kubectl get events --field-selector involvedObject.kind=Gateway,involvedObject.name=internal-http --context=gke-west-1 --namespace store
    

    La implementación de la puerta de enlace se realizó de forma correcta si el resultado es similar al siguiente:

    LAST SEEN   TYPE     REASON   OBJECT                  MESSAGE
    5m18s       Normal   ADD      gateway/internal-http   store/internal-http
    3m44s       Normal   UPDATE   gateway/internal-http   store/internal-http
    3m9s        Normal   SYNC     gateway/internal-http   SYNC on store/internal-http was a success
    

Versión canary basada en encabezados

La versión canary basada en encabezados permite que el propietario del servicio haga coincidir el tráfico de prueba sintético que no proviene de usuarios reales. Esta es una forma fácil de validar que la red básica de la aplicación está funcionando sin exponer a los usuarios directamente.

  1. Aplica el siguiente manifiesto HTTPRoute al clúster de configuración, gke-west-1 en este ejemplo:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      # Matches for env=canary and sends it to store-west-2 ServiceImport
      - matches:
        - headers:
          - name: env
            value: canary
        backendRefs:
          - group: net.gke.io
            kind: ServiceImport
            name: store-west-2
            port: 8080
      # All other traffic goes to store-west-1 ServiceImport
      - backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store-west-1
          port: 8080
    EOF
    

    Una vez implementado, este HTTPRoute configura el siguiente comportamiento de enrutamiento:

    • Las solicitudes internas a store.example.internal sin el encabezado HTTP env: canary se enrutan a los Pods store en el clúster gke-west-1.
    • Las solicitudes internas a store.example.internal con el encabezado HTTP env: canary se enrutan a los Pods store en el clúster gke-west-2.

    La HTTPRoute permite el enrutamiento a clústeres diferentes en función de los encabezados HTTP

    Envía tráfico a la dirección IP de la puerta de enlace para validar que la HTTPRoute funcione correctamente.

  2. Recupera la dirección IP interna de internal-http.

    kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}" --context gke-west-1 --namespace store
    

    Reemplaza VIP en los siguientes pasos por la dirección IP que recibas como resultado.

  3. Envía una solicitud a la puerta de enlace con el encabezado HTTP env: canary. Esto confirmará que el tráfico se enruta a gke-west-2. Usa un cliente privado en la misma VPC que los clústeres de GKE para confirmar que las solicitudes se enrutan de forma correcta. El siguiente comando debe ejecutarse en una máquina que tenga acceso privado a la dirección IP de la puerta de enlace o no funcionará.

    curl -H "host: store.example.internal" -H "env: canary" http://VIP
    

    El resultado confirma que un Pod entregó la solicitud desde el clúster gke-west-2:

    {
        "cluster_name": "gke-west-2", 
        "host_header": "store.example.internal",
        "node_name": "gke-gke-west-2-default-pool-4cde1f72-m82p.c.agmsb-k8s.internal",
        "pod_name": "store-5f5b954888-9kdb5",
        "pod_name_emoji": "😂",
        "project_id": "agmsb-k8s",
        "timestamp": "2021-05-31T01:21:55",
        "zone": "us-west1-a"
    }
    

Duplicación de tráfico

En esta etapa, se envía el tráfico al clúster deseado, pero también se duplica ese tráfico en el clúster de versión canary.

El uso de la duplicación es útil para determinar cómo la carga de tráfico afectará el rendimiento de la aplicación sin afectar de ninguna manera las respuestas a los clientes. Puede no ser necesario para todos los tipos de implementaciones, pero puede ser útil cuando se implementan cambios grandes que podrían afectar el rendimiento o la carga.

  1. Aplica el siguiente manifiesto HTTPRoute al clúster de configuración, gke-west-1 en este ejemplo:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      # Sends all traffic to store-west-1 ServiceImport
      - backendRefs:
        - name: store-west-1
          group: net.gke.io
          kind: ServiceImport
          port: 8080
        # Also mirrors all traffic to store-west-2 ServiceImport
        filters:
        - type: RequestMirror
          requestMirror:
            backendRef:
              group: net.gke.io
              kind: ServiceImport
              name: store-west-2
              port: 8080
    EOF
    
  2. Con tu cliente privado, envía una solicitud a la puerta de enlace internal-http. Usa la ruta de acceso /mirror para poder identificar de forma única esta solicitud en los registros de la aplicación en un paso posterior.

    curl -H "host: store.example.internal" http://VIP/mirror
    
  3. El resultado confirma que el cliente recibió una respuesta de un Pod en el clúster gke-west-1:

    {
        "cluster_name": "gke-west-1", 
        "host_header": "store.example.internal",
        "node_name": "gke-gke-west-1-default-pool-65059399-ssfq.c.agmsb-k8s.internal",
        "pod_name": "store-5f5b954888-brg5w",
        "pod_name_emoji": "🎖",
        "project_id": "agmsb-k8s",
        "timestamp": "2021-05-31T01:24:51",
        "zone": "us-west1-a"
    }
    

    Esto confirma que el clúster principal responde al tráfico. Aún debes confirmar que el clúster al que migras reciba tráfico duplicado.

  4. Verifica los registros de la aplicación de un Pod store en el clúster gke-west-2. Los registros deben confirmar que el Pod recibió tráfico duplicado del balanceador de cargas.

    kubectl logs deployment/store --context gke-west-2 -n store | grep /mirror
    
  5. Este resultado confirma que los Pods en el clúster gke-west-2 también reciben las mismas solicitudes. Sin embargo, sus respuestas a estas solicitudes no se envían al cliente. Las direcciones IP que se ven en los registros son las de las direcciones IP internas del balanceador de cargas que se comunican con los Pods.

    Found 2 pods, using pod/store-5c65bdf74f-vpqbs
    [2023-10-12 21:05:20,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:20] "GET /mirror HTTP/1.1" 200 -
    [2023-10-12 21:05:27,158] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 -
    [2023-10-12 21:05:27,805] INFO in _internal: 192.168.21.3 - - [12/Oct/2023 21:05:27] "GET /mirror HTTP/1.1" 200 -
    

División del tráfico

La división del tráfico es uno de los métodos más comunes para implementar código nuevo o implementar en entornos nuevos de forma segura. El propietario del servicio establece un porcentaje explícito de tráfico que se envía a los backends de versión canary, que suele ser una cantidad muy pequeña del tráfico general para que el éxito de la implementación se pueda determinar con una cantidad aceptable de riesgos para las solicitudes de usuarios reales.

Si se hace una división del tráfico con una minoría del tráfico, el propietario del servicio puede inspeccionar el estado de la aplicación y las respuestas. Si todos los indicadores se ven en buen estado, puede continuar con la migración de sistemas completa.

  1. Aplica el siguiente manifiesto HTTPRoute al clúster de configuración, gke-west-1 en este ejemplo:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
      - backendRefs:
        # 90% of traffic to store-west-1 ServiceImport
        - name: store-west-1
          group: net.gke.io
          kind: ServiceImport
          port: 8080
          weight: 90
        # 10% of traffic to store-west-2 ServiceImport
        - name: store-west-2
          group: net.gke.io
          kind: ServiceImport
          port: 8080
          weight: 10
    EOF
    
  2. Con tu cliente privado, envía una solicitud curl continua a la puerta de enlaceinternal- http.

    while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
    

    El resultado será similar a este, lo que indica que se está realizando una división del tráfico de 90/10.

    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-1",
    "cluster_name": "gke-west-1",
    ...
    

Migración de tráfico

La última etapa de la migración azul-verde es migrar por completo al clúster nuevo y quitar el clúster anterior. Si el propietario del servicio estuviera integrando un segundo clúster a un clúster existente, este último paso sería diferente, ya que el último paso tendría tráfico hacia ambos clústeres. En ese caso, se recomienda una sola ServiceImport store que tenga Pods de los clústeres gke-west-1 y gke-west-2. Esto permite que con el balanceador de cargas se puede decidir a dónde debe dirigirse el tráfico para una aplicación activa-activa, según la proximidad, el estado y la capacidad.

  1. Aplica el siguiente manifiesto HTTPRoute al clúster de configuración, gke-west-1 en este ejemplo:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: internal-store-route
      namespace: store
      labels:
        gateway: internal-http
    spec:
      parentRefs:
      - kind: Gateway
        namespace: store
        name: internal-http
      hostnames:
      - "store.example.internal"
      rules:
        - backendRefs:
          # No traffic to the store-west-1 ServiceImport
          - name: store-west-1
            group: net.gke.io
            kind: ServiceImport
            port: 8080
            weight: 0
          # All traffic to the store-west-2 ServiceImport
          - name: store-west-2
            group: net.gke.io
            kind: ServiceImport
            port: 8080
            weight: 100
    EOF
    
  2. Con tu cliente privado, envía una solicitud curl continua a la puerta de enlaceinternal- http.

    while true; do curl -H "host: store.example.internal" -s VIP | grep "cluster_name"; sleep 1; done
    

    El resultado será similar a este, lo que indica que todo el tráfico se dirige ahora a gke-west-2.

    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    "cluster_name": "gke-west-2",
    ...
    

En este último paso, se completa una migración de aplicación azul-verde de un clúster de GKE a otro.

Implementa el balanceo de cargas basado en la capacidad

En el ejercicio de esta sección, se muestran los conceptos del balanceo de cargas global y la capacidad del Service mediante la implementación de una aplicación en dos clústeres de GKE en diferentes regiones. El tráfico generado se envía en varios niveles de solicitudes por segundo (RPS) para mostrar cómo se balancean las cargas del tráfico entre los clústeres y las regiones.

En el siguiente diagrama, se muestra la topología que implementarás y cómo el tráfico se desborda entre clústeres y regiones cuando el tráfico supera la capacidad del Service:

Tráfico desbordándose de un clúster a otro

Para obtener más información sobre la administración del tráfico, consulta Administración del tráfico de GKE.

Prepare el entorno

  1. Sigue Habilita puertas de enlace de varios clústeres para preparar tu entorno.

  2. Confirma que los recursos de GatewayClass estén instalados en el clúster de configuración:

    kubectl get gatewayclasses --context=gke-west-1
    

    El resultado es similar a este:

    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
    

Implementa una aplicación

Implementa el servidor de aplicaciones web de muestra 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 es similar a este:

namespace/store created
deployment.apps/store created

Implementa un Service, una puerta de enlace y una HTTPRoute

  1. Aplica el siguiente manifiesto Service a los clústeres gke-west-1 y gke-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
    EOF
    
    cat << 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
    EOF
    

    El Service se anota con max-rate-per-endpoint configurado en 10 solicitudes por segundo. Con 2 réplicas por clúster, cada Service tiene 20 RPS de capacidad por clúster.

    A fin de obtener más información sobre cómo elegir un nivel de capacidad de servicio para tu Service, consulta Determina la capacidad de tu Service.

  2. Aplica el siguiente manifiesto Gateway al clúster de configuración, gke-west-1 en este ejemplo:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    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
    EOF
    

    En el manifiesto, se describe una puerta de enlace externa, global y de varios clústeres que implementa un balanceador de cargas de aplicaciones externo con una dirección IP de acceso público.

  3. Aplica el siguiente manifiesto HTTPRoute al clúster de configuración, gke-west-1 en este ejemplo:

    cat << EOF | kubectl apply --context gke-west-1 -f -
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    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
    EOF
    

    El manifiesto describe una HTTPRoute que configura la puerta de enlace con una regla de enrutamiento que dirige todo el tráfico al ServiceImport de almacenamiento. Los storegrupos de ServiceImport store agrupa los Pods del Service de almacenamiento en ambos clústeres y permite que los balanceadores de cargas se dirijan a ellos como un solo Service.

    Puedes verificar los eventos de la puerta de enlace después de unos minutos para ver si finalizó la implementación:

    kubectl describe gateway store -n traffic-test --context gke-west-1
    

    El resultado es similar a este:

    ...
    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 success
    

    En este resultado, se muestra que la puerta de enlace se implementó de forma correcta. Es posible que el tráfico tarde unos minutos en comenzar a pasar después de que se implemente la puerta de enlace. Toma nota de la dirección IP en este resultado, ya que se usa en el siguiente paso.

Confirma el tráfico

Para confirmar que el tráfico pase a la aplicación, prueba la dirección IP de la puerta de enlace con un comando curl:

curl GATEWAY_IP_ADDRESS

El resultado es similar a este:

{
  "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 entregó la solicitud.

Verifica el tráfico mediante pruebas de carga

Para verificar que el balanceador de cargas funcione, puedes implementar 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 cargas. En los siguientes pasos, se demuestran tres niveles de carga:

  • 10 RPS, que está por debajo de la capacidad del Service de almacenamiento en gke-west-1.
  • 30 RPS, que está por sobre la capacidad para el Service de almacenamiento gke-west-1 y provoca un desbordamiento de tráfico a gke-east-1.
  • 60 RPS, que está por sobre la capacidad de los Services en ambos clústeres.

Configurar panel

  1. Obtén el nombre del URLmap subyacente para tu puerta de enlace:

    kubectl get gateway store -n traffic-test --context=gke-west-1 -o=jsonpath="{.metadata.annotations.networking\.gke\.io/url-maps}"
    

    El resultado es similar a este:

    /projects/PROJECT_NUMBER/global/urlMaps/gkemcg1-traffic-test-store-armvfyupay1t
    
  2. En la consola de Google Cloud , ve a la página Explorador de métricas.

    Ir al Explorador de métricas

  3. En Seleccionar una métrica, haz clic en CÓDIGO: MQL.

  4. Ingresa la siguiente consulta para observar las métricas de tráfico del Service de almacenamiento 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)]
    

    Reemplaza GATEWAY_URL_MAP por el nombre del URLmap del paso anterior.

  5. Haga clic en Run query. Espera al menos 5 minutos después de implementar el generador de cargas en la siguiente sección para que las métricas se muestren en el gráfico.

Realiza pruebas con 10 RPS

  1. Implementa 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'
    

    Reemplaza GATEWAY_IP_ADDRESS por la dirección IP de la puerta de enlace del paso anterior.

    El resultado es similar al 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 cargas envía de forma continua 10 RPS a la puerta de enlace. Aunque el tráfico proviene de una región de Google Cloud , el balanceador de cargas lo trata como el tráfico de clientes que proviene de la costa oeste de EE.UU. Para simular una diversidad de clientes realista, el generador de cargas envía cada solicitud HTTP como una conexión TCP nueva, lo que significa que el tráfico se distribuye de manera más uniforme entre los Pods de backend.

    El generador tarda hasta 5 minutos en generar tráfico para el panel.

  2. Ve el panel Explorador de métricas. Aparecen dos líneas que indican cuánto tráfico tiene balanceo de cargas en cada clúster:

    Gráfico que muestra el tráfico con balanceo de cargas a los clústeres

    Deberías ver que us-west1-a recibe alrededor de 10 RPS de tráfico, mientras que us-east1-b no recibe tráfico. Debido a que el generador de tráfico se ejecuta en us-west1, todo el tráfico se envía al Service en el clúster gke-west-1.

  3. Detén el generador de cargas con Ctrl+C y, luego, borra el Pod:

    kubectl delete pod loadgen --context gke-west-1
    

Realiza pruebas con 30 RPS

  1. Vuelve a implementar el generador de cargas, pero configúralo 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.

  2. Ve el panel de Cloud Ops.

    Gráfico que muestra el tráfico que se desborda a gke-east-1

    Deberías ver que se envían alrededor de 20 RPS a us-west1-a y 10 RPS a us-east1-b. Esto indica que el Service en gke-west-1 se usa por completo y desborda 10 RPS de tráfico al Service en gke-east-1.

  3. Detén el generador de cargas con Ctrl+C y, luego, borra el Pod:

    kubectl delete pod loadgen --context gke-west-1
    

Realiza pruebas con 60 RPS

  1. Implementa el generador de cargas 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'
    
  2. Espera 5 minutos y ve tu panel Cloud Ops. Ahora, debería mostrar que ambos clústeres reciben aproximadamente 30 RPS. Dado que todos los Services están sobreutilizados a nivel global, no hay desbordamiento de tráfico y los Services absorben todo el tráfico que pueden.

    Gráfico que muestra los Services sobreutilizados

  3. Detén el generador de cargas con Ctrl+C y, luego, borra el Pod:

    kubectl delete pod loadgen --context gke-west-1
    

Limpia

Después de completar los ejercicios de esta página, sigue estos pasos para quitar los recursos a fin de prevenir cobros no deseados en tu cuenta:

  1. Borra los clústeres.

  2. Anula el registro de tus clústeres en la flota si no es necesario que estén registrados para otro propósito.

  3. Inhabilita la función multiclusterservicediscovery:

    gcloud container fleet multi-cluster-services disable
    
  4. Inhabilitar entrada de varios clústeres

    gcloud container fleet ingress disable
    
  5. Inhabilita las API:

    gcloud services disable \
        multiclusterservicediscovery.googleapis.com \
        multiclusteringress.googleapis.com \
        trafficdirector.googleapis.com \
        --project=PROJECT_ID
    

Usa la puerta de enlace de varios clústeres con VPC compartida

Una puerta de enlace de varios clústeres también se puede implementar en un entorno de VPC compartida, con diferentes topologías, según el caso de uso.

En la siguiente tabla, se describen las topologías de las puertas de enlace de varios clústeres compatibles dentro de un entorno de VPC compartida:

Situación Proyecto host de flotas Clúster de configuración Clústeres de cargas de trabajo
1 Proyecto de host de VPC compartida Proyecto de host de VPC compartida Proyecto de host de VPC compartida
2 Proyecto de servicio de VPC compartida Proyecto de servicio de VPC compartida
(igual que el proyecto de servicio de la flota)
Proyecto de servicio de VPC compartida
(igual que el proyecto de servicio de la flota)

Para crear puertas de enlace de varios clústeres en un entorno de VPC compartida, sigue estos pasos:

  1. Sigue los pasos para configurar los Services de varios clústeres con una VPC compartida.

  2. Crea tus servicios y expórtalos al clúster de configuración

  3. Si planeas usar una puerta de enlace interna de varios clústeres, crea una subred de solo proxy.

  4. Crea tu puerta de enlace externa o interna de varios clústeres y HTTPRoutes

Una vez que hayas completado estos pasos, puedes validar la implementación según tu topología.

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?