Como configurar o Traffic Director com VPC compartilhada em vários clusters do GKE

Neste tutorial mostramos como configurar o Traffic Director para comunicação de serviço a serviço entre serviços executados em vários projetos em uma rede de VPC compartilhada. Ele é voltado a administradores de rede e administradores da plataforma Google Kubernetes Engine (GKE).

As empresas normalmente dividem os recursos em vários projetos do Google Cloud, separando-os por equipes, aplicativos ou ambientes, como ambientes de desenvolvimento, preparação e produção. Todo projeto do Google Cloud vem com uma nuvem privada virtual (VPC) padrão usada por recursos do Google Cloud, como instâncias do Compute Engine e clusters do GKE.

Em vez de gerenciar VPCs em cada projeto, a VPC compartilhada permite centralizar todos os recursos de VPC (sub-redes, regras de firewall, balanceadores de carga) em um único projeto de host e depois compartilhar recursos de rede compartilhados em outros projetos, chamados projetos de serviço. Essa abordagem permite que os administradores de rede gerenciem todos os recursos de rede centralmente, oferecendo a possibilidade de dividir nível de projeto para equipes, aplicativos e ambientes. Para permitir acesso a recursos de rede para seus projetos, use contas de serviço para configurar as permissões de gerenciamento de identidade e acesso (IAM) para projetos de serviço.

O diagrama a seguir mostra um projeto host da VPC compartilhada que compartilha quatro sub-redes para dois projetos de serviço (duas sub-redes cada), incluindo os endereços IP de cada projeto.

Um projeto host de VPC compartilhada que compartilha quatro sub-redes com dois projetos de serviço.

Em alguns casos, a comunicação entre serviços é necessária para aqueles que estiverem sendo executados em vários projetos de serviço. Contanto que as instâncias entre projetos de serviço estejam conectados à mesma VPC, é possível estabelecer a acessibilidade configurando regras de firewall de VPC. Para serviços que estejam sendo executados em clusters de GKE, é possível usar o Traffic Director para criar uma malha de serviço entre serviços executados em vários clusters de GKE, em vários projetos e em várias regiões. O Traffic Director funciona como um plano de controle da malha de serviço que configura proxies do Envoy executados como contêineres de sidecar em cada pod executado em clusters do GKE (links em inglês). Sidecars de proxies do Envoy interceptam todas as solicitações do contêiner de aplicativo em execução em cada pod e conectam serviços entre clusters do GKE. É possível usar o Traffic Director para serviços executados em instâncias do Compute Engine.

Neste tutorial, você cria e define a VPC compartilhada com dois projetos de serviço. Você cria dois clusters de GKE, um em cada projeto de serviço em diferentes regiões, usando a VPC compartilhada. Você configura um serviço de amostra com proxies do Envoy sendo executados como sidecars. Você também usa o Traffic Director para configurar proxies do Envoy para comunicação de serviço a serviço entre clusters do GKE.

O diagrama a seguir mostra um projeto host da VPC compartilhada que compartilha quatro sub-redes com dois projetos de serviço, com duas sub-redes para cada projeto de serviço.

Um projeto host de VPC compartilhada que compartilha quatro
sub-redes com dois projetos de serviço, com duas sub-redes para cada projeto de serviço.

Cada projeto de serviço tem um cluster do GKE que inclui um pod de aplicativo de amostra e um pod BusyBox (em inglês). Os proxies secundários do Envoy executados em cada pod de aplicativo se conectam pela rede, em regiões e clusters.

Objetivos

  • Criar um projeto host e dois projetos de serviço.
  • Criar uma VPC compartilhada no projeto host com duas sub-redes. Há uma sub-rede para cada um dos dois projetos de serviço usados pelos clusters do GKE.
  • Criar dois clusters do GKE, um em cada projeto de serviço, usando as sub-redes da VPC compartilhada.
  • Implantar um aplicativo de amostra usando httpbin (em inglês) nos dois clusters com os proxies de sidecar do Envoy. Implantar um pod do BusyBox nos dois clusters para testar a conectividade.
  • Configurar o Traffic Director para permitir conectividade de rede entre todos os serviços.
  • Confirmar se os serviços podem se comunicar entre os clusters do GKE e entre projetos de serviço.

Custos

Neste tutorial, usamos os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem ser qualificados para uma avaliação gratuita.

Ao concluir este tutorial, exclua os recursos criados para evitar o faturamento contínuo. Para mais informações, consulte Como fazer a limpeza.

Antes de começar

Para configurar uma VPC compartilhada no Google Cloud, verifique se você tem os recursos e papéis a seguir no Google Cloud:

  • Um recurso da organização, que é o nó raiz na hierarquia de recursos do Google Cloud e é o supernó hierárquico dos projetos. Para criar um recurso de organização, siga as instruções em Como conseguir um recurso de organização. Só é possível criar uma VPC compartilhada entre projetos em um recurso de organização.
  • Os papéis de IAM a seguir no nível da organização para seu usuário:
    • Criador do projeto (roles/resourcemanager.projectCreator). Criar projetos de serviço e host.
    • Editor (roles/editor). Criar e excluir recursos em projetos do Cloud na organização.
    • Gerente de faturamento do projeto (roles/billing.projectManager). Atribuir contas de faturamento a projetos na organização. Esse papel não permite criar contas de faturamento, mas sim atribuir contas de faturamento atuais a projetos. Se você precisar criar uma nova conta de faturamento, use o papel de Administrador da conta de faturamento (roles/billing.admin).
    • Administrador do Compute (roles/compute.admin). Criar recursos de rede (VPCs, sub-redes, regras de firewall) para todos os projetos na organização.
    • Administrador de IAM do projeto (roles/resourcemanager.projectIamAdmin). Administrar políticas de IAM para todos os projetos na organização.
    • Excluidor de projeto (roles/resourcemanager.projectDeleter). Excluir projetos na organização (opcional).

