Configuração do Traffic Director para pods do Google Kubernetes Engine com injeção automática do Envoy

Visão geral

Em uma malha de serviço, o código do aplicativo não precisa saber sobre sua configuração de rede. Em vez disso, seus aplicativos se comunicam por meio de um plano de dados, que é configurado por um plano de controle que gerencia a rede de serviços. Neste guia, o Traffic Director é seu plano de controle e os proxies sidecar do Envoy são seu plano de dados.

O injetor do sidecar do Envoy facilita a adição de proxies sidecar do Envoy aos pods do Google Kubernetes Engine. Quando o injetor do sidecar do Envoy adiciona um proxy, ele também o configura para processar o tráfego de aplicativos e se conectar ao Traffic Director para configuração.

No guia, mostramos uma configuração simples do Traffic Director com o Google Kubernetes Engine. Estas etapas representam a base que pode ser estendida a casos de uso avançados, como uma malha de serviço que se estende por vários clusters do Google Kubernetes Engine e, possivelmente, VMs do Compute Engine.

O processo de configuração envolve:

  1. criação um cluster do GKE para suas cargas de trabalho;
  2. instalação do injetor do sidecar do Envoy e ativação da injeção;
  3. implantação de um cliente de amostra e verificação da injeção;
  4. implantação de um serviço do Kubernetes para testes;
  5. configuração do Traffic Director com componentes do Cloud Load Balancing para rotear o tráfego para o serviço de teste;
  6. verificação da configuração enviando uma solicitação do cliente de amostra para o serviço de teste.
Visão geral dos componentes implantados como parte deste guia de configuração (clique para ampliar)
Visão geral dos componentes implantados como parte deste guia de configuração (clique para ampliar)

Pré-requisitos

Antes de seguir as instruções deste guia, leia a seção Como se preparar para a configuração do Traffic Director e verifique se você concluiu as tarefas de pré-requisito descritas nesse documento.

Como criar um cluster do GKE para suas cargas de trabalho

Os clusters do GKE precisam atender aos seguintes requisitos para serem compatíveis com o Traffic Director:

Como criar o cluster do GKE

Crie um cluster do GKE chamado traffic-director-cluster na zona us-central1-a.

gcloud container clusters create traffic-director-cluster \
  --zone us-central1-a \
  --scopes=https://www.googleapis.com/auth/cloud-platform \
  --enable-ip-alias

Como apontar o kubectl para o cluster recém-criado

Altere o contexto atual de kubectl para o cluster recém-criado emitindo o seguinte comando:

gcloud container clusters get-credentials traffic-director-cluster \
    --zone us-central1-a

Como instalar o injetor do sidecar do Envoy

Nas seções a seguir, fornecemos instruções para instalar o injetor do sidecar do Envoy. Quando o injetor do sidecar está ativado, ele implanta automaticamente proxies sidecar para cargas de trabalho novas e atuais do Google Kubernetes Engine. Como o injetor do sidecar do Envoy é executado dentro do cluster do GKE, você precisa instalá-lo uma vez em cada cluster se estiver usando o Traffic Director para aceitar uma malha de serviço de vários clusters.

Como fazer o download do injetor do sidecar

Faça o download e extraia o injetor do sidecar do Envoy.

wget https://storage.googleapis.com/traffic-director/td-sidecar-injector-xdsv3.tgz
tar -xzvf td-sidecar-injector-xdsv3.tgz
cd td-sidecar-injector-xdsv3

Como configurar o injetor do sidecar

Configure o injetor do sidecar editando specs/01-configmap.yaml para:

  • Preencha TRAFFICDIRECTOR_GCP_PROJECT_NUMBER substituindo YOUR_PROJECT_NUMBER_HERE pelo número do projeto. O número do projeto é o identificador numérico dele. Para informações sobre como conseguir uma lista de todos os projetos, consulte Como identificar projetos.
  • Preencha TRAFFICDIRECTOR_NETWORK_NAME substituindo YOUR_NETWORK_NAME_HERE pelo nome da rede da nuvem privada virtual do Google Cloud que você quer usar com o Traffic Director. Anote o nome dessa rede VPC, porque você precisará dele mais tarde ao configurar o Traffic Director.

Por exemplo, o arquivo pode ser assim:

