Implementa una puerta de enlace interna de varios clústeres

En este documento, se te guía a través de un ejemplo práctico para implementar una puerta de enlace interna de varios clústeres que enruta el tráfico dentro de tu red de VPC a una aplicación que se ejecuta en dos clústeres de GKE diferentes.

Las Gateways de varios clústeres proporcionan una forma eficaz de administrar el tráfico de los servicios implementados en varios clústeres de GKE. Si usas la infraestructura global de balanceo de cargas de Google, puedes crear un solo punto de entrada para tus aplicaciones, lo que simplifica la administración y mejora la confiabilidad.

En este instructivo, usarás una aplicación de ejemplo de store para simular una situación real en la que un servicio de compras en línea es propiedad de equipos independientes y está operado por ellos, y se implementa en una flota de clústeres de GKE compartidos.

En este ejemplo, se muestra cómo configurar el enrutamiento basado en rutas para dirigir el tráfico a diferentes clústeres.

Antes de comenzar

Las puertas de enlace de varios clústeres requieren cierta preparación del entorno antes de que puedan implementarse. Antes de continuar, sigue los pasos que se indican en Prepara tu entorno para las puertas de enlace de varios clústeres:

  1. Implemente clústeres de GKE

  2. Registra tus clústeres en una flota (si aún no lo hiciste).

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

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

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

Puedes implementar Gateways de varios clústeres que proporcionan balanceo de cargas interno de capa 7 en clústeres de GKE en varias regiones. Estas puertas de enlace usan la GatewayClass gke-l7-cross-regional-internal-managed-mc. Esta GatewayClass aprovisiona un balanceador de cargas de aplicaciones interno entre regiones que administra Google Cloud y que habilita VIP internas a las que pueden acceder los clientes dentro de tu red de VPC. Los frontends pueden exponer estas puertas de enlace en las regiones que elijas con solo usar la puerta de enlace para solicitar direcciones en esas regiones. La VIP interna puede ser una sola dirección IP o direcciones IP en varias regiones, con una dirección IP por región especificada en la puerta de enlace. El tráfico se dirige al clúster de GKE de backend en buen estado más cercano que puede atender la solicitud.

Requisitos previos

  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. Crea 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 en la que se encuentren tus clústeres de GKE y en la que operará el balanceador de cargas. Los balanceadores de cargas de aplicaciones internos entre regiones requieren que el propósito de esta subred se establezca en GLOBAL_MANAGED_PROXY.

    # Proxy-only subnet for us-west1
    gcloud compute networks subnets create us-west1-proxy-only-subnet \
        --purpose=GLOBAL_MANAGED_PROXY \
        --role=ACTIVE \
        --region=us-west1 \
        --network=default \
        --range=10.129.0.0/23 # Choose an appropriate unused CIDR range
    
    # Proxy-only subnet for us-east1
    gcloud compute networks subnets create us-east1-proxy-only-subnet \
        --purpose=GLOBAL_MANAGED_PROXY \
        --role=ACTIVE \
        --region=us-east1 \
        --network=default \
        --range=10.130.0.0/23 # Choose an appropriate unused CIDR range
    

    Si no usas la red predeterminada, reemplaza default por el nombre de tu red de VPC. Asegúrate de que los rangos de 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. Crea recursos de Service y ServiceExport de Kubernetes en cada clúster para exportar los servicios, lo que hace que los servicios se puedan detectar en toda la flota. En el siguiente ejemplo, se exportan un servicio store genérico y servicios específicos de la región (store-west-1, store-east-1) desde cada clúster, todo dentro del espacio de nombres store.

    Aplicar a gke-west1:

    cat << EOF | kubectl apply --context gke-west1 -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store
      namespace: store
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store-west-1 # Specific to this cluster
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    ---
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: store-west-1 # Exporting the region-specific service
      namespace: store
    EOF
    

    Aplicar 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 los ServiceImports: Verifica que los recursos ServiceImport se creen en cada clúster dentro del espacio de nombres store. La creación de los clústeres puede tardar unos minutos. bash kubectl get serviceimports --context gke-west1 -n store kubectl get serviceimports --context gke-east1 -n store Deberías ver store, store-west-1 y store-east-1 en la lista (o las entradas pertinentes según la propagación).

Configura una puerta de enlace interna multirregión

Define un recurso Gateway que haga referencia a la GatewayClass gke-l7-cross-regional-internal-managed-mc. Aplicas este manifiesto a tu clúster de configuración designado, como gke-west-1.

