Neste tutorial, demonstramos como expor vários serviços gRPC implantados no Google Kubernetes Engine (GKE) em um único endereço IP externo usando um balanceador de carga de rede de passagem externo e o proxy Envoy. O tutorial destaca alguns dos recursos avançados do Envoy para gRPC.
Introdução
O gRPC é um framework de RPC de código aberto, independente de linguagem, baseado em HTTP/2 e que usa buffers de protocolo para uma representação de transmissão eficiente e uma serialização rápida. Inspirado no Stubby, um framework interno de RPC do Google, o gRPC permite comunicação de baixa latência entre microsserviços e entre clientes móveis e APIs.
Ele é executado via HTTP/2 e oferece várias vantagens em relação ao HTTP/1.1, como codificação binária eficiente, multiplexação de solicitações e respostas em uma única conexão e controle de fluxo automático. Além disso, também oferece várias opções de balanceamento de carga. Este tutorial se concentra em situações em que os clientes não são confiáveis, como clientes móveis e aqueles executados fora do limite de confiança do provedor de serviços. Dentre todas as opções de balanceamento de carga fornecidas pelo gRPC, você usará neste tutorial o balanceamento de carga baseado em proxy.
No tutorial, você implanta um serviço do Kubernetes de TYPE=LoadBalancer
, que
é exposto como balanceamento de carga de rede de passagem externo de camada de transporte (camada 4) no
Google Cloud. Esse serviço fornece um endereço IP público e transmite conexões TCP diretamente para os back-ends configurados. Nesse caso, o back-end será uma implantação do Kubernetes de instâncias do Envoy.
O Envoy é um proxy de camada de aplicativo de código aberto (camada 7) que oferece muitos recursos avançados. Neste tutorial, ele será utilizado para encerrar conexões TLS e encaminhar o tráfego do gRPC ao serviço do Kubernetes apropriado. Comparando com outras soluções de camada de aplicativo, como o Kubernetes Ingress, o Envoy proporciona várias opções de personalização, como as seguintes:
- Descoberta de serviço
- Algoritmos de balanceamento de carga
- Transformação de solicitações e respostas, por exemplo, para JSON ou gRPC-Web
- Autenticação de solicitações validando tokens JWT
- Verificações de integridade do gRPC
Ao combinar um balanceador de carga de rede de passagem externo com o Envoy, é possível configurar um endpoint (endereço IP externo) que encaminha o tráfego para um conjunto de instâncias do Envoy em execução em um cluster do Google Kubernetes Engine. Então, essas instâncias usam as informações da camada de aplicativo sobre solicitações de proxy nos diferentes serviços do gRPC em execução no cluster. As instâncias do Envoy usam o DNS do cluster para identificar e balancear a carga das solicitações de gRPC de entrada para os pods íntegros e em execução de cada serviço. Isso significa que a carga de tráfego é balanceada para os pods por solicitação de RPC, e não por conexão TCP do cliente.
Arquitetura
Neste tutorial, você implanta dois serviços do gRPC, echo-grpc
e reverse-grpc
, em um cluster do Google Kubernetes Engine (GKE) e os expõe à Internet em um endereço IP público. Veja no diagrama a seguir a arquitetura de envio desses dois serviços por meio de um único endpoint:
Um balanceador de carga de rede de passagem externo aceita solicitações recebidas da Internet (por exemplo, de clientes móveis ou consumidores de serviço fora da sua empresa). O balanceador de carga de rede de passagem externo executa as seguintes tarefas:
- Faz o balanceamento de carga das conexões de entrada para os nós no pool. O tráfego
é encaminhado para o serviço
envoy
do Kubernetes, que é exposto em todos os nós no cluster. O proxy de rede do Kubernetes encaminha as conexões para os pods que estão executando o Envoy. - Executa verificações de integridade HTTP em nós no cluster.
O Envoy executa as seguintes tarefas:
- Encerra as conexões TLS.
- Descobre os pods que executam os serviços do gRPC consultando o serviço de DNS do cluster interno.
- Encaminha e balanceia a carga de tráfego para os pods de serviço do gRPC.
- Executa verificações de integridade dos serviços do gRPC de acordo com o protocolo de verificação de integridade do gRPC (em inglês).
- Expõe um endpoint para verificação de integridade das instâncias do Envoy pelo balanceador de carga de rede de passagem externo.
Os serviços do gRPC (echo-grpc
e reverse-grpc
) são expostos como serviços headless do Kubernetes (em inglês).
Isso significa que nenhum endereço clusterIP
é atribuído, e o proxy de rede do Kubernetes não faz o balanceamento de carga do tráfego para os pods. Em vez disso, um registro A de DNS que contém os endereços IP dos pods é criado no serviço de DNS do cluster. O Envoy descobre os endereços a partir dessa entrada de DNS e divide a carga entre eles de acordo com a política configurada.
Veja no diagrama a seguir os objetos do Kubernetes usados neste tutorial:
Custos
Neste documento, você usará 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.
Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.
Antes de começar
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, activate Cloud Shell.
Prepare o ambiente
No Cloud Shell, defina o projeto do Google Cloud que você quer usar neste tutorial:
gcloud config set project PROJECT_ID
Substitua
PROJECT_ID
pelo ID do projeto do Google Cloud.Ative as APIs Artifact Registry e GKE:
gcloud services enable artifactregistry.googleapis.com \ container.googleapis.com
Criar o cluster do GKE
No Cloud Shell, crie um cluster do GKE para executar os serviços do gRPC:
gcloud container clusters create envoy-grpc-tutorial \ --enable-ip-alias \ --release-channel rapid \ --scopes cloud-platform \ --workload-pool PROJECT_ID.svc.id.goog \ --zone us-central1-f
Este tutorial usa a zona
us-central1-f
. É possível usar uma zona ou região diferente.Verifique se o contexto
kubectl
foi configurado listando os nós no cluster:kubectl get nodes --output name
A saída é semelhante a:
node/gke-envoy-grpc-tutorial-default-pool-c9a3c791-1kpt node/gke-envoy-grpc-tutorial-default-pool-c9a3c791-qn92 node/gke-envoy-grpc-tutorial-default-pool-c9a3c791-wf2h
Criar o repositório do Artifact Registry
No Cloud Shell, crie um novo repositório para armazenar imagens de contêiner:
gcloud artifacts repositories create envoy-grpc-tutorial-images \ --repository-format docker \ --location us-central1
Crie o repositório na mesma região do cluster do GKE para ajudar a otimizar a latência e a largura de banda da rede quando os nós extraírem imagens de contêiner.
Conceda o papel Leitor do Artifact Registry no repositório para a conta de serviço do Google usada pelas VMs de nó do cluster do GKE:
PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format 'value(projectNumber)') gcloud artifacts repositories add-iam-policy-binding envoy-grpc-tutorial-images \ --location us-central1 \ --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role roles/artifactregistry.reader
Adicione uma entrada auxiliar de credencial para o nome do host do repositório no arquivo de configuração do Docker no diretório principal do Cloud Shell:
gcloud auth configure-docker us-central1-docker.pkg.dev
A entrada auxiliar de credenciais permite que as ferramentas de imagem de contêiner em execução no Cloud Shell sejam autenticadas no local do repositório do Artifact Registry para extrair e enviar imagens.
Implantar os serviços do gRPC
Para rotear o tráfego para vários serviços do gRPC por trás de um balanceador de carga, implante
dois serviços de amostra do gRPC: echo-grpc
e reverse-grpc
. Os dois serviços expõem um
método unário que usa uma string no campo de solicitação content
. echo-grpc
responde com o conteúdo inalterado, enquanto reverse-grpc
responde com a
string de conteúdo invertida.
No Cloud Shell, clone o repositório que contém os serviços gRPC e mude para o diretório do repositório:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/networking/grpc-gke-nlb-tutorial/
Crie um certificado TLS autoassinado e uma chave privada:
openssl req -x509 -newkey rsa:4096 -nodes -sha256 -days 365 \ -keyout privkey.pem -out cert.pem -extensions san \ -config \ <(echo "[req]"; echo distinguished_name=req; echo "[san]"; echo subjectAltName=DNS:grpc.example.com ) \ -subj '/CN=grpc.example.com'
Crie um secret do Kubernetes chamado
envoy-certs
que contenha a chave privada e o certificado TLS autoassinado:kubectl create secret tls envoy-certs \ --key privkey.pem --cert cert.pem \ --dry-run=client --output yaml | kubectl apply --filename -
O Envoy usa esse certificado TLS e a chave privada quando encerra as conexões TLS.
Crie as imagens de contêiner para os aplicativos de amostra
echo-grpc
ereverse-grpc
, envie as imagens para o Artifact Registry e implante os aplicativos no cluster do GKE usando o Skaffold:skaffold run \ --default-repo=us-central1-docker.pkg.dev/PROJECT_ID/envoy-grpc-tutorial-images \ --module=echo-grpc,reverse-grpc \ --skip-tests
O Skaffold é uma ferramenta de código aberto do Google que automatiza fluxos de trabalho para desenvolvimento, criação, envio e implantação de aplicativos como contêineres.
Implante o Envoy no cluster do GKE usando o Skaffold:
skaffold run \ --digest-source=none \ --module=envoy \ --skip-tests
Verifique se dois pods estão prontos para cada implantação:
kubectl get deployments
A resposta será similar à mostrada a seguir. Os valores de
READY
precisam ser2/2
para todas as implantações.NAME READY UP-TO-DATE AVAILABLE AGE echo-grpc 2/2 2 2 1m envoy 2/2 2 2 1m reverse-grpc 2/2 2 2 1m
Verifique se
echo-grpc
,envoy
ereverse-grpc
existem como serviços do Kubernetes:kubectl get services --selector skaffold.dev/run-id
A resposta será similar à mostrada a seguir.
echo-grpc
ereverse-grpc
devem terTYPE=ClusterIP
eCLUSTER-IP=None
.NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo-grpc ClusterIP None <none> 8081/TCP 2m envoy LoadBalancer 10.40.2.203 203.0.113.1 443:31516/TCP 2m reverse-grpc ClusterIP None <none> 8082/TCP 2m
Testar os serviços do gRPC
Para testar os serviços, use a ferramenta de linha de comando
grpcurl
.
No Cloud Shell, instale
grpcurl
:go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
Consiga o endereço IP externo do serviço
envoy
do Kubernetes e armazene-o em uma variável de ambiente:EXTERNAL_IP=$(kubectl get service envoy \ --output=jsonpath='{.status.loadBalancer.ingress[0].ip}')
Envie uma solicitação para o app de amostra
echo-grpc
:grpcurl -v -d '{"content": "echo"}' \ -proto echo-grpc/api/echo.proto \ -authority grpc.example.com -cacert cert.pem \ $EXTERNAL_IP:443 api.Echo/Echo
A saída é semelhante a:
Resolved method descriptor: rpc Echo ( .api.EchoRequest ) returns ( .api.EchoResponse ); Request metadata to send: (empty) Response headers received: content-type: application/grpc date: Wed, 02 Jun 2021 07:18:22 GMT hostname: echo-grpc-75947768c9-jkdcw server: envoy x-envoy-upstream-service-time: 3 Response contents: { "content": "echo" } Response trailers received: (empty) Sent 1 request and received 1 response
O cabeçalho de resposta
hostname
mostra o nome do podecho-grpc
que processou a solicitação. Se você repetir o comando algumas vezes, verá dois valores diferentes para o cabeçalho de respostahostname
, correspondentes aos nomes dos pods deecho-grpc
.Verifique o mesmo comportamento com o serviço Reverse do gRPC:
grpcurl -v -d '{"content": "reverse"}' \ -proto reverse-grpc/api/reverse.proto \ -authority grpc.example.com -cacert cert.pem \ $EXTERNAL_IP:443 api.Reverse/Reverse
A saída é semelhante a:
Resolved method descriptor: rpc Reverse ( .api.ReverseRequest ) returns ( .api.ReverseResponse ); Request metadata to send: (empty) Response headers received: content-type: application/grpc date: Wed, 02 Jun 2021 07:20:15 GMT hostname: reverse-grpc-5c9b974f54-wlfwt server: envoy x-envoy-upstream-service-time: 1 Response contents: { "content": "esrever" } Response trailers received: (empty) Sent 1 request and received 1 response
Configuração do Envoy
Para entender melhor a configuração do Envoy, consulte o arquivo
de configuração envoy/k8s/envoy.yaml
no repositório Git.
A seção route_config
especifica como as solicitações de entrada são roteadas para os aplicativos de amostra echo-grpc
e reverse-grpc
.
Os apps de amostra são definidos como clusters do Envoy.
Os campos type: STRICT_DNS
e lb_policy: ROUND_ROBIN
na definição do cluster especificam que o Envoy executa pesquisas de DNS no nome do host especificado no campo address
e faz um balanceamento de carga nos endereços IP na resposta à busca DNS. A resposta contém vários endereços IP porque
os objetos do serviço do Kubernetes que definem os apps de amostra especificam
serviços headless.
O campo http2_protocol_options
especifica que o Envoy usa o protocolo
HTTP/2 para os apps de amostra.
O campo grpc_health_check
na seção health_checks
especifica que
o Envoy usa o protocolo de verificação de integridade gRPC para determinar a integridade dos
apps de amostra.
Resolver problemas
Se você tiver problemas ao seguir este tutorial, recomendamos que consulte estes documentos:
- Solução de problemas do GKE
- Como solucionar problemas de clusters do Kubernetes
- Como solucionar problemas de aplicativos implantados no Kubernetes
Você também pode analisar a interface de administração do Envoy para diagnosticar problemas com a configuração do Envoy.
Para abrir a interface de administração, configure o encaminhamento de portas do Cloud Shell para a porta
admin
de um dos pods do Envoy:kubectl port-forward \ $(kubectl get pods -o name | grep envoy | head -n1) 8080:8090
Espere até que esta saída seja exibida no console:
Forwarding from 127.0.0.1:8080 -> 8090
Clique no botão Visualização da Web no Cloud Shell e selecione Visualizar na porta 8080. Isso abre uma nova janela do navegador que mostra a interface de administração.
Quando terminar, volte para o Cloud Shell e pressione
Control+C
para encerrar o encaminhamento de portas.
Outras formas de rotear o tráfego do gRPC
É possível modificar essa solução de várias maneiras para adequá-la ao seu ambiente.
Balanceadores de carga de camada de aplicativo alternativos
Algumas das funcionalidades de camada do aplicativo fornecidas pelo Envoy também são disponibilizadas por outras soluções de balanceamento de carga:
É possível usar um balanceador de carga de aplicativo externo global ou regional em vez de um balanceador de carga de rede de passagem externo e um Envoy autogerenciado. O uso de um balanceador de carga de aplicativo externo oferece vários benefícios em comparação com um balanceador de carga de rede de passagem externo, como o recurso de gerenciamento de tráfego avançado, certificados TLS gerenciados e integração com outros produtos do Google Cloud, como o Cloud CDN, Google Cloud Armor e IAP.
Recomendamos o uso de um balanceador de carga de aplicativo externo global ou regional se os recursos de gerenciamento de tráfego que eles oferecem atenderem aos seus casos de uso e se você não precisar de suporte ao cliente para autenticação com base no certificado, também conhecida como autenticação TLS mútua (mTLS, na sigla em inglês). Para mais informações, consulte estes documentos:
Se você usar o Cloud Service Mesh ou o Istio, é possível usar os recursos deles para rotear e fazer o balanceamento de carga do tráfego do gRPC. O Cloud Service Mesh e o Istio fornecem um gateway de entrada que é implantado como balanceador de carga de rede de passagem externo com um back-end do Envoy, semelhante à arquitetura neste tutorial. A principal diferença é que o Envoy é configurado por meio dos objetos de roteamento de tráfego do Istio.
Para tornar os serviços de exemplo neste tutorial roteáveis na malha de serviço do Cloud Service Mesh ou do Istio, é necessário remover a linha
clusterIP: None
dos manifestos do serviço do Kubernetes (echo-service.yaml
ereverse-service.yaml
). Isso significa usar a funcionalidade de descoberta de serviço e balanceamento de carga do Cloud Service Mesh ou do Istio em vez da funcionalidade semelhante no Envoy.Se você já usa o Cloud Service Mesh ou o Istio, recomendamos o uso do gateway de entrada para rotear aos serviços do gRPC.
É possível usar o NGINX em vez do Envoy como uma implantação ou usando o controlador de entrada do NGINX para o Kubernetes (em inglês). Usamos o Envoy neste tutorial porque ele fornece funcionalidades de gRPC mais avançadas, como suporte ao protocolo de verificação de integridade do gRPC (em inglês).
Conectividade de rede interna VPC
Se você quiser expor os serviços fora do cluster do GKE, mas dentro da rede VPC, poderá usar um balanceador de carga de rede de passagem interno ou um balanceador de carga de aplicativo interno
Para usar um balanceador de carga de rede de passagem interno no lugar de um externo, adicione a anotação cloud.google.com/load-balancer-type: "Internal"
ao manifesto envoy-service.yaml
.
Para usar um balanceador de carga de aplicativo interno, consulte a documentação sobre Como configurar o Ingress para balanceadores de carga de aplicativo internos.
Limpar
Depois de concluir o tutorial, você pode limpar os recursos que criou para que eles parem de usar a cota e gerar cobranças. Nas seções a seguir, você aprenderá a excluir e desativar esses recursos.
Exclua o projeto
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Excluir os recursos
Se você quiser manter o projeto do Google Cloud usado neste tutorial, exclua os recursos individuais:
No Cloud Shell, exclua o clone do repositório Git local:
cd ; rm -rf kubernetes-engine-samples/networking/grpc-gke-nlb-tutorial/
Exclua o cluster do GKE:
gcloud container clusters delete envoy-grpc-tutorial \ --zone us-central1-f --async --quiet
Exclua o repositório no Artifact Registry:
gcloud artifacts repositories delete envoy-grpc-tutorial-images \ --location us-central1 --async --quiet
A seguir
- Leia sobre a rede do GKE.
- Veja exemplos de como exibir serviços do gRPC a clientes dentro do cluster do Kubernetes (em inglês).
Confira opções para o balanceamento de carga do gRPC (em inglês).
Confira arquiteturas de referência, diagramas, tutoriais e práticas recomendadas do Google Cloud. Confira o Centro de arquitetura do Cloud.