$ cat ./td-sidecar-injector-xdsv3/specs/01-configmap.yaml
   apiVersion: v1
   kind: ConfigMap
   metadata:
     name: injector-mesh
     namespace: istio-control
   data:
     mesh: |-
       defaultConfig:
         discoveryAddress: trafficdirector.googleapis.com:443

         # Envoy proxy port to listen on for the admin interface.
         proxyAdminPort: 15000

         proxyMetadata:
           # GCP Project number where Traffic Director resources are configured.
           # This is a numeric identifier of your project (e.g. "111222333444").
           # You can get a list of all your projects with their corresponding numbers by
           # using "gcloud projects list" command or looking it up under "Project info"
           # section of your GCP console.
           # If left empty, configuration will be attempted to be fetched for the GCP
           # project associated with service credentials.
           # Leaving empty is not recommended as it is not guaranteed to work in future
           # releases.
           TRAFFICDIRECTOR_GCP_PROJECT_NUMBER: "YOUR_PROJECT_NUMBER_HERE"

           # GCP VPC network name for which the configuration is requested (This is the VPC
           # network name referenced in the forwarding rule in GCP API). If left empty,
           # configuration will be attempted to be fetched for the VPC network over which
           # the request to Traffic Director (trafficdirector.googleapis.com) is sent out.
           # Leaving empty is not recommended as it is not guaranteed to work in future
           # releases.
           TRAFFICDIRECTOR_NETWORK_NAME: "YOUR_NETWORK_NAME_HERE"

Também é possível ativar a geração de registros e o rastreamento para cada proxy que é injetado automaticamente. Para mais informações sobre essas configurações, consulte Como configurar atributos adicionais para proxies sidecar. Quando você usa o injetor de arquivo secundário, o valor de TRAFFICDIRECTOR_ACCESS_LOG_PATH só pode ser definido como um arquivo no diretório /etc/istio/proxy/. Por exemplo, o diretório /etc/istio/proxy/access.log é um local válido.

TRAFFICDIRECTOR_INTERCEPTION_PORT não pode ser configurado neste ConfigMap, porque ele já está configurado pelo injetor do sidecar.

Como configurar o TLS para o injetor do sidecar

Nesta seção, mostramos como configurar o TLS para o injetor do sidecar.

O injetor do sidecar usa um webhook de admissão mutável do Kubernetes (em inglês) para injetar proxies quando novos pods são criados. Esse webhook é um endpoint HTTPS, portanto, você precisa fornecer uma chave e um certificado para TLS.

É possível criar uma chave privada e um certificado autoassinado usando openssl para proteger o injetor do sidecar.

Opcionalmente, se você tiver sua própria chave privada e um certificado assinado por uma autoridade de certificação (CA, na sigla em inglês) confiável, pule esta próxima etapa.

CN=istio-sidecar-injector.istio-control.svc

openssl req \
  -x509 \
  -newkey rsa:4096 \
  -keyout key.pem \
  -out cert.pem \
  -days 365 \
  -nodes \
  -subj "/CN=${CN}" \
  -addext "subjectAltName=DNS:${CN}"

cp cert.pem ca-cert.pem

Este comando openssl de exemplo gera uma chave RSA privada de 4.096 bits para key.pem e um certificado autoassinado no formato X.509 para cert.pem. Como o certificado é autoassinado, ele é copiado para ca-cert.pem e considerado o certificado da CA de assinatura também. O certificado permanece válido por 365 dias e não requer uma senha longa. Para mais informações sobre a criação e a assinatura de certificados, consulte a documentação do Kubernetes sobre Solicitações de assinatura de certificado (em inglês).

As etapas desta seção precisam ser repetidas para gerar e reaplicar novas chaves e certificados antes que eles expirem.

Depois de ter a chave e os certificados, você precisa criar um secret do Kubernetes e atualizar o webhook do injetor do sidecar.

  1. Crie o namespace em que o secret do Kubernetes precisa ser criado:

    kubectl apply -f specs/00-namespaces.yaml
    
  2. Crie o secret para o injetor do sidecar.

    kubectl create secret generic istio-sidecar-injector -n istio-control \
      --from-file=key.pem \
      --from-file=cert.pem \
      --from-file=ca-cert.pem
    
  3. Modifique o caBundle do webhook de injeção do sidecar chamado istio-sidecar-injector-istio-control em specs/02-injector.yaml:

    CA_BUNDLE=$(cat cert.pem | base64 | tr -d '\n')
    sed -i "s/caBundle:.*/caBundle:\ ${CA_BUNDLE}/g" specs/02-injector.yaml
    

Como instalar o injetor do sidecar no cluster do GKE

  1. Implante o injetor do sidecar.

    kubectl apply -f specs/
    
  2. Verifique se o injetor do sidecar está em execução.

    kubectl get pods -A | grep sidecar-injector
    

    Com isso, será retornada uma resposta semelhante a esta:

    istio-control   istio-sidecar-injector-6b475bfdf9-79965  1/1 Running   0   11s
    istio-control   istio-sidecar-injector-6b475bfdf9-vntjd  1/1 Running   0   11s
    