Para configurar os recursos e papéis anteriores, siga estas etapas:

  1. Acesse a página Gerenciar recursos.

    Acessar a página "Gerenciar recursos"

  2. Selecione sua organização do Google Cloud e copie o número da ID da organização da coluna de ID para um bloco de notas ou arquivo. Ele será usado posteriormente neste tutorial.

  3. Na mesma linha da sua organização, clique em e, em seguida, clique em Configurações.

  4. Na página IAM e Administrador, clique em IAM. Verifique se você tem os papéis do IAM adequados para seu usuário no nível da organização.

    Será exibida uma lista de papéis para um usuário específico.

  5. No Console do Cloud, ative o Cloud Shell.

    Ativar o Cloud Shell

  6. Verifique se você fez login com o mesmo nome de usuário que tem os papéis configurados na etapa 4:

    gcloud info --format=json | jq '.config.account'
    
  7. Encontre a conta de faturamento usada para os projetos do Cloud:

    gcloud beta billing accounts list
    

    A resposta será semelhante a esta:

    ACCOUNT_ID            NAME                    OPEN  MASTER_ACCOUNT_ID
    1337A-1337A-1337A     My Billing Account      True
    

    Copie o ID da conta de faturamento em um bloco de notas ou arquivo. Você precisará desse número na próxima etapa.

  8. Defina variáveis de ambiente para o ID da organização e da conta de faturamento:

    export ORG_ID=ORG_ID_NUMBER
    export BILLING_ID=BILLING_ACCOUNT_ID
    

    Substitua:

    • ORG_ID_NUMBER: o ID da organização na etapa 2
    • BILLING_ACCOUNT_ID: o ID da conta de faturamento da etapa 7

Na próxima seção, você criará recursos na organização.

Como configurar o ambiente

Nesta seção, você cria três projetos na organização do Google Cloud: o projeto host em que você configura uma VPC compartilhada e dois projetos de serviço que usam os recursos da VPC compartilhada.

Criar projetos e faturamento

  1. No Cloud Shell, crie três projetos na organização do Google Cloud:

    export RANDOM_PERSIST=$RANDOM
    export HOST_PROJECT="td-${ORG_ID}-${RANDOM_PERSIST}-host-prj"
    export SVC_PROJECT_1="td-${ORG_ID}-${RANDOM_PERSIST}-svc-prj1"
    export SVC_PROJECT_2="td-${ORG_ID}-${RANDOM_PERSIST}-svc-prj2"
    gcloud projects create ${HOST_PROJECT} --organization=${ORG_ID}
    gcloud projects create ${SVC_PROJECT_1} --organization=${ORG_ID}
    gcloud projects create ${SVC_PROJECT_2} --organization=${ORG_ID}
    

    As variáveis do projeto definidas nos comandos anteriores precisam representar os IDs dos três projetos.

  2. Ative o faturamento dos três projetos:

    gcloud beta billing projects link ${HOST_PROJECT} \
        --billing-account ${BILLING_ID}
    gcloud beta billing projects link ${SVC_PROJECT_1} \
        --billing-account ${BILLING_ID}
    gcloud beta billing projects link ${SVC_PROJECT_2} \
        --billing-account ${BILLING_ID}
    
  3. Ative as APIs GKE e Traffic Director em todos os projetos:

    gcloud services enable container.googleapis.com trafficdirector.googleapis.com --project $HOST_PROJECT
    gcloud services enable container.googleapis.com trafficdirector.googleapis.com --project $SVC_PROJECT_1
    gcloud services enable container.googleapis.com trafficdirector.googleapis.com --project $SVC_PROJECT_2
    

Conseguir contas de serviço do Google Cloud

Cada projeto do Cloud vem com várias contas de serviço padrão que incluem permissões padrão para vários recursos. Veja a seguir as três contas de serviço padrão gerenciadas pelo Google necessárias para este tutorial:

Você precisa dos e-mails da conta de serviço dos dois projetos de serviço para criar permissões do IAM no projeto host. Com essas permissões, os projetos de serviço consomem recursos (neste caso, uma VPC compartilhada) do projeto host. Essas contas de serviço têm uma convenção de nomenclatura padrão que usa o número do projeto.

  • No Cloud Shell, encontre os dois e-mails da conta de serviço dos dois projetos de serviço:

    export SVC_PROJECT_1_NUM=$(gcloud projects list --format=json --filter="${SVC_PROJECT_1}" | jq -r '.[].projectNumber')
    export SVC_PROJECT_2_NUM=$(gcloud projects list --format=json --filter="${SVC_PROJECT_2}" | jq -r '.[].projectNumber')
    
    export SVC_PROJECT_1_COMPUTE_SA="${SVC_PROJECT_1_NUM}-compute@developer.gserviceaccount.com"
    export SVC_PROJECT_2_COMPUTE_SA="${SVC_PROJECT_2_NUM}-compute@developer.gserviceaccount.com"
    
    export SVC_PROJECT_1_GKE_SA="service-${SVC_PROJECT_1_NUM}@container-engine-robot.iam.gserviceaccount.com"
    export SVC_PROJECT_2_GKE_SA="service-${SVC_PROJECT_2_NUM}@container-engine-robot.iam.gserviceaccount.com"
    
    export SVC_PROJECT_1_API_SA="${SVC_PROJECT_1_NUM}@cloudservices.gserviceaccount.com"
    export SVC_PROJECT_2_API_SA="${SVC_PROJECT_2_NUM}@cloudservices.gserviceaccount.com"
    