El campo spec.addresses te permite solicitar direcciones IP efímeras en regiones específicas o usar direcciones IP estáticas previamente asignadas.

  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/v1
    metadata:
      name: internal-cross-region-gateway
      namespace: store # Namespace for the Gateway resource
    spec:
      gatewayClassName: gke-l7-cross-regional-internal-managed-mc
      addresses:
      # Addresses across regions. Address value is allowed to be empty or matching
      # the region name.
      - type: networking.gke.io/ephemeral-ipv4-address/us-west1
        value: "us-west1"
      - type: networking.gke.io/ephemeral-ipv4-address/us-east1
        value: "us-east1"
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute # Only allow HTTPRoute to 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 Gateway, 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 Route que se pueden adjuntar, por ejemplo, HTTPRoute.
    • spec.addresses:
      • type: networking.gke.io/ephemeral-ipv4-address/REGION: Solicita una dirección IP efímera.
      • value: Especifica la región de la dirección, por ejemplo, "us-west1" o "us-east1".
  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 de HTTPRoute para administrar el enrutamiento del tráfico y aplícalos 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/v1
    metadata:
      name: store-route
      namespace: store
      labels:
        gateway: cross-regional-internal
    spec:
      parentRefs:
      - name: internal-cross-region-gateway
        namespace: store # Namespace where the Gateway is deployed
      hostnames:
      - "store.example.internal" # Hostname clients will use
      rules:
      - matches: # Rule for traffic to /west
        - path:
            type: PathPrefix
            value: /west
        backendRefs:
        - group: net.gke.io # Indicates a multi-cluster ServiceImport
          kind: ServiceImport
          name: store-west-1 # Targets the ServiceImport for the west cluster
          port: 8080
      - matches: # Rule for traffic to /east
        - path:
            type: PathPrefix
            value: /east
        backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          name: store-east-1 # Targets the ServiceImport for the east cluster
          port: 8080
      - backendRefs: # Default rule for other paths (e.g., /)
        - group: net.gke.io
          kind: ServiceImport
          name: store # Targets the generic 'store' ServiceImport (any region)
          port: 8080
    

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

    • spec.parentRefs: Adjunta esta ruta a internal-cross-region-gateway en el espacio de nombres store.
    • spec.hostnames: Representa el nombre de host que los clientes usan para acceder al servicio.
    • spec.rules: Define la lógica de enrutamiento. En este ejemplo, se usa el enrutamiento basado en rutas de acceso:
      • El tráfico de /west va a la ServiceImport store-west-1.
      • El tráfico de /east va a la ServiceImport store-east-1.
      • Todo el resto del tráfico, como /, se dirige al objeto ServiceImport genérico store.
    • backendRefs:
      • group: net.gke.io y kind: ServiceImport segmentan los 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 internal-cross-region-gateway -n store -o yaml --context gke-west1
    

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

  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 se pueda conectar 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 las VIP, como VIP1_WEST o VIP2_EAST.

  2. Envía solicitudes de prueba: Desde una VM cliente en tu VPC, haz lo siguiente:

    # Assuming VIP_WEST is an IP in us-west1 and VIP_EAST is an IP in us-east1
    # Traffic to /west should ideally be served by gke-west-1
    curl -H "host: store.example.internal" http://VIP_WEST/west
    curl -H "host: store.example.internal" http://VIP_EAST/west # Still targets store-west-1 due to path
    
    # Traffic to /east should ideally be served by gke-east-1
    curl -H "host: store.example.internal" http://VIP_WEST/east # Still targets store-east-1 due to path
    curl -H "host: store.example.internal" http://VIP_EAST/east
    
    # Traffic to / (default) could be served by either cluster
    curl -H "host: store.example.internal" http://VIP_WEST/
    curl -H "host: store.example.internal" http://VIP_EAST/
    

    La respuesta debe incluir detalles de la aplicación store que indiquen qué pod de backend atendió 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 asignadas previamente.

  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. Actualiza el manifiesto de Gateway modificando la sección spec.addresses en tu archivo cross-regional-gateway.yaml:

    # cross-regional-gateway-static-ip.yaml
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: internal-cross-region-gateway # Or a new name if deploying alongside
      namespace: store
    spec:
      gatewayClassName: gke-l7-cross-regional-internal-managed-mc
      addresses:
      - type: networking.gke.io/named-address-with-region # Use for named static IP
        value: "regions/us-west1/addresses/cross-region-gw-ip-west"
      - type: networking.gke.io/named-address-with-region
        value: "regions/us-east1/addresses/cross-region-gw-ip-east"
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          kinds:
          - kind: HTTPRoute
    
  3. Aplica el manifiesto de Gateway actualizado.

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

Consideraciones especiales para las subredes no predeterminadas

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

  • La misma red de VPC: Todos los recursos creados por el usuario, como las direcciones IP estáticas, las subredes de solo proxy y los clústeres de GKE, deben residir en la misma red de VPC.

  • Subred de direcciones: Cuando creas direcciones IP estáticas para la puerta de enlace, se asignan desde subredes normales en las regiones especificadas.

  • Nombres de subredes del clúster: Cada región debe tener una subred con el mismo nombre que la subred en la que reside el clúster de configuración de MCG.

    • Por ejemplo, si tu clúster de configuración gke-west-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.

Realiza una limpieza

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

  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
    

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?