Como abrir uma porta em um cluster particular

Se você estiver instalando o injetor de arquivo secundário do Envoy em um cluster particular, será necessário abrir a porta TCP 9443 na regra de firewall para os nós mestres para que o webhook funcione corretamente.

As etapas a seguir descrevem como atualizar a regra de firewall. Observe que o update substitui a regra de firewall atual. Portanto, inclua as portas padrão 443 (HTTPS) e 10250 (kubelet) e também a nova porta que você quer abrir.

  1. Encontre o intervalo de origem (master-ipv4-cidr) do cluster. No comando a seguir, substitua CLUSTER_NAME pelo nome do cluster:

    FIREWALL_RULE_NAME=$(gcloud compute firewall-rules list \
     --filter="name~gke-CLUSTER_NAME-[0-9a-z]*-master" \
     --format="value(name)")
    
  2. Atualize a regra de firewall para abrir a porta TCP 9443 para ativar a injeção automática:

    gcloud compute firewall-rules update ${FIREWALL_RULE_NAME} \
     --allow tcp:10250,tcp:443,tcp:9443
    

Como ativar a injeção do sidecar

O comando a seguir ativa a injeção do namespace default. O injetor do sidecar injeta contêineres de sidecar em pods criados nesse namespace:

kubectl label namespace default istio-injection=enabled

Verifique se o namespace default está ativado corretamente executando o seguinte:

kubectl get namespace -L istio-injection

Isso retornará:

NAME              STATUS   AGE     ISTIO-INJECTION
default           Active   7d16h   enabled
istio-control     Active   7d15h
istio-system      Active   7d15h

Como implantar um cliente de amostra e verificar a injeção

Nesta seção, mostramos como implantar um pod de amostra que executa o Busybox, que fornece uma interface simples para alcançar um serviço de teste. Em uma implantação real, você implantaria seu próprio aplicativo cliente.

kubectl create -f demo/client_sample.yaml

O pod do Busybox consiste em dois contêineres. O primeiro contêiner é o cliente com base na imagem do Busybox, e o segundo é o proxy Envoy inserido pelo injetor do sidecar. Para mais informações sobre o pod, execute o comando a seguir:

kubectl describe pods -l run=client

Isso retornará:

…
Init Containers:
# Istio-init sets up traffic interception for the pod.
  Istio-init:
…
Containers:
# busybox is the client container that runs application code.
  busybox:
…
# Envoy is the container that runs the injected Envoy proxy.
  envoy:
…

Como implantar um serviço do Kubernetes para testes

Nas seções a seguir, você verá instruções para configurar um serviço de teste que será usado posteriormente neste guia para fornecer uma verificação completa da configuração.

Como configurar serviços do GKE com NEGs

Os serviços do GKE precisam ser identificados usando grupos de endpoints de rede (NEGs, na sigla em inglês) para que seja possível configurá-los como back-ends de um serviço de back-end do Traffic Director. Adicione a anotação NEG à especificação de serviço do Kubernetes e escolha um nome (substituindo NEG-NAME no exemplo abaixo) para encontrá-lo facilmente depois. O nome será necessário ao anexar o NEG ao serviço de back-end do Traffic Director. Consulte Como nomear NEGs para mais informações sobre anotações de NEG.

...
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "NEG-NAME"}}}'
spec:
  ports:
  - port: 80
    name: service-test
    protocol: TCP
    targetPort: 8000

Essa anotação cria um NEG independente que contém endpoints correspondentes aos endereços IP e às portas dos pods do serviço. Para mais informações e exemplos, consulte Grupos de endpoints de rede autônomos.

Veja no exemplo de serviço a seguir a anotação NEG. O serviço exibe o nome do host por HTTP na porta 80. Use o comando a seguir para receber o serviço e implantá-lo no cluster do GKE.

wget -q -O - \
https://storage.googleapis.com/traffic-director/demo/trafficdirector_service_sample.yaml \
| kubectl apply -f -

Verifique se o novo serviço foi criado e se o pod do aplicativo está em execução:

kubectl get svc

A resposta será semelhante a:

NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service-test     ClusterIP   10.71.9.71   none          80/TCP    41m
[..skip..]

Verifique se o pod de aplicativo associado a este serviço está em execução:

kubectl get pods
Isso retorna:
NAME                        READY     STATUS    RESTARTS   AGE
app1-6db459dcb9-zvfg2       2/2       Running   0          6m
[..skip..]

