Implantar um gateway interno de vários clusters

Este documento orienta você em um exemplo prático para implantar um gateway interno de vários clusters e rotear o tráfego na rede VPC para um aplicativo executado em dois clusters diferentes do GKE.

Os gateways de vários clusters oferecem uma maneira eficiente de gerenciar o tráfego de serviços implantados em vários clusters do GKE. Ao usar a infraestrutura global de balanceamento de carga do Google, você pode criar um único ponto de entrada para seus aplicativos, o que simplifica o gerenciamento e melhora a confiabilidade.

Neste tutorial, você usa um aplicativo store de amostra para simular um cenário real em que um serviço de compras on-line é de propriedade e operado por equipes separadas e implantado em uma frota de clusters compartilhados do GKE.

Este exemplo mostra como configurar o roteamento baseado em caminho para direcionar o tráfego a diferentes clusters.

Antes de começar

Os gateways de vários clusters precisam de preparação do ambiente para serem implantados. Antes de continuar, siga as etapas em Preparar o ambiente para gateways de vários clusters:

  1. Implante cluster do GKE.

  2. Registre os clusters em uma frota, se ainda não tiver feito isso.

  3. Ative os controladores do gateway de vários clusters e do serviço de vários clusters.

Por fim, analise as limitações e problemas conhecidos do GKE Gateway controller antes de usá-lo no seu ambiente.

Implantar um gateway interno de vários clusters em várias regiões

É possível implantar gateways de vários clusters que oferecem balanceamento de carga interno da camada 7 em clusters do GKE em várias regiões. Esses gateways usam a GatewayClass gke-l7-cross-regional-internal-managed-mc. Essa GatewayClass provisiona um balanceador de carga de aplicativo interno entre regiões gerenciado por Google Cloud e que permite VIPs internos acessíveis a clientes na sua rede VPC. Esses gateways podem ser expostos por front-ends nas regiões de sua escolha. Basta usar o gateway para solicitar endereços nessas regiões. O VIP interno pode ser um único endereço IP ou endereços IP em várias regiões, com um endereço IP por região especificada no gateway. O tráfego é direcionado para o cluster do GKE de back-end íntegro mais próximo que pode atender à solicitação.

Pré-requisitos

  1. Configure seu projeto e shell configurando o ambiente gcloud com o ID do projeto:

    export PROJECT_ID="YOUR_PROJECT_ID"
    gcloud config set project ${PROJECT_ID}
    
  2. Crie clusters do GKE em regiões diferentes.

    Este exemplo usa dois clusters, gke-west-1 em us-west1 e gke-east-1 em us-east1. Verifique se a API Gateway está ativada (--gateway-api=standard) e se os clusters estão registrados em uma frota.

    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
    

    Renomeie os contextos para facilitar o acesso:

    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. Ative os serviços de vários clusters (MCS) e a Entrada de vários clusters (MCI/gateway):

    gcloud container fleet multi-cluster-services enable --project=${PROJECT_ID}
    
    # Set the config membership to one of your clusters (e.g., gke-west-1)
    # This cluster will be the source of truth for multi-cluster Gateway and Route resources.
    gcloud container fleet ingress enable \
        --config-membership=projects/${PROJECT_ID}/locations/us-west1/memberships/gke-west-1 \
        --project=${PROJECT_ID}
    
  4. Configure sub-redes somente proxy. Uma sub-rede somente proxy é necessária em cada região em que os clusters do GKE estão localizados e em que o balanceador de carga vai operar. Os balanceadores de carga de aplicativo internos entre regiões exigem que a finalidade dessa sub-rede seja definida como GLOBAL_MANAGED_PROXY.

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

    Se você não estiver usando a rede padrão, substitua default pelo nome da sua rede VPC. Verifique se os intervalos CIDR são exclusivos e não se sobrepõem.

  5. Implante seus aplicativos de demonstração, como store, nos dois clusters. O arquivo de exemplo store.yaml de gke-networking-recipes cria um namespace store e um deployment.

    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. Exporte os serviços de cada cluster criando recursos Service e ServiceExport do Kubernetes em cada cluster, o que torna os serviços detectáveis em toda a frota. O exemplo a seguir exporta um serviço store genérico e serviços específicos da região (store-west-1, store-east-1) de cada cluster, todos no namespace 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. Verifique ServiceImports: confira se os recursos ServiceImport foram criados em cada cluster no namespace store. A criação pode levar alguns minutos. bash kubectl get serviceimports --context gke-west1 -n store kubectl get serviceimports --context gke-east1 -n store Você vai encontrar store, store-west-1 e store-east-1 listados (ou entradas relevantes com base na propagação).

Configurar um gateway interno multirregional

Defina um recurso Gateway que faça referência à GatewayClass gke-l7-cross-regional-internal-managed-mc. Você aplica esse manifesto ao cluster de configuração designado, como gke-west-1.

O campo spec.addresses permite solicitar endereços IP temporários em regiões específicas ou usar endereços IP estáticos pré-alocados.

  1. Para usar endereços IP temporários, salve o manifesto Gateway a seguir 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
    

    A lista a seguir define alguns dos campos no arquivo YAML anterior:

    • metadata.namespace: o namespace em que o recurso de gateway é criado, por exemplo, store.
    • spec.gatewayClassName: o nome da GatewayClass. Precisa ser gke-l7-cross-regional-internal-managed-mc.
    • spec.listeners.allowedRoutes.kinds: os tipos de objetos de rota que podem ser anexados, por exemplo, HTTPRoute.
    • spec.addresses:
      • type: networking.gke.io/ephemeral-ipv4-address/REGION: solicita um endereço IP efêmero.
      • value: especifica a região do endereço, por exemplo, "us-west1" ou "us-east1".
  2. Aplique o manifesto ao cluster de configuração, por exemplo, gke-west1:

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