Criar uma rede e sub-redes VPC

  1. No Cloud Shell, crie uma rede VPC no projeto host chamado shared-vpc. Crie uma VPC de modo personalizado para gerar sub-redes manualmente.

    gcloud compute networks create shared-vpc \
        --subnet-mode custom \
        --project $HOST_PROJECT
    
  2. Crie duas sub-redes no recurso shared-vpc. Uma sub-rede será usada pelos clusters do GKE em cada um dos dois projetos de serviço. Crie um intervalo principal para os nós do GKE e dois intervalos secundários, um para pods do GKE e outro para serviços do GKE.

    export REGION_1=us-west1
    export ZONE_1=us-west1-a
    export REGION_2=us-central1
    export ZONE_2=us-central1-a
    
    gcloud compute networks subnets create subnet-1 \
        --project $HOST_PROJECT \
        --network shared-vpc \
        --range 10.0.4.0/22 \
        --region ${REGION_1} \
        --secondary-range subnet-1-services=10.0.32.0/20,subnet-1-pods=10.4.0.0/14
    
    gcloud compute networks subnets create subnet-2 \
        --project $HOST_PROJECT \
        --network shared-vpc \
        --range 172.16.4.0/22 \
        --region ${REGION_2} \
        --secondary-range subnet-2-services=172.16.16.0/20,subnet-2-pods=172.20.0.0/14
    
  3. Crie regras de firewall para todos os intervalos de endereços IP na rede VPC para que os pods do GKE possam se comunicar em todas as portas e protocolos. Restrinja esta regra para permitir apenas as portas necessárias.

    gcloud compute firewall-rules create allow-gke-svc-1-all \
        --project ${HOST_PROJECT} \
        --network shared-vpc \
        --allow tcp,udp \
        --direction INGRESS \
        --source-ranges 10.0.4.0/22,10.4.0.0/14,10.0.32.0/20
    
    gcloud compute firewall-rules create allow-gke-svc-2-all \
        --project ${HOST_PROJECT} \
        --network shared-vpc \
        --allow tcp,udp \
        --direction INGRESS \
        --source-ranges 172.16.4.0/22,172.20.0.0/14,172.16.16.0/20
    
    gcloud compute firewall-rules create allow-healthchecks \
        --project ${HOST_PROJECT} \
        --network shared-vpc \
        --allow tcp,udp \
        --direction INGRESS \
        --source-ranges 130.211.0.0/22,35.191.0.0/16
    

    As duas primeiras regras de firewall mostradas anteriormente permitem conectividade de rede subnet-1 e subnet-2 na rede VPC compartilhada. Essa conectividade permite a comunicação IP entre pods de clusters diferentes. A terceira regra de firewall, allow-healthchecks, ativa o Cloud Load Balancing para verificar a integridade dos serviços de back-end antes de enviar tráfego para eles. O Cloud Load Balancing usa intervalos de endereços IP conhecidos para realizar verificações de integridade configuradas como source-ranges para os endereços IP na regra de firewall.

Como criar uma VPC compartilhada

Nesta seção, você ativa e configura a VPC compartilhada no projeto host. Você também configura as permissões de IAM que permitem que os projetos de serviço usem os recursos da VPC compartilhada.

Ativar a VPC compartilhada

  1. No Cloud Shell, ative a VPC compartilhada no projeto host:

    gcloud compute shared-vpc enable ${HOST_PROJECT}
    
  2. Adicione os dois projetos de serviço à VPC compartilhada:

    gcloud compute shared-vpc associated-projects add \
        ${SVC_PROJECT_1} \
        --host-project ${HOST_PROJECT}
    
    gcloud compute shared-vpc associated-projects add \
        ${SVC_PROJECT_2} \
        --host-project ${HOST_PROJECT}
    

Configurar papéis do IAM

  1. No Cloud Shell, crie uma pasta de trabalho (WORKDIR) em que você cria os arquivos associados a esta seção:

    mkdir -p ~/td-shared-vpc
    cd ~/td-shared-vpc
    export WORKDIR=$(pwd)
    
  2. Configure permissões de IAM no projeto de host para que os projetos de serviço possam usar os recursos na VPC compartilhada.

    Nesta etapa, você configura as permissões do IAM para que subnet-1 possa ser acessado pelo projeto de serviço 1 e subnet-2 pelo projeto de serviço 2. Atribua o papel do IAM de Usuário da rede do Compute (roles/compute.networkUser) à conta de serviço padrão de computação do Compute Engine e à conta de serviço das APIs do Google Cloud em cada projeto de serviço para cada sub-rede.

    1. Para o projeto de serviço 1, configure as permissões do IAM para subnet-1:

      export SUBNET_1_ETAG=$(gcloud beta compute networks subnets get-iam-policy subnet-1 --project ${HOST_PROJECT} --region ${REGION_1} --format=json | jq -r '.etag')
      
      cat > subnet-1-policy.yaml <<EOF
      bindings:
      - members:
        - serviceAccount:${SVC_PROJECT_1_API_SA}
        - serviceAccount:${SVC_PROJECT_1_GKE_SA}
        role: roles/compute.networkUser
      etag: ${SUBNET_1_ETAG}
      EOF
      
      gcloud beta compute networks subnets set-iam-policy subnet-1 \
      subnet-1-policy.yaml \
          --project ${HOST_PROJECT} \
          --region ${REGION_1}
      
    2. Para o projeto de serviço 2, configure as permissões do IAM para subnet-2:

      export SUBNET_2_ETAG=$(gcloud beta compute networks subnets get-iam-policy subnet-2 --project ${HOST_PROJECT} --region ${REGION_2} --format=json | jq -r '.etag')
      
      cat > subnet-2-policy.yaml <<EOF
      bindings:
      - members:
        - serviceAccount:${SVC_PROJECT_2_API_SA}
        - serviceAccount:${SVC_PROJECT_2_GKE_SA}
        role: roles/compute.networkUser
      etag: ${SUBNET_2_ETAG}
      EOF
      
      gcloud beta compute networks subnets set-iam-policy subnet-2 \
      subnet-2-policy.yaml \
          --project ${HOST_PROJECT} \
          --region ${REGION_2}
      
  3. Para cada projeto de serviço, você precisa conceder o papel do IAM de Usuário do agente de serviço de host do Kubernetes Engine (roles/container.hostServiceAgentUser) à conta de serviço do GKE no projeto host:

    gcloud projects add-iam-policy-binding ${HOST_PROJECT} \
        --member serviceAccount:${SVC_PROJECT_1_GKE_SA} \
        --role roles/container.hostServiceAgentUser
    
    gcloud projects add-iam-policy-binding ${HOST_PROJECT} \
        --member serviceAccount:${SVC_PROJECT_2_GKE_SA} \
        --role roles/container.hostServiceAgentUser
    

    Com esse papel, a conta de serviço do GKE do projeto de serviço usa a conta de serviço do GKE do projeto host para configurar os recursos de rede compartilhados.

  4. Para cada projeto de serviço, conceda à conta de serviço padrão do Compute Engine o papel do IAM de Visualizador da rede do Compute (roles/compute.networkViewer) no projeto host.

    gcloud projects add-iam-policy-binding ${SVC_PROJECT_1} \
        --member serviceAccount:${SVC_PROJECT_1_COMPUTE_SA} \
        --role roles/compute.networkViewer
    
    gcloud projects add-iam-policy-binding ${SVC_PROJECT_2} \
        --member serviceAccount:${SVC_PROJECT_2_COMPUTE_SA} \
        --role roles/compute.networkViewer
    

    Quando o proxy sidecar do Envoy se conecta ao serviço xDS (API Traffic Director), o proxy usa a conta de serviço do host da máquina virtual (VM) do Compute Engine ou a instância do nó do GKE (link em inglês). A conta de serviço precisa ter a permissão compute.globalForwardingRules.get do IAM no nível do projeto. O papel de Visualizador de rede do Compute é suficiente para esta etapa.

Verificar a configuração da VPC compartilhada

  1. No Cloud Shell, verifique quais sub-redes podem ser usadas nos dois projetos de serviço:

    gcloud container subnets list-usable \
        --project ${SVC_PROJECT_1} \
        --network-project ${HOST_PROJECT}
    

    A resposta será semelhante a esta:

    PROJECT                       REGION    NETWORK     SUBNET    RANGE
    td-012345678-host-project  us-west1  shared-vpc  subnet-1  10.0.4.0/22
        ┌──────────────────────┬───────────────┬─────────────────────────────┐
        │ SECONDARY_RANGE_NAME │ IP_CIDR_RANGE │            STATUS           │
        ├──────────────────────┼───────────────┼─────────────────────────────┤
        │ subnet-1-pods        │ 10.4.0.0/14   │ usable for pods or services │
        │ subnet-1-services    │ 10.0.32.0/20  │ usable for pods or services │
        └──────────────────────┴───────────────┴─────────────────────────────┘
    

    Se nenhum item estiver listado, aguarde alguns instantes e execute o comando anterior novamente:

    gcloud container subnets list-usable \
        --project ${SVC_PROJECT_2} \
        --network-project ${HOST_PROJECT}
    

    A resposta será semelhante a esta:

    PROJECT                       REGION       NETWORK     SUBNET    RANGE
    td-012345678-host-project  us-central1  shared-vpc  subnet-2  172.16.4.0/22
        ┌──────────────────────┬────────────────┬─────────────────────────────┐
        │ SECONDARY_RANGE_NAME │ IP_CIDR_RANGE  │            STATUS           │
        ├──────────────────────┼────────────────┼─────────────────────────────┤
        │ subnet-2-pods        │ 172.20.0.0/14  │ usable for pods or services │
        │ subnet-2-services    │ 172.16.16.0/20 │ usable for pods or services │
        └──────────────────────┴────────────────┴─────────────────────────────┘
    

Na saída anterior, é possível ver que subnet-1 e os endereços secundários podem ser usados pelo projeto de serviço 1. Da mesma forma, subnet-2 e os endereços secundários podem ser usados pelo projeto de serviço 2.

Agora é possível criar recursos, como clusters do GKE, nos projetos de serviço que usam essas sub-redes.

Como criar clusters do GKE

Nesta seção, você criará dois clusters do GKE, um em cada projeto de serviço. Cada cluster usa uma sub-rede da VPC compartilhada. Não há clusters no projeto host, que é usado para recursos de rede compartilhados.

  1. No Cloud Shell, crie dois clusters do GKE, um em cada projeto de serviço:

    export GKE_1="gke-svc-1"
    export GKE_2="gke-svc-2"
    
    gcloud container clusters create ${GKE_1} \
        --project ${SVC_PROJECT_1} \
        --zone=${ZONE_1} \
        --enable-ip-alias \
        --scopes "https://www.googleapis.com/auth/cloud-platform" \
        --network projects/${HOST_PROJECT}/global/networks/shared-vpc \
        --subnetwork projects/${HOST_PROJECT}/regions/${REGION_1}/subnetworks/subnet-1 \
        --cluster-secondary-range-name subnet-1-pods \
        --services-secondary-range-name subnet-1-services --async
    
    gcloud container clusters create ${GKE_2} \
        --project ${SVC_PROJECT_2} \
        --zone=${ZONE_2} \
        --enable-ip-alias \
        --scopes "https://www.googleapis.com/auth/cloud-platform" \
        --network projects/${HOST_PROJECT}/global/networks/shared-vpc \
        --subnetwork projects/${HOST_PROJECT}/regions/${REGION_2}/subnetworks/subnet-2 \
        --cluster-secondary-range-name subnet-2-pods \
        --services-secondary-range-name subnet-2-services
    
  2. Confirme se os dois clusters estão em execução:

    gcloud container clusters list --project ${SVC_PROJECT_1}
    gcloud container clusters list --project ${SVC_PROJECT_2}
    

    Para gke_svc_1, a saída será assim:

    NAME       LOCATION    MASTER_VERSION  MASTER_IP       MACHINE_TYPE   NODE_VERSION   NUM_NODES  STATUS
    gke-svc-1  us-west1-a  1.13.10-gke.0   35.233.232.169  n1-standard-1  1.13.10-gke.0  3          RUNNING
    

    Para gke-svc-2, a saída será assim:

    NAME       LOCATION       MASTER_VERSION  MASTER_IP      MACHINE_TYPE   NODE_VERSION   NUM_NODES  STATUS
    gke-svc-2  us-central1-a  1.13.10-gke.0   35.232.172.85  n1-standard-1  1.13.10-gke.0  3          RUNNING
    
  3. Crie um novo arquivo kubeconfig para este tutorial:

    touch td-kubeconfig
    
    export KUBECONFIG=td-kubeconfig
    

    Depois de executar esse comando, o arquivo kubeconfig não interferirá no arquivo kubeconfig padrão. No final deste tutorial, é possível excluir a variável de ambiente KUBECONFIG e redefini-la para o padrão.

  4. Crie credenciais no arquivo kubeconfig para ambos os clusters e armazene os dois contextos nas variáveis para uso posterior:

    gcloud container clusters get-credentials ${GKE_1} \
        --project ${SVC_PROJECT_1} --zone ${ZONE_1}
    export GKE_SVC_1_CONTEXT=`kubectl config current-context`
    
    gcloud container clusters get-credentials ${GKE_2} \
        --project ${SVC_PROJECT_2} --zone ${ZONE_2}
    export GKE_SVC_2_CONTEXT=`kubectl config current-context`
    

Como implantar aplicativos

Implante aplicativos de amostra nos dois clusters do GKE. Com a ferramenta de linha de comando curl, você também cria uma implantação busybox nos dois clusters para testar a conectividade entre aplicativos.

  1. Faça o download do aplicativo de amostra e dos manifestos do BusyBox Kubernetes:

    wget https://storage.googleapis.com/solutions-public-assets/td-shared-vpc-gke/app1.yaml
    wget https://storage.googleapis.com/solutions-public-assets/td-shared-vpc-gke/busybox.yaml
    

    O aplicativo de amostra monitora a porta HTTP 80 e responde com o nome do host (nesse caso, o nome do pod).

  2. Implante o aplicativo de amostra e o aplicativo BusyBox nos dois clusters do GKE:

    kubectl apply -f app1.yaml --cluster $GKE_SVC_1_CONTEXT
    kubectl apply -f app1.yaml --cluster $GKE_SVC_2_CONTEXT
    kubectl apply -f busybox.yaml --cluster $GKE_SVC_1_CONTEXT
    kubectl apply -f busybox.yaml --cluster $GKE_SVC_2_CONTEXT
    

Inspecionar implantações

  1. Confirme se os dois aplicativos estão em execução em ambos os clusters do GKE:

    kubectl get pods --cluster $GKE_SVC_1_CONTEXT
    kubectl get pods --cluster $GKE_SVC_2_CONTEXT
    

    Para GKE_1, a saída será assim:

    NAME                      READY   STATUS    RESTARTS   AGE
    app1-f565f7c75-l867n      2/2     Running   0          93s
    app1-f565f7c75-tc652      2/2     Running   0          93s
    busybox-6dcf7d84f-2hntb   2/2     Running   0          90s
    

    Para GKE_2, a saída será assim:

    NAME                      READY   STATUS    RESTARTS   AGE
    app1-f565f7c75-sp5vf      2/2     Running   0          99s
    app1-f565f7c75-v578c      2/2     Running   0          99s
    busybox-6dcf7d84f-vccjl   2/2     Running   0          97s
    

    Em ambos os clusters do GKE, há dois pods do aplicativo de nome de host de amostra app1 e um pod do busybox em execução. Cada pod tem dois contêineres em execução.

  2. Inspecione os contêineres em execução em um dos pods app1 em um dos clusters do GKE:

    export APP1_POD_1=$(kubectl --cluster ${GKE_SVC_1_CONTEXT} get pods -l run=app1 | awk 'NR==2 {print $1}')
    kubectl get pods ${APP1_POD_1} --cluster ${GKE_SVC_1_CONTEXT} -o json | jq '.spec.containers[].image'
    

    A resposta será semelhante a esta:

    "gcr.io/kubernetes-e2e-test-images/serve-hostname-amd64:1.1"
    "docker.io/istio/proxyv2:1.1.2"
    

    É possível ver dois contêineres executando o pod app1. O primeiro é o contêiner do aplicativo de nome do host de amostra. O segundo contêiner é o proxy sidecar do Envoy que encaminha as solicitações de entrada e saída do pod.

  3. Inspecione a seção de argumentos do contêiner de proxy do Envoy:

    kubectl get pods ${APP1_POD_1} --cluster ${GKE_SVC_1_CONTEXT} -o json | jq '.spec.containers[1].args'
    

    A resposta será semelhante a esta:

    [
      "proxy",
      "sidecar",
      "--domain",
      "$(POD_NAMESPACE).svc.cluster.local",
      "--configPath",
      "/etc/istio/proxy",
      "--binaryPath",
      "/usr/local/bin/envoy",
      "--serviceCluster",
      "$(POD_NAMESPACE)",
      "--drainDuration",
      "45s",
      "--parentShutdownDuration",
      "1m0s",
      "--discoveryAddress",
      "trafficdirector.googleapis.com:443",
      "--proxyLogLevel",
      "info",
      "--connectTimeout",
      "10s",
      "--proxyAdminPort",
      "15000",
      "--concurrency",
      "2",
      "--statusPort",
      "15020"
    ]
    +
    

    A configuração de proxy discoveryAddress aponta para a API Traffic Director. É assim que os proxies do Envoy são configurados. Você configurará proxies do Envoy na seção a seguir.

Como configurar o Traffic Director

O Traffic Director configura os proxies sidecar do Envoy em execução dentro de cada pod de aplicativo para que eles possam se comunicar pela rede. Além disso, o Traffic Director usa uma configuração para permitir o tráfego leste-oeste entre os serviços. Essa configuração é semelhante à usada no balanceamento de carga HTTP(S) externo do Google Cloud para permitir o tráfego norte-sul de clientes externos de um serviço.

Configure os seguintes componentes para o Traffic Director:

O diagrama a seguir mostra o fluxo lógico do plano de controle e o fluxo de tráfego para os pods do Kubernetes ou instâncias de VM do Compute Engine.

O fluxo lógico do plano de controle e o tráfego para pods do Kubernetes ou instâncias de VM do Compute Engine.

Os pods do Kubernetes são representados como endpoints em um NEG pelos controladores de NEG, enquanto as instâncias de VM do Compute Engine são gerenciadas por grupos de instâncias gerenciadas (MIGs, na sigla em inglês). Os serviços de back-end podem ter um ou mais back-ends, que podem ser NEGs (neste caso, pods do Kubernetes) ou MIGs (neste caso, instâncias de VM do Compute Engine). O Traffic Director realiza o balanceamento de carga global com base na capacidade do NEG ou MIG e entrega os endpoints do NEG ou MIG com integridade verificada ao plano de dados.

O fluxo de tráfego é gerenciado usando informações nas regras de encaminhamento globais, proxies de destino e mapas de URL para rotear o tráfego para serviços de back-end.

Para configurar os componentes do Traffic Director e do Cloud Load Balancing, execute estas etapas:

  1. Encontre o nome do NEG para o aplicativo de amostra em execução nos dois clusters.

    export GKE_SVC_1_APP1_NEG=$(gcloud beta compute network-endpoint-groups list --project ${SVC_PROJECT_1} | grep west | awk '{print     $1}')
    export GKE_SVC_2_APP1_NEG=$(gcloud beta compute network-endpoint-groups list --project ${SVC_PROJECT_2} | grep central | awk'{print $1}')
    

    Os NEGs permitem o balanceamento de carga nativo do contêiner em clusters do GKE. É possível usar NEGs como back-ends por trás dos balanceadores de carga do Google Cloud.

  2. Crie verificações de integridade para o serviço de back-end nos dois projetos de serviço:

    gcloud compute health-checks create http td-gke-health-check-svc-proj-1 \
        --project ${SVC_PROJECT_1} --use-serving-port
    
    gcloud compute health-checks create http td-gke-health-check-svc-proj-2 \
        --project ${SVC_PROJECT_2} --use-serving-port
    
  3. Crie um serviço de back-end nos dois projetos de serviço e associe a verificação de integridade criada na etapa anterior aos serviços de back-end.

    gcloud compute backend-services create td-gke-service-svc-proj-1 \
        --project ${SVC_PROJECT_1} --global \
        --health-checks td-gke-health-check-svc-proj-1 \
        --load-balancing-scheme INTERNAL_SELF_MANAGED
    
    gcloud compute backend-services create td-gke-service-svc-proj-2 \
        --project ${SVC_PROJECT_2} --global \
        --health-checks td-gke-health-check-svc-proj-2 \
        --load-balancing-scheme INTERNAL_SELF_MANAGED
    
  4. Adicione os NEGs do aplicativo de amostra nos dois projetos de serviço como back-ends dos serviços de back-end.

    gcloud compute backend-services add-backend td-gke-service-svc-proj-1 \
        --project ${SVC_PROJECT_1} --global \
        --network-endpoint-group ${GKE_SVC_1_APP1_NEG} \
        --network-endpoint-group-zone ${ZONE_1} \
        --balancing-mode RATE \
        --max-rate-per-endpoint 5
    
    gcloud compute backend-services add-backend td-gke-service-svc-proj-2 \
        --project ${SVC_PROJECT_2} --global \
        --network-endpoint-group ${GKE_SVC_2_APP1_NEG} \
        --network-endpoint-group-zone ${ZONE_2} \
        --balancing-mode RATE \
        --max-rate-per-endpoint 5
    
  5. Crie um mapa de URL em cada projeto de serviço:

    gcloud compute url-maps create td-gke-url-map-svc-proj-1 \
        --project ${SVC_PROJECT_1} --default-service td-gke-service-svc-proj-1
    
    gcloud compute url-maps create td-gke-url-map-svc-proj-2 \
        --project ${SVC_PROJECT_2} --default-service td-gke-service-svc-proj-2
    
  6. Crie um proxy de destino em cada projeto de serviço:

    gcloud compute target-http-proxies create td-gke-proxy-svc-proj-1 \
        --project ${SVC_PROJECT_1} --url-map td-gke-url-map-svc-proj-1
    
    gcloud compute target-http-proxies create td-gke-proxy-svc-proj-2 \
        --project ${SVC_PROJECT_2} --url-map td-gke-url-map-svc-proj-2
    
  7. Reserve dois endereços IP estáticos internos a serem usados nas regras de encaminhamento dos dois serviços:

    gcloud compute addresses create static-ip-svc-proj-1 \
        --project ${SVC_PROJECT_1} \
        --subnet projects/${HOST_PROJECT}/regions/${REGION_1}/subnetworks/subnet-1 \
        --region=${REGION_1} --addresses 10.0.7.250
    
    gcloud compute addresses create static-ip-svc-proj-2 \
        --project ${SVC_PROJECT_2} \
        --subnet projects/${HOST_PROJECT}/regions/${REGION_2}/subnetworks/subnet-2 \
        --region=${REGION_2} --addresses 172.16.7.250
    
  8. Crie uma regra de encaminhamento em cada projeto de serviço:

    gcloud compute forwarding-rules create td-gke-forwarding-rule-svc-proj-1 \
        --project ${SVC_PROJECT_1} --global \
        --target-http-proxy td-gke-proxy-svc-proj-1 --ports 80 \
        --address https://www.googleapis.com/compute/v1/projects/"${SVC_PROJECT_1}"/regions/"${REGION_1}"/addresses/static-ip-svc-proj-1 \
        --network https://www.googleapis.com/compute/v1/projects/"${HOST_PROJECT}"/global/networks/shared-vpc \
        --load-balancing-scheme INTERNAL_SELF_MANAGED
    
    gcloud compute forwarding-rules create td-gke-forwarding-rule-svc-proj-2 \
        --project ${SVC_PROJECT_2} --global \
        --target-http-proxy td-gke-proxy-svc-proj-2 --ports 80 \
        --address https://www.googleapis.com/compute/v1/projects/"${SVC_PROJECT_2}"/regions/"${REGION_2}"/addresses/static-ip-svc-proj-2 \
        --network https://www.googleapis.com/compute/v1/projects/"${HOST_PROJECT}"/global/networks/shared-vpc \
        --load-balancing-scheme INTERNAL_SELF_MANAGED
    

Como testar a conectividade entre serviços

Você configurou o Traffic Director. Os proxies sidecar do Envoy em execução em cada pod de aplicativo agora podem se conectar pela rede em regiões e clusters. Em seguida, você testará a conectividade de rede entre os serviços implantados nos dois clusters do GKE.

  1. Encontre o nome do pod busybox em execução nos dois clusters do GKE. Use o nome do pod no teste de conectividade de rede:

    export BUSYBOX_SVC_PROJECT_1_POD=$(kubectl get pods -l run=client -o=jsonpath='{.items[0].metadata.name}' --cluster=${GKE_SVC_1_CONTEXT})
    export BUSYBOX_SVC_PROJECT_2_POD=$(kubectl get pods -l run=client -o=jsonpath='{.items[0].metadata.name}' --cluster=${GKE_SVC_2_CONTEXT})
    
  2. Verifique as configurações istio-proxy de um dos pods busybox:

    kubectl --context ${GKE_SVC_1_CONTEXT} exec ${BUSYBOX_SVC_PROJECT_1_POD} -c istio-proxy -- curl localhost:15000/clusters | grep neg
    

    A resposta será semelhante a esta:

    cloud-internal-istio:cloud_mp_748236137853_5025068062950697453::172.20.0.16:8000::sub_zone::jf:us-central1-a_3769163129600485500_neg
    cloud-internal-istio:cloud_mp_748236137853_5025068062950697453::172.20.1.10:8000::sub_zone::jf:us-central1-a_3769163129600485500_neg
    cloud-internal-istio:cloud_mp_397592564267_7855627510184552468::10.4.2.7:8000::sub_zone::pv:us-west1-a_4416141197590276889_neg
    cloud-internal-istio:cloud_mp_397592564267_7855627510184552468::10.4.0.11:8000::sub_zone::pv:us-west1-a_4416141197590276889_neg
    

    Nesta saída, o primeiro campo é um nome de serviço interno atribuído pelo Traffic Director. O segundo campo (endereço IP) é o endereço IP do pod para o serviço. O último campo representa a zona e o ID do NEG do pod. Você verá dois endereços IP de pod na zona us-central1-a dos pods app1 no cluster gke-svc-2. Você também verá dois endereços IP de pod na zona us-west1-a dos pods app1 no cluster gke-svc-1.

  3. Encontre os nomes do pod para o aplicativo de nome do host nos clusters do GKE dos dois projetos de serviço:

    kubectl get pods -l run=app1 --cluster=${GKE_SVC_1_CONTEXT}
    kubectl get pods -l run=app1 --cluster=${GKE_SVC_2_CONTEXT}
    

    Anote os nomes dos pods para testes de conectividade na próxima seção.

Testar a conectividade

  1. Teste as solicitações HTTP do pod do BusyBox no projeto de serviço 1 para o aplicativo do host no projeto de serviço 1:

    for i in {1..10}
    do
    kubectl exec -it ${BUSYBOX_SVC_PROJECT_1_POD}
    --cluster=${GKE_SVC_1_CONTEXT} -c busybox -- /bin/sh -c
    'wget -q -O - 10.0.7.250'; echo
    done
    

    O resultado é o nome do host dos pods da implantação em execução no cluster do GKE no projeto de serviço 1.

  2. Teste as solicitações HTTP do BusyBox no projeto de serviço 1 para o aplicativo do host no projeto de serviço 2:

    for i in {1..10}
    do
    kubectl exec -it ${BUSYBOX_SVC_PROJECT_1_POD}
    --cluster=${GKE_SVC_1_CONTEXT} -c busybox -- /bin/sh -c
    'wget -q -O - 172.16.7.250'; echo
    done
    

    O resultado é o nome do host dos pods da implantação em execução no cluster do GKE no projeto de serviço 2.

  3. Teste as solicitações HTTP do BusyBox no projeto de serviço 2 para o aplicativo de nome do host no projeto de serviço 2:

    for i in {1..10}
    do
    kubectl exec -it ${BUSYBOX_SVC_PROJECT_2_POD}
    --cluster=${GKE_SVC_2_CONTEXT} -c busybox -- /bin/sh -c
    'wget -q -O - 172.16.7.250'; echo
    done`
    

    O resultado é o nome do host dos pods da implantação em execução no cluster do GKE no projeto de serviço 2.

  4. Teste as solicitações HTTP do BusyBox no projeto de serviço 2 para o aplicativo do host no projeto de serviço 1:

    for i in {1..10}
    do
    kubectl exec -it ${BUSYBOX_SVC_PROJECT_2_POD}
    --cluster=${GKE_SVC_2_CONTEXT} -c busybox -- /bin/sh -c
    'wget -q -O - 10.0.7.250'; echo
    done
    

    O resultado é o nome do host dos pods da implantação em execução no cluster do GKE no projeto de serviço 1.

Você configurou o Traffic Director em uma VPC compartilhada para rotear o tráfego entre serviços em execução nos clusters do GKE em vários projetos de serviço.

Limpeza

Para evitar cobranças recorrentes na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Redefinir o kubeconfig

  • Redefina a variável KUBECONFIG para apontar para o arquivo kubeconfig padrão:

    unset KUBECONFIG
    

Excluir todos os projetos

A maneira mais fácil de evitar o faturamento é excluir os projetos criados para este tutorial. Antes de excluir os projetos, desative a VPC compartilhada. Para fazer isso, execute as seguintes etapas exatamente nesta ordem:

  1. Remova as regras de encaminhamento dos dois projetos de serviço:

    gcloud compute forwarding-rules delete td-gke-forwarding-rule \
        --project ${SVC_PROJECT_1} --global
    
    gcloud compute forwarding-rules delete td-gke-forwarding-rule \
        --project ${SVC_PROJECT_2} --global
    
  2. Remova os NEGs dos serviços de back-end dos dois projetos de serviço:

    gcloud compute backend-services remove-backend td-gke-service \
        --project ${SVC_PROJECT_1} --global \
        --network-endpoint-group ${GKE_SVC_1_APP1_NEG} \
        --network-endpoint-group-zone ${ZONE_1}
    
    gcloud compute backend-services remove-backend td-gke-service \
        --project ${SVC_PROJECT_2} --global \
        --network-endpoint-group ${GKE_SVC_2_APP1_NEG} \
        --network-endpoint-group-zone ${ZONE_2}
    
  3. Remova os NEGs dos dois projetos de serviço:

    gcloud compute network-endpoint-groups delete ${GKE_SVC_1_APP1_NEG} --project=${SVC_PROJECT_1} --zone=${ZONE_1} --quiet
    
    gcloud compute network-endpoint-groups delete ${GKE_SVC_2_APP1_NEG} --project=${SVC_PROJECT_2} --zone=${ZONE_2} --quiet
    
  4. Exclua os clusters do GKE dos dois projetos de serviço:

    gcloud container clusters delete ${GKE_1} --project=${SVC_PROJECT_1} --zone=${ZONE_1} --quiet
    
    gcloud container clusters delete ${GKE_2} --project=${SVC_PROJECT_2} --zone=${ZONE_2} --quiet
    
  5. Desvincule os projetos de serviço da VPC compartilhada:

    gcloud compute shared-vpc associated-projects remove ${SVC_PROJECT_1} --host-project ${HOST_PROJECT}
    
    gcloud compute shared-vpc associated-projects remove ${SVC_PROJECT_2} --host-project ${HOST_PROJECT}
    
  6. Desative a VPC compartilhada no projeto host:

    gcloud compute shared-vpc disable ${HOST_PROJECT}
    
  7. Exclua os três projetos criados para este tutorial:

    gcloud projects delete ${HOST_PROJECT}
    gcloud projects delete ${SVC_PROJECT_1}
    gcloud projects delete ${SVC_PROJECT_2}
    

A seguir