Como salvar o nome do NEG

Encontre o NEG criado no exemplo acima e registre o nome dele para a configuração do Traffic Director na próxima seção.

gcloud compute network-endpoint-groups list

Isso retorna o resultado a seguir:

NAME                 LOCATION          ENDPOINT_TYPE      SIZE
NEG-NAME           us-central1-a     GCE_VM_IP_PORT      1

Salve o nome do NEG na variável NEG_NAME:

NEG_NAME=$(gcloud compute network-endpoint-groups list \
| grep service-test | awk '{print $1}')

Como configurar o Traffic Director com componentes do Cloud Load Balancing

Nesta seção, você configura o Traffic Director usando recursos de balanceamento de carga do Compute Engine. Isso permite que o proxy sidecar do cliente de amostra receba a configuração do Traffic Director. As solicitações de saída do cliente de amostra são processadas pelo proxy secundário e encaminhadas para o serviço de teste.

Você precisa configurar os componentes a seguir:

Como criar a verificação de integridade e a regra de firewall

Console

  1. Acesse a página "Verificações de integridade" no Console do Google Cloud.
    Acessar a página "Verificações de integridade"
  2. Clique em Criar verificação de integridade.
  3. Para o nome, insira td-gke-health-check.
  4. Como protocolo, selecione HTTP.
  5. Clique em Criar.

  6. Acesse a página "Firewall" no Console do Google Cloud.
    Acessar a página "Firewall"

  7. Clique em Criar regra de firewall.

  8. Na página Criar regra de firewall, forneça estas informações:

    • Nome: informe um nome para a regra. Neste exemplo, use fw-allow-health-checks.
    • Rede: escolha uma rede VPC.
    • Prioridade: informe um número para a prioridade. Números mais baixos têm prioridades mais altas. Certifique-se de que a regra de firewall tenha uma prioridade mais alta que outras regras que podem negar o tráfego de entrada.
    • Direção do tráfego: escolha entrada.
    • Ação se houver correspondência: escolha permitir.
    • Destinos: escolha Todas as instâncias na rede.
    • Filtro de origem: escolha Intervalos de IP.
    • Intervalos de IP de origem: 35.191.0.0/16,130.211.0.0/22.
    • Portas e protocolos permitidos: use tcp. O TCP é o protocolo subjacente a todos os protocolos de verificação de integridade.
    • Clique em Criar.

gcloud

  1. Crie a verificação de integridade.

    gcloud compute health-checks create http td-gke-health-check \
      --use-serving-port
    
  2. Crie a regra de firewall para permitir os intervalos de endereços IP do verificador de integridade.

    gcloud compute firewall-rules create fw-allow-health-checks \
      --action ALLOW \
      --direction INGRESS \
      --source-ranges 35.191.0.0/16,130.211.0.0/22 \
      --rules tcp
    

Como criar o serviço de back-end

Crie um serviço de back-end global com o esquema de balanceamento de carga INTERNAL_SELF_MANAGED. No Console do Cloud, o esquema de balanceamento de carga é definido implicitamente. Adicione a verificação de integridade ao serviço de back-end.

Console

  1. Acesse a página do Traffic Director no Console do Cloud.

    Acessar a página do Traffic Director

  2. Na guia Serviços, clique em Criar serviço.

  3. Clique em Continuar.

  4. Como nome do serviço, insira td-gke-service.

  5. Em Tipo de back-end, selecione Grupos de endpoints de rede.

  6. Selecione o grupo de endpoints de rede que você criou.

  7. Defina o RPS máximo como 5.

  8. Clique em Concluído.

  9. Em Verificação de integridade, selecione td-gke-health-check, que é a verificação de integridade que você criou.

  10. Clique em Continuar.

gcloud

  1. Crie o serviço de back-end e associe a verificação de integridade a ele.

    gcloud compute backend-services create td-gke-service \
     --global \
     --health-checks td-gke-health-check \
     --load-balancing-scheme INTERNAL_SELF_MANAGED
    
  2. Adicione o NEG criado anteriormente como um back-end ao serviço de back-end.

    gcloud compute backend-services add-backend td-gke-service \
     --global \
     --network-endpoint-group ${NEG_NAME} \
     --network-endpoint-group-zone us-central1-a \
     --balancing-mode RATE \
     --max-rate-per-endpoint 5
    

Como criar o mapa de regras de roteamento

