Implemente um gateway interno de vários clusters

Este documento explica um exemplo prático para implementar um gateway interno de vários clusters para encaminhar tráfego na sua rede VPC para uma aplicação que é executada em dois clusters do GKE diferentes.

Os gateways em vários clusters oferecem uma forma eficaz de gerir o tráfego para serviços implementados em vários clusters do GKE. Ao usar a infraestrutura de balanceamento de carga global da Google, pode criar um único ponto de entrada para as suas aplicações, o que simplifica a gestão e melhora a fiabilidade.

Neste tutorial, vai usar uma aplicação de exemplo store para simular um cenário real em que um serviço de compras online é detido e operado por equipas separadas e implementado numa frota de clusters do GKE partilhados.

Este exemplo mostra como configurar o encaminhamento baseado em caminhos para direcionar o tráfego para diferentes clusters.

Antes de começar

Os gateways de vários clusters requerem alguma preparação ambiental antes de poderem ser implementados. Antes de continuar, siga os passos em Prepare o seu ambiente para gateways multicluster:

  1. Implemente clusters do GKE.

  2. Registe os seus clusters numa frota (se ainda não o tiverem feito).

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

Por último, reveja as limitações e os problemas conhecidos do controlador do GKE Gateway antes de usar o controlador no seu ambiente.

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

Pode implementar gateways de vários clusters que oferecem equilíbrio de carga interno da camada 7 em clusters do GKE em várias regiões. Estes gateways usam a gke-l7-cross-regional-internal-managed-mc GatewayClass. Esta GatewayClass aprovisiona um Application Load Balancer interno entre regiões gerido por Google Cloud e que ativa VIPs internos aos quais os clientes na sua rede VPC podem aceder. Estas entradas podem ser expostas por front-ends nas regiões à sua escolha, bastando usar a entrada para pedir 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 especificado no gateway. O tráfego é direcionado para o cluster GKE de back-end saudável mais próximo que pode publicar o pedido.

Pré-requisitos

  1. Configure o projeto e a 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 diferentes regiões.

    Este exemplo usa dois clusters, gke-west-1 em us-west1 e gke-east-1 em us-east1. Certifique-se de que a API Gateway está ativada (--gateway-api=standard) e que os clusters estão registados numa 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
    

    Mude o nome dos 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 em vários clusters (MCS) e a entrada em 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 só de proxy. É necessária uma sub-rede só de proxy em cada região onde os seus clusters do GKE estão localizados e onde o balanceador de carga vai funcionar. Os Application Load Balancers internos entre regiões requerem que a finalidade desta 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 não estiver a usar a rede predefinida, substitua default pelo nome da sua rede VPC. Certifique-se de que os intervalos CIDR são únicos e não se sobrepõem.

  5. Implemente as suas aplicações de demonstração, como store, em ambos os clusters. O ficheiro de exemplo store.yaml de gke-networking-recipes cria um espaço de nomes store e uma implementação.

    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 serviços de cada cluster criando recursos Service do Kubernetes e recursos ServiceExport em cada cluster, o que torna os serviços detetáveis em toda a frota. O exemplo seguinte exporta um serviço store genérico e serviços específicos da região (store-west-1, store-east-1) de cada cluster, tudo no espaço de nomes 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: Confirme se os recursos ServiceImport são criados em cada cluster no espaço de nomes store. A criação dos vídeos pode demorar alguns minutos. bash kubectl get serviceimports --context gke-west1 -n store kubectl get serviceimports --context gke-east1 -n store Deve ver store, store-west-1 e store-east-1 apresentados (ou entradas relevantes com base na propagação).

Configure um gateway interno de várias regiões

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

O campo spec.addresses permite-lhe pedir endereços IP efémeros em regiões específicas ou usar endereços IP estáticos pré-atribuídos.

  1. Para usar endereços IP efémeros, guarde o seguinte manifesto 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
    

    A lista seguinte define alguns dos campos no ficheiro YAML anterior:

    • metadata.namespace: o espaço de nomes onde o recurso Gateway é criado, por exemplo, store.
    • spec.gatewayClassName: o nome da GatewayClass. Tem de ser gke-l7-cross-regional-internal-managed-mc.
    • spec.listeners.allowedRoutes.kinds: os tipos de objetos Route que podem ser anexados, por exemplo, HTTPRoute.
    • spec.addresses:
      • type: networking.gke.io/ephemeral-ipv4-address/REGION: pede 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
    

Anexe HTTPRoutes ao Gateway

Defina recursos HTTPRoute para gerir o encaminhamento de tráfego e aplique-os ao seu cluster de configuração.

  1. Guarde 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 seguinte define alguns dos campos no ficheiro YAML anterior:

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

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

Valide o estado do gateway e da rota

  1. Verifique o estado do gateway:

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

    Procure uma condição com o estado type:Programadoand: "Verdadeiro". 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 estado 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".

Confirme o tráfego

Depois de atribuir os endereços IP ao gateway, pode testar o tráfego a partir de uma VM de cliente que esteja na sua rede VPC e numa das regiões ou numa região que possa estabelecer ligação ao endereço IP do gateway.

  1. Recupere os endereços IP do gateway.

    O comando seguinte tenta analisar o resultado JSON. Pode ter de ajustar o jsonpath com base na estrutura exata.

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

    O resultado deste comando deve incluir os VIPs, como VIP1_WEST ou VIP2_EAST.

  2. Envie pedidos de teste: A partir de 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 deve incluir detalhes da aplicação store que indiquem que pod de back-end publicou o pedido, como cluster_name ou zone.

Use endereços IP estáticos

Em vez de endereços IP efémeros, pode usar endereços IP internos estáticos pré-atribuídos.

  1. Crie endereços IP estáticos nas regiões que 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 não estiver a usar a sub-rede predefinida, substitua default pelo nome da sub-rede que tem o endereço IP que quer atribuir. Estas sub-redes são sub-redes normais e não sub-redes apenas de proxy.

  2. Atualize o manifesto do gateway modificando a secção spec.addresses no ficheiro 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 do gateway atualizado.

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

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

Tenha em atenção as seguintes considerações quando usa sub-redes não predefinidas:

  • Mesma rede de VPC: todos os recursos criados pelo utilizador, como endereços IP estáticos, sub-redes apenas de proxy e clusters do GKE, têm de residir na mesma rede de VPC.

  • Sub-rede de endereços: quando cria endereços IP estáticos para o gateway, estes são atribuídos a partir de sub-redes normais nas regiões especificadas.

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

    • 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 está a pedir moradas também têm de ter a sub-rede my-custom-subnet. Se pedir endereços nas regiões us-east1 e us-centra1, também tem de existir uma sub-rede denominada my-custom-subnet nessas regiões.

Limpar

Depois de concluir os exercícios neste documento, siga estes passos para remover recursos e evitar a incorrência de cobranças indesejadas na sua conta:

  1. Elimine os clusters.

  2. Anule o registo dos clusters da frota se não precisarem de ser registados para outro fim.

  3. Desative a funcionalidade multiclusterservicediscovery:

    gcloud container fleet multi-cluster-services disable
    
  4. Desative a entrada em 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
    

Resolução de problemas

A sub-rede só de proxy para o gateway interno não existe

Se o seguinte evento for apresentado no seu gateway interno, significa que não existe uma sub-rede apenas de proxy para essa região. Para resolver este problema, implemente 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.

Não existe um upstream em bom estado

Sintoma:

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

no healthy upstream

Motivo:

Esta mensagem de erro indica que o verificador de estado de funcionamento não consegue encontrar serviços de back-end em bom estado. É possível que os seus serviços de back-end estejam em bom estado, mas pode ter de personalizar as verificações de funcionamento.

Solução alternativa:

Para resolver este problema, personalize a verificação de estado com base nos requisitos da sua aplicação (por exemplo, /health) através de um HealthCheckPolicy.

O que se segue?