Anexar HTTPRoutes ao gateway

Defina recursos HTTPRoute para gerenciar o roteamento de tráfego e aplique-os ao cluster de configuração.

  1. Salve o seguinte manifesto 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
    

    A lista a seguir define alguns dos campos no arquivo YAML anterior:

    • spec.parentRefs: anexa essa rota a internal-cross-region-gateway no namespace store.
    • spec.hostnames: representa o nome do host que os clientes usam para acessar o serviço.
    • spec.rules: define a lógica de roteamento. Este exemplo usa o roteamento baseado em caminho:
      • O tráfego de /west vai para o ServiceImport store-west-1.
      • O tráfego de /east vai para o ServiceImport store-east-1.
      • Todo o resto do tráfego, como /, vai para o ServiceImport store genérico.
    • backendRefs:
      • group: net.gke.io e kind: ServiceImport segmentam serviços de vários clusters.
  2. Aplique o manifesto HTTPRoute ao cluster de configuração:

    kubectl apply --context gke-west1 -f store-route.yaml
    

Verificar o status do gateway e da rota

  1. Verifique o status do gateway:

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

    Procure uma condição com o status type:Programadoand: "True". You should see IP addresses assigned in thestatus.addressesfield, corresponding to the regions you specified (e.g., one forus-west1and one forus-east1`).

  2. Verifique o status do HTTPRoute:

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

    Procure uma condição em status.parents[].conditions com type: Accepted (ou ResolvedRefs) e status: "True".

Confirmar o trânsito

Depois de atribuir os endereços IP ao gateway, teste o tráfego de uma VM cliente na rede VPC e em uma das regiões, ou em uma região que possa se conectar ao endereço IP do gateway.

  1. Recupere os endereços IP do gateway.

    O comando a seguir tenta analisar a saída JSON. Talvez seja necessário ajustar o jsonpath com base na estrutura exata.

    kubectl get gateway cross-region-gateway -n store --context gke-west1 -o=jsonpath="{.status.addresses[*].value}".
    

    A saída desse comando precisa incluir os VIPs, como VIP1_WEST ou VIP2_EAST.

  2. Envie solicitações de teste: Em uma VM cliente na sua 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/
    

    A resposta precisa incluir detalhes do aplicativo store que indicam qual pod de back-end atendeu à solicitação, como cluster_name ou zone.

Usar endereços IP estáticos

Em vez de endereços IP temporários, use endereços IP internos estáticos pré-alocados.

  1. Crie endereços IP estáticos nas regiões que você quer 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}
    

    Se você não estiver usando a sub-rede padrão, substitua default pelo nome da sub-rede que tem o endereço IP que você quer alocar. Essas sub-redes são sub-redes regulares, não as sub-redes somente proxy.

  2. Atualize o manifesto do gateway modificando a seção spec.addresses no arquivo 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. Aplique o manifesto de gateway atualizado.

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

Considerações especiais para sub-redes não padrão

Considere as seguintes observações ao usar sub-redes não padrão:

  • Mesma rede VPC:todos os recursos criados pelo usuário, como endereços IP estáticos, sub-redes somente proxy e clusters do GKE, precisam estar na mesma rede VPC.

  • Sub-rede de endereço:quando você cria endereços IP estáticos para o gateway, eles são alocados de sub-redes regulares nas regiões especificadas.

  • Nomenclatura de sub-rede do cluster:cada região precisa ter uma sub-rede com o mesmo nome da sub-rede em que o cluster de configuração do MCG reside.

    • Por exemplo, se o cluster de configuração gke-west-1 estiver em projects/YOUR_PROJECT/regions/us-west1/subnetworks/my-custom-subnet, as regiões para as quais você está solicitando endereços também precisarão ter a sub-rede my-custom-subnet. Se você solicitar endereços nas regiões us-east1 e us-centra1, uma sub-rede chamada my-custom-subnet também precisará existir nessas regiões.

Limpar

Depois de concluir os exercícios neste documento, siga estas etapas para remover os recursos e evitar cobranças indesejadas na conta:

  1. Excluir os clusters.

  2. Cancele o registro dos clusters da frota se eles não precisarem ser registrados para outra finalidade.

  3. Desative o recurso multiclusterservicediscovery:

    gcloud container fleet multi-cluster-services disable
    
  4. Desativar a Entrada de vários clusters:

    gcloud container fleet ingress disable
    
  5. Desative as APIs:

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

Solução de problemas

Não existe uma sub-rede somente proxy para o gateway interno

Se o evento a seguir aparecer no gateway interno, não existe uma sub-rede apenas proxy nessa região. Para resolver esse problema, implante uma sub-rede apenas de proxy.

generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/us-west1/targetHttpProxies/gkegw-x5vt-default-internal-http-2jzr7e3xclhj'. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.

Nenhum upstream íntegro

Sintoma:

O seguinte problema pode ocorrer quando você cria um gateway mas não pode acessar os serviços de back-end (código de resposta 503):

no healthy upstream

Motivo:

Esta mensagem de erro indica que a sondagem da verificação de integridade não consegue encontrar a integridade dos serviços de back-end. É possível que os serviços de back-end estejam íntegros, mas talvez seja necessário personalizar as verificações de integridade.

Alternativa:

Para resolver esse problema, personalize a verificação de integridade com base nas condições (por exemplo, /health) usando um HealthCheckPolicy.

A seguir