Este tutorial demonstra como expor vários serviços gRPC implementados no Google Kubernetes Engine (GKE) num único endereço IP externo através de um equilibrador de carga de rede de encaminhamento direto externo e do Envoy Proxy. O tutorial realça algumas das funcionalidades avançadas que o Envoy oferece para o gRPC.
Introdução
O gRPC é uma framework de RPC de código aberto e independente da linguagem baseada em HTTP/2 que usa memórias intermédias do protocolo para uma representação eficiente na rede e uma serialização rápida. Inspirado no Stubby, a framework de RPCs interna da Google, o gRPC permite uma comunicação de baixa latência entre microsserviços e entre clientes móveis e APIs.
O gRPC é executado através do HTTP/2 e oferece várias vantagens em relação ao HTTP/1.1, como a codificação binária eficiente, a multiplexagem de pedidos e respostas através de uma única ligação e o controlo de fluxo automático. O gRPC também oferece várias opções para o equilíbrio de carga. Este tutorial centra-se em situações em que os clientes não são fidedignos, como clientes móveis e clientes executados fora do limite de confiança do fornecedor de serviços. Das opções de equilíbrio de carga que o gRPC oferece, vai usar o equilíbrio de carga baseado em proxy neste tutorial.
No tutorial, implementa um serviço Kubernetes de TYPE=LoadBalancer
, que é exposto como um Network Load Balancer de encaminhamento externo da camada de transporte (camada 4) noGoogle Cloud. Este serviço fornece um único endereço IP público e passa as ligações TCP diretamente para os backends configurados. No tutorial, o back-end é uma implementação do Kubernetes de instâncias do Envoy.
O Envoy é um proxy de camada de aplicação (camada 7) de código aberto que oferece muitas funcionalidades avançadas. Neste tutorial, vai usá-lo para terminar as ligações TLS e encaminhar o tráfego gRPC para o serviço Kubernetes adequado. Em comparação com outras soluções da camada de aplicação, como o Kubernetes Ingress, a utilização do Envoy diretamente oferece várias opções de personalização, como as seguintes:
- Deteção de serviços
- Algoritmos de balanceamento de carga
- Transformar pedidos e respostas, por exemplo, em JSON ou gRPC-Web
- Autenticar pedidos validando tokens JWT
- Verificações de funcionamento gRPC
Ao combinar um Network Load Balancer de passagem externo com o Envoy, pode configurar um ponto final (endereço IP externo) que encaminha o tráfego para um conjunto de instâncias do Envoy em execução num cluster do Google Kubernetes Engine. Estas instâncias usam então informações da camada de aplicação para encaminhar pedidos para diferentes serviços gRPC em execução no cluster. As instâncias do Envoy usam o DNS do cluster para identificar e equilibrar a carga dos pedidos gRPC recebidos para os pods em funcionamento e em bom estado de cada serviço. Isto significa que o tráfego é equilibrado para os pods por pedido RPC, em vez de por ligação TCP do cliente.
Arquitetura
Neste tutorial, implementa dois serviços gRPC, echo-grpc
e reverse-grpc
, num cluster do Google Kubernetes Engine (GKE) e expõe-nos à Internet num endereço IP público. O diagrama seguinte mostra a arquitetura para expor estes dois serviços através de um único ponto final:
Um Network Load Balancer de encaminhamento externo aceita pedidos recebidos da Internet (por exemplo, de clientes móveis ou consumidores de serviços fora da sua empresa). O balanceador de carga de rede de encaminhamento externo realiza as seguintes tarefas:
- Equilibra a carga das ligações recebidas aos nós no conjunto. O tráfego é encaminhado para o serviço do Kubernetes, que é exposto em todos os nós no cluster.
envoy
O proxy de rede do Kubernetes encaminha estas ligações para pods que estão a executar o Envoy. - Realiza verificações de funcionamento de HTTP nos nós no cluster.
O Envoy realiza as seguintes tarefas:
- Termina as ligações TLS.
- Descobre pods que executam os serviços gRPC consultando o serviço DNS do cluster interno.
- Encaminha e equilibra o tráfego para os pods de serviço gRPC.
- Realiza verificações de funcionamento dos serviços gRPC de acordo com o protocolo de verificação de funcionamento do gRPC.
- Expõe um ponto final para a verificação de funcionamento das instâncias do Envoy pelo balanceador de carga de rede de encaminhamento externo.
Os serviços gRPC (echo-grpc
e reverse-grpc
) são expostos como
serviços sem cabeça do Kubernetes.
Isto significa que não é atribuído nenhum endereço clusterIP
e o proxy de rede do Kubernetes não equilibra a carga do tráfego para os pods. Em alternativa, é criado um registo A de DNS que
contém os endereços IP do pod no serviço DNS do cluster. O Envoy descobre os endereços IP dos pods a partir desta entrada de DNS e equilibra a carga entre eles de acordo com a política configurada no Envoy.
O diagrama seguinte mostra os objetos do Kubernetes envolvidos neste tutorial:
Custos
Neste documento, usa os seguintes componentes faturáveis do Google Cloud:
Para gerar uma estimativa de custos com base na sua utilização projetada,
use a calculadora de preços.
Quando terminar as tarefas descritas neste documento, pode evitar a faturação contínua eliminando os recursos que criou. Para mais informações, consulte o artigo Limpe.
Antes de começar
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
Verify 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 Google Cloud projeto que quer usar para este tutorial:
gcloud config set project PROJECT_ID
Substitua
PROJECT_ID
pelo ID do seu projeto.Google CloudAtive as APIs Artifact Registry e GKE:
gcloud services enable artifactregistry.googleapis.com \ container.googleapis.com
Crie o cluster do GKE
No Cloud Shell, crie um cluster do GKE para executar os seus serviços gRPC:
gcloud container clusters create envoy-grpc-tutorial \ --enable-ip-alias \ --release-channel rapid \ --scopes cloud-platform \ --workload-pool PROJECT_ID.svc.id.goog \ --location us-central1-f
Este tutorial usa a zona
us-central1-f
. Pode usar uma zona ou região diferente.Verifique se o contexto
kubectl
foi configurado listando os nós no seu cluster:kubectl get nodes --output name
O resultado tem o seguinte aspeto:
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
Crie o repositório do Artifact Registry
No Cloud Shell, crie um novo repositório para armazenar imagens de contentores:
gcloud artifacts repositories create envoy-grpc-tutorial-images \ --repository-format docker \ --location us-central1
Crie o repositório na mesma região que o cluster do GKE para ajudar a otimizar a latência e a largura de banda da rede quando os nós extraem imagens de contentores.
Conceda a função Leitor do Artifact Registry no repositório à conta de serviço Google usada pelas VMs de nós 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 de auxiliar de credenciais para o nome de anfitrião do repositório ao ficheiro de configuração do Docker no diretório base do Cloud Shell:
gcloud auth configure-docker us-central1-docker.pkg.dev
A entrada do auxiliar de credenciais permite que as ferramentas de imagem de contentores executadas no Cloud Shell se autentiquem na localização do repositório do Artifact Registry para extrair e enviar imagens.
Implemente os serviços gRPC
Para encaminhar tráfego para vários serviços gRPC atrás de um balanceador de carga, implementa dois serviços gRPC de exemplo:
echo-grpc
ereverse-grpc
. Ambos os serviços expõem um método unário que recebe uma string no campo de pedidocontent
.echo-grpc
responde com o conteúdo inalterado, enquantoreverse-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 segredo do Kubernetes denominado
envoy-certs
que contenha o certificado TLS autoassinado e a chave privada:kubectl create secret tls envoy-certs \ --key privkey.pem --cert cert.pem \ --dry-run=client --output yaml | kubectl apply --filename -
O Envoy usa este certificado TLS e chave privada quando termina as ligações TLS.
Crie as imagens de contentores para as apps de exemplo
echo-grpc
ereverse-grpc
, envie as imagens para o Artifact Registry e implemente as apps no cluster do GKE com 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 da Google que automatiza os fluxos de trabalho para desenvolver, criar, enviar e implementar aplicações como contentores.
Implemente o Envoy no cluster do GKE através do Skaffold:
skaffold run \ --digest-source=none \ --module=envoy \ --skip-tests
Verifique se existem dois pods prontos para cada implementação:
kubectl get deployments
O resultado tem um aspeto semelhante ao seguinte. Os valores de
READY
devem ser2/2
para todas as implementaçõ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
O resultado tem um aspeto semelhante ao seguinte. Tanto
echo-grpc
comoreverse-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
Teste os serviços gRPC
Para testar os serviços, use a ferramenta de linha de comandos
grpcurl
.No Cloud Shell, instale o
grpcurl
:go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
Obtenha o endereço IP externo do serviço Kubernetes e armazene-o numa variável de ambiente:
envoy
EXTERNAL_IP=$(kubectl get service envoy \ --output=jsonpath='{.status.loadBalancer.ingress[0].ip}')
Envie um pedido para a app de exemplo
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
O resultado tem o seguinte aspeto:
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 o pedido. Se repetir o comando algumas vezes, deve ver dois valores diferentes para o cabeçalho de respostahostname
, correspondentes aos nomes dos podsecho-grpc
.Verifique o mesmo comportamento com o serviço gRPC inverso:
grpcurl -v -d '{"content": "reverse"}' \ -proto reverse-grpc/api/reverse.proto \ -authority grpc.example.com -cacert cert.pem \ $EXTERNAL_IP:443 api.Reverse/Reverse
O resultado tem o seguinte aspeto:
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 compreender melhor a configuração do Envoy, pode consultar o ficheiro de configuração
envoy/k8s/envoy.yaml
no repositório Git.A secção
route_config
especifica como os pedidos recebidos são encaminhados para as apps de exemploecho-grpc
ereverse-grpc
.As apps de exemplo são definidas como clusters do Envoy.
Os campos
type: STRICT_DNS
elb_policy: ROUND_ROBIN
na definição do cluster especificam que o Envoy realiza procuras de DNS do nome de anfitrião especificado no campoaddress
e equilibra a carga nos endereços IP na resposta à procura de DNS. A resposta contém vários endereços IP porque os objetos de serviço do Kubernetes que definem as apps de exemplo especificam serviços sem cabeçalho.O campo
http2_protocol_options
especifica que o Envoy usa o protocolo HTTP/2 para as apps de exemplo.O campo
grpc_health_check
na secçãohealth_checks
especifica que o Envoy usa o protocolo de verificação de funcionamento gRPC para determinar o funcionamento das apps de exemplo.Resolver problemas
Se tiver problemas com este tutorial, recomendamos que reveja estes documentos:
- Resolução de problemas de clusters do Kubernetes
- Resolução de problemas de aplicações implementadas no Kubernetes
Também pode explorar 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 porta 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
Aguarde até ver este resultado na consola:
Forwarding from 127.0.0.1:8080 -> 8090
Clique no botão Pré-visualização na Web no Cloud Shell e selecione Pré-visualizar na porta 8080. Esta ação abre uma nova janela do navegador que mostra a interface de administração.
Quando terminar, volte ao Cloud Shell e prima
Control+C
para terminar o encaminhamento de portas.
Formas alternativas de encaminhar o tráfego gRPC
Pode modificar esta solução de várias formas para se adequar ao seu ambiente.
Balanceadores de carga da camada de aplicação alternativos
Algumas das funcionalidades da camada de aplicação que o Envoy oferece também podem ser oferecidas por outras soluções de equilíbrio de carga:
Pode usar um balanceador de carga de aplicações externo global ou um balanceador de carga de aplicações externo regional em vez de um balanceador de carga de rede de encaminhamento externo e um Envoy autogerido. A utilização de um Application Load Balancer externo oferece várias vantagens em comparação com um Network Load Balancer de passagem externo, como a capacidade de gestão de tráfego avançada, certificados TLS geridos e integração com outros Google Cloud produtos, como o Cloud CDN, o Google Cloud Armor e o IAP.
Recomendamos que use um Application Load Balancer externo global ou um Application Load Balancer externo regional se as capacidades de gestão de tráfego que oferecem satisfizerem os seus exemplos de utilização e se não precisar de suporte para autenticação baseada em certificados de cliente, também conhecida como autenticação TLS mútua (mTLS). Para mais informações, consulte os seguintes documentos:
Se usar o Cloud Service Mesh ou o Istio, pode usar as respetivas funcionalidades para encaminhar e equilibrar a carga do tráfego gRPC. Tanto a Cloud Service Mesh como o Istio fornecem um gateway de entrada implementado como um Network Load Balancer de passagem externo com um back-end do Envoy, semelhante à arquitetura neste tutorial. A principal diferença é que o Envoy é configurado através dos objetos de encaminhamento de tráfego do Istio.
Para tornar os serviços de exemplo neste tutorial encaminháveis na malha de serviços do Google Cloud ou na malha de serviços do Istio, tem de remover a linha
clusterIP: None
dos manifestos de serviços do Kubernetes (echo-service.yaml
ereverse-service.yaml
). Isto significa usar a funcionalidade de deteção de serviços e equilíbrio de carga da malha de serviços do Google Cloud ou do Istio em vez da funcionalidade semelhante no Envoy.Se já usa o Cloud Service Mesh ou o Istio, recomendamos que use o gateway de entrada para fazer o encaminhamento para os seus serviços gRPC.
Pode usar o NGINX em vez do Envoy, como uma implementação ou usando o controlador de entrada NGINX para Kubernetes. O Envoy é usado neste tutorial porque oferece uma funcionalidade gRPC mais avançada, como suporte para o protocolo de verificação do estado do gRPC.
Conetividade da rede de VPC interna
Se quiser expor os serviços fora do cluster do GKE, mas apenas na rede VPC, pode usar um Network Load Balancer de encaminhamento interno ou um Application Load Balancer interno.
Para usar um Network Load Balancer de encaminhamento interno em vez de um Network Load Balancer de encaminhamento externo, adicione a anotação
cloud.google.com/load-balancer-type: "Internal"
ao manifestoenvoy-service.yaml
.Para usar um balanceador de carga de aplicações interno, consulte a documentação sobre a configuração da entrada para balanceadores de carga de aplicações internos.
Limpar
Depois de concluir o tutorial, pode limpar os recursos que criou para que deixem de usar a quota e incorrer em custos. As secções seguintes descrevem como eliminar ou desativar estes recursos.
Elimine 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.
Elimine os recursos
Se quiser manter o Google Cloud projeto que usou neste tutorial, elimine os recursos individuais:
No Cloud Shell, elimine o clone do repositório Git local:
cd ; rm -rf kubernetes-engine-samples/networking/grpc-gke-nlb-tutorial/
Elimine o cluster do GKE:
gcloud container clusters delete envoy-grpc-tutorial \ --location us-central1-f --async --quiet
Elimine o repositório no Artifact Registry:
gcloud artifacts repositories delete envoy-grpc-tutorial-images \ --location us-central1 --async --quiet
O que se segue?
- Leia sobre a rede do GKE.
- Procure exemplos de como expôr serviços gRPC a clientes no seu cluster do Kubernetes.
Explore as opções de equilíbrio de carga do gRPC.
Explore arquiteturas de referência, diagramas e práticas recomendadas sobre o Google Cloud. Consulte o nosso Centro de arquitetura na nuvem.