O mapa de regras de roteamento define como o Traffic Director encaminha o tráfego na malha. Como parte do mapa de regras de roteamento, configure um endereço IP virtual (VIP) e um conjunto de regras de gerenciamento de tráfego associadas, como roteamento baseado em host. Quando um aplicativo envia uma solicitação ao VIP, o proxy sidecar do Envoy anexado faz o seguinte:

  1. Intercepta a solicitação.
  2. Avalia-a de acordo com as regras de gerenciamento de tráfego no mapa de URL.
  3. Seleciona um serviço de back-end com base no nome do host na solicitação.
  4. Escolhe um back-end ou endpoint associado ao serviço de back-end selecionado.
  5. Envia o tráfego para esse back-end ou endpoint.

Console

No console, o proxy de destino é combinado à regra de encaminhamento. Quando você cria a regra de encaminhamento, o Google Cloud cria automaticamente um proxy HTTP de destino e o anexa ao mapa de URL.

A regra de rota consiste na regra de encaminhamento e nas regras de host e caminho (também conhecida como mapa de URL).

  1. Acesse a página do Traffic Director no Console do Cloud.

    Acessar a página do Traffic Director

  2. Clique em Mapas de regra de roteamento.

  3. Clique em Criar regra de roteamento.

  4. Insira td-gke-url-map como o Nome do mapa de URL.

  5. Clique em Adicionar regra de encaminhamento.

  6. Como nome da regra de encaminhamento, insira td-gke-forwarding-rule.

  7. Selecione a rede.

  8. Selecione seu IP interno.

  9. Clique em Salvar.

  10. Opcionalmente, adicione regras de host e de caminho personalizadas ou use as regras padrão.

  11. Defina o host como service-test.

  12. Clique em Salvar.

gcloud

  1. Crie um mapa de URL que use td-gke-service como o serviço de back-end padrão.

    gcloud compute url-maps create td-gke-url-map \
       --default-service td-gke-service
    
  2. Crie uma correspondência de caminho do mapa de URL e uma regra de host para rotear o tráfego para o serviço com base no nome do host e em um caminho. Este exemplo usa service-test como o nome do serviço e uma correspondência de caminho padrão que corresponde a todas as solicitações de caminho para esse host (/*).

    gcloud compute url-maps add-path-matcher td-gke-url-map \
       --default-service td-gke-service \
       --path-matcher-name td-gke-path-matcher
    
    gcloud compute url-maps add-host-rule td-gke-url-map \
       --hosts service-test \
       --path-matcher-name td-gke-path-matcher
    
  3. Crie o proxy HTTP de destino.

    gcloud compute target-http-proxies create td-gke-proxy \
       --url-map td-gke-url-map
    
  4. Crie a regra de encaminhamento.

    gcloud compute forwarding-rules create td-gke-forwarding-rule \
      --global \
      --load-balancing-scheme=INTERNAL_SELF_MANAGED \
      --address=0.0.0.0 \
      --target-http-proxy=td-gke-proxy \
      --ports 80 --network default
    

Neste ponto, o Traffic Director configura seus proxies sidecar para rotear solicitações que especificam o nome de host service-test para back-ends de td-gke-service. Nesse caso, esses back-ends são endpoints no grupo de endpoints da rede associado ao serviço de teste do Kubernetes implantado anteriormente.

Como verificar a configuração

Nesta seção, veja como verificar se o tráfego enviado do cliente de amostra do Busybox é roteado para seu serviço do Kubernetes service-test. Para enviar uma solicitação de teste, acesse um shell em um dos contêineres e execute o comando de verificação a seguir. Um pod service-test retorna o nome do host do pod de serviço.

# Get the name of the pod running Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to execute that tests connectivity to the service service-test.
TEST_CMD="wget -q -O - service-test; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

Veja como a configuração é verificada:

  • O cliente de amostra enviou uma solicitação que especificou o nome do host service-test.
  • O cliente de amostra tem um proxy sidecar do Envoy que foi injetado pelo injetor do sidecar do Envoy.
  • O proxy secundário interceptou a solicitação.
  • Como você configurou 0.0.0.0 como VIP no mapa de regras de roteamento, o Envoy inspecionará o nome do host da solicitação.
  • Usando o mapa de URL, o Envoy correspondeu o nome do host service-test ao serviço td-gke-service do Traffic Director.
  • O Envoy escolheu um endpoint do grupo de endpoints de rede associado a td-gke-service.
  • O Envoy enviou a solicitação para um pod associado ao serviço service-test do Kubernetes.

A seguir

Dependendo de como os microsserviços são distribuídos na sua rede, talvez seja necessário adicionar mais regras de encaminhamento ou mais regras de host e caminho ao mapa de URL. Para mais informações sobre regras de encaminhamento e mapas de URL, leia os documentos a seguir: