Questo tutorial mostra come esporre più servizi gRPC di cui è stato eseguito il deployment Google Kubernetes Engine (GKE) su un singolo indirizzo IP esterno utilizzando una bilanciatore del carico di rete passthrough esterno e Proxy di Envoy. Il tutorial evidenzia alcune delle funzionalità avanzate fornite da Envoy per gRPC.
Introduzione
gRPC è un framework RPC open source indipendente dal linguaggio basato su HTTP/2 che utilizza buffer di protocollo per una rappresentazione on-the-wire efficiente e una rapida serializzazione. Ispirato a Stubby del framework RPC interno di Google, gRPC consente una bassa latenza la comunicazione tra microservizi e tra client mobile e API.
gRPC viene eseguito su HTTP/2 e offre diversi vantaggi rispetto a HTTP/1.1, quali: codifica binaria efficiente, multiplexing di richieste e risposte su un singolo e controllo automatico del flusso. gRPC offre anche diverse opzioni il bilanciamento del carico. Questo tutorial si concentra sulle situazioni in cui i client non sono attendibili, come i client mobile e i client in esecuzione al di fuori del confine di attendibilità del fornitore di servizi. Tra le opzioni di bilanciamento del carico fornite da gRPC, utilizzerai il bilanciamento del carico basato su proxy in questo tutorial.
Nel tutorial eseguirai il deployment di un servizio Kubernetes di TYPE=LoadBalancer
, che
è esposto come bilanciatore del carico di rete passthrough esterno di livello 4 (livello 4)
in Google Cloud. Questo servizio fornisce un singolo indirizzo IP pubblico e inoltra le connessioni TCP direttamente ai backend configurati. Nel tutorial, il backend è un deployment Kubernetes di istanze Envoy.
Envoy è un proxy open source a livello di applicazione (livello 7) che offre molte funzionalità avanzate. In questo tutorial, la utilizzerai per terminare TLS e instradare il traffico gRPC al servizio Kubernetes appropriato. Rispetto ad altre soluzioni a livello di applicazione come Kubernetes Ingress, l'utilizzo di Envoy offre direttamente più opzioni di personalizzazione, ad esempio:
- Service Discovery
- Algoritmi di bilanciamento del carico
- Trasformazione di richieste e risposte, ad esempio in JSON o gRPC-Web
- Autenticazione delle richieste mediante convalida dei token JWT
- Controlli di integrità gRPC
Combinando un bilanciatore del carico di rete passthrough esterno con Envoy, puoi configurare un endpoint (indirizzo IP esterno) che inoltra il traffico a una serie di istanze Envoy in esecuzione in un cluster Google Kubernetes Engine. Queste istanze utilizzano quindi le informazioni del livello di applicazione per eseguire il proxy delle richieste a diversi servizi gRPC in esecuzione nel cluster. Le istanze Envoy utilizzano il DNS del cluster per identificare e bilanciare il carico in entrata Richieste gRPC ai pod in stato integro e in esecuzione per ciascun servizio. Ciò significa il traffico viene distribuito con bilanciamento del carico ai pod in base a richiesta RPC anziché per TCP di connessione dal client.
Architettura
In questo tutorial, esegui il deployment di due servizi gRPC, echo-grpc
e reverse-grpc
,
in un cluster Google Kubernetes Engine (GKE) e li esponi a internet
su un indirizzo IP pubblico. Il seguente diagramma mostra l'architettura per l'esposizione di questi due servizi tramite un unico endpoint:
Un bilanciatore del carico di rete passthrough esterno accetta le richieste in entrata da internet (ad esempio da client mobile o utenti finali di servizi esterni alla tua azienda). Il bilanciatore del carico di rete passthrough esterno esegue le seguenti attività:
- Esegue il bilanciamento del carico delle connessioni in entrata ai nodi del pool. Traffico
viene inoltrato al servizio Kubernetes
envoy
, che è esposto su tutti nodi nel cluster. Il proxy di rete Kubernetes inoltra questi delle connessioni ai pod che eseguono Envoy. - Esegue controlli di integrità HTTP sui nodi del cluster.
Envoy esegue le seguenti attività:
- Termina le connessioni TLS.
- Individua i pod che eseguono i servizi gRPC eseguendo una query sul servizio DNS del cluster interno.
- Instrada il traffico e bilancia il carico verso i pod del servizio gRPC.
- Esegue controlli di integrità dei servizi gRPC in base al protocollo di controllo di integrità gRPC.
- Espone un endpoint per il controllo di integrità delle istanze Envoy da parte del bilanciatore del carico di rete passthrough esterno.
I servizi gRPC (echo-grpc
e reverse-grpc
) sono esposti come
servizi headless Kubernetes.
Ciò significa che non è stato assegnato alcun indirizzo clusterIP
e il proxy di rete Kubernetes non esegue il bilanciamento del carico del traffico verso i pod. Al contrario, un record A DNS
contiene gli indirizzi IP dei pod creati nel servizio DNS del cluster. Envoy
rileva gli indirizzi IP dei pod da questa voce DNS e dai bilanciatori del carico
in base al criterio configurato in Envoy.
Il seguente diagramma mostra gli oggetti Kubernetes coinvolti in questo tutorial:
Costi
In questo documento utilizzi i seguenti componenti fatturabili di Google Cloud:
Per generare una stima dei costi basata sull'utilizzo previsto,
utilizza il Calcolatore prezzi.
Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.
Prima di iniziare
-
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.
prepara l'ambiente
In Cloud Shell, imposta il progetto Google Cloud che da usare per questo tutorial:
gcloud config set project PROJECT_ID
Sostituisci
PROJECT_ID
con il tuo ID progetto Google Cloud.Abilita le API Artifact Registry e GKE:
gcloud services enable artifactregistry.googleapis.com \ container.googleapis.com
crea il cluster GKE
In Cloud Shell, crea un cluster GKE per eseguire i tuoi servizi 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
Questo tutorial utilizza la zona
us-central1-f
. Puoi utilizzare un'altra zona o regione.Verifica che il contesto
kubectl
sia stato configurato elencando il nodi nel tuo cluster:kubectl get nodes --output name
L'output è simile al seguente:
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
Crea il repository Artifact Registry
In Cloud Shell, crea un nuovo repository in cui archiviare le immagini container:
gcloud artifacts repositories create envoy-grpc-tutorial-images \ --repository-format docker \ --location us-central1
Il repository viene creato nella stessa regione di GKE per ottimizzare la latenza e la larghezza di banda della rete quando i nodi eseguono il pull immagini container.
Concedi Lettore Artifact Registry del repository all'account di servizio Google utilizzato dalle VM del nodo del cluster 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
Aggiungi una voce di helper delle credenziali per il nome host del repository al file di configurazione Docker nella home directory di Cloud Shell:
gcloud auth configure-docker us-central1-docker.pkg.dev
La voce di utilità per le credenziali consente agli strumenti per le immagini dei container in esecuzione in Cloud Shell di autenticarsi nella posizione del repository Artifact Registry per il pull e il push delle immagini.
Esegui il deployment dei servizi gRPC
Per instradare il traffico a più servizi gRPC dietro un bilanciatore del carico, esegui il deployment
due servizi gRPC di esempio: echo-grpc
e reverse-grpc
. Entrambi i servizi espongono un metodo unario che accetta una stringa nel campo della richiesta content
. echo-grpc
risponde con i contenuti invariati, mentre reverse-grpc
risponde con la
stringa di contenuti invertita.
In Cloud Shell, clona il repository contenente i servizi gRPC e passa alla directory del repository:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/networking/grpc-gke-nlb-tutorial/
Crea un certificato TLS autofirmato e una chiave privata:
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'
Crea un segreto Kubernetes denominato
envoy-certs
che contenga il certificato TLS autofirmato e la chiave privata:kubectl create secret tls envoy-certs \ --key privkey.pem --cert cert.pem \ --dry-run=client --output yaml | kubectl apply --filename -
Envoy utilizza questo certificato TLS e questa chiave privata quando termina TLS e connessioni a Internet.
Crea le immagini container per le app di esempio
echo-grpc
ereverse-grpc
, esegui il push delle immagini in Artifact Registry ed esegui il deployment delle app al cluster GKE, utilizzando Skaffold:skaffold run \ --default-repo=us-central1-docker.pkg.dev/PROJECT_ID/envoy-grpc-tutorial-images \ --module=echo-grpc,reverse-grpc \ --skip-tests
Skaffold è uno strumento open source di Google che automatizza i flussi di lavoro per lo sviluppo, la creazione, il push e il deployment delle applicazioni come container.
Esegui il deployment di Envoy nel cluster GKE utilizzando Skaffold:
skaffold run \ --digest-source=none \ --module=envoy \ --skip-tests
Verifica che due pod siano pronti per ogni deployment:
kubectl get deployments
L'output è simile al seguente. I valori per
READY
devono essere2/2
per tutti i deployment.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
Verifica che
echo-grpc
,envoy
ereverse-grpc
esistano come Kubernetes Servizi:kubectl get services --selector skaffold.dev/run-id
L'output è simile al seguente. Sia
echo-grpc
chereverse-grpc
devono avereTYPE=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
Testa i servizi gRPC
Per testare i servizi, utilizza
grpcurl
a strumento a riga di comando.
In Cloud Shell, installa
grpcurl
:go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
Ottieni l'indirizzo IP esterno del servizio Kubernetes
envoy
e archivialo in una variabile di ambiente:EXTERNAL_IP=$(kubectl get service envoy \ --output=jsonpath='{.status.loadBalancer.ingress[0].ip}')
Invia una richiesta all'app di esempio
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
L'output è simile al seguente:
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
L'intestazione della risposta
hostname
mostra il nome del podecho-grpc
che ha gestito la richiesta. Se ripeti il comando alcune volte, dovresti vedere due valori diversi per l'intestazione di rispostahostname
, corrispondenti ai nomi dei podecho-grpc
.Verifica lo stesso comportamento con il servizio 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
L'output è simile al seguente:
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
Configurazione Envoy
Per comprendere meglio la configurazione di Envoy, puoi esaminare il file di configurazione envoy/k8s/envoy.yaml
nel repository Git.
La sezione route_config
specifica in che modo le richieste in entrata vengono instradate
App di esempio echo-grpc
e reverse-grpc
.
Le app di esempio sono definite Cluster di Envoy.
I campi type: STRICT_DNS
e lb_policy: ROUND_ROBIN
nella definizione del cluster specificano che Envoy esegue ricerche DNS del nome host specificato nel campo address
e il bilanciamento del carico tra gli indirizzi IP nella risposta alla ricerca DNS. La risposta contiene più indirizzi IP perché gli oggetti Kubernetes Service che definiscono le app di esempio specificano servizi headless.
Il campo http2_protocol_options
specifica che Envoy utilizza il protocollo HTTP/2 per le app di esempio.
Il campo grpc_health_check
nella sezione health_checks
specifica che
Envoy utilizza il protocollo per il controllo di integrità gRPC per determinare l'integrità del
app di esempio.
Risoluzione dei problemi
Se riscontri problemi con questo tutorial, ti consigliamo di esaminare i seguenti documenti:
- Risoluzione dei problemi dei cluster Kubernetes
- Risoluzione dei problemi delle applicazioni di cui è stato eseguito il deployment su Kubernetes
Puoi anche esplorare l'interfaccia di amministrazione di Envoy per diagnosticare i problemi relativi alla configurazione di Envoy.
Per aprire l'interfaccia di amministrazione, configura il port forwarding da Cloud Shell alla porta
admin
di uno dei pod Envoy:kubectl port-forward \ $(kubectl get pods -o name | grep envoy | head -n1) 8080:8090
Attendi finché non viene visualizzato questo output nella console:
Forwarding from 127.0.0.1:8080 -> 8090
Fai clic sul pulsante Anteprima web in Cloud Shell e seleziona Anteprima sulla porta 8080. Viene visualizzata una nuova finestra del browser in cui a riga di comando gcloud.
Al termine, torna a Cloud Shell premi
Control+C
per terminare il port forwarding.
Metodi alternativi per instradare il traffico gRPC
Puoi modificare questa soluzione in vari modi per adattarla al tuo ambiente.
Bilanciatori del carico a livello di applicazione alternativi
Alcune delle funzionalità del livello di applicazione fornite da Envoy possono essere fornite anche da altre soluzioni di bilanciamento del carico:
Puoi utilizzare uno dei seguenti Bilanciatore del carico delle applicazioni esterno globale o bilanciatore del carico delle applicazioni esterno regionale invece di un bilanciatore del carico di rete passthrough esterno e di Envoy autogestito. L'utilizzo di un il bilanciatore del carico delle applicazioni esterno offre diversi vantaggi rispetto a un bilanciatore del carico di rete passthrough esterno, come funzionalità avanzate di gestione del traffico, certificati TLS gestiti, e l'integrazione con altri prodotti Google Cloud come Cloud CDN, Google Cloud Armor e IAP.
Ti consigliamo di utilizzare un bilanciatore del carico delle applicazioni esterno globale oppure Bilanciatore del carico delle applicazioni esterno regionale se offre funzionalità di gestione del traffico soddisfare i tuoi casi d'uso e se non hai bisogno di assistenza per autenticazione basata su certificati, nota anche come TLS reciproca (mTLS) autenticazione. Per ulteriori informazioni, consulta i seguenti documenti:
Se utilizzi Cloud Service Mesh o Istio, puoi utilizzare le relative funzionalità per instradare e bilanciare il carico del traffico gRPC. Sia Cloud Service Mesh che Istio forniscono Gateway in entrata distribuito come bilanciatore del carico di rete passthrough esterno con un backend Envoy, all'architettura. La differenza principale è che Envoy viene configurato tramite il protocollo instradamento del traffico di oggetti strutturati.
Come rendere instradabili i servizi di esempio di questo tutorial in Cloud Service Mesh o il mesh di servizi Istio, devi rimuovere la riga
clusterIP: None
dal Manifest dei servizi Kubernetes (echo-service.yaml
ereverse-service.yaml
). Ciò significa utilizzare il Service Discovery e caricamento funzionalità di bilanciamento di Cloud Service Mesh o Istio anziché le sue funzionalità in Envoy.Se utilizzi già Cloud Service Mesh o Istio, ti consigliamo di utilizzare il gateway di ingresso per eseguire il routing ai tuoi servizi gRPC.
Puoi utilizzare NGINX al posto di Envoy, come deployment o utilizzando Controller Ingress NGINX per Kubernetes. In questo tutorial viene utilizzato Envoy perché fornisce gRPC più avanzato funzionalità, come il supporto per protocollo per il controllo di integrità gRPC.
Connettività di rete VPC interna
Se vuoi esporre i servizi all'esterno del cluster GKE, solo all'interno della tua rete VPC, puoi utilizzare bilanciatore del carico di rete passthrough interno o un bilanciatore del carico delle applicazioni interno.
Per utilizzare un bilanciatore del carico di rete passthrough interno al posto di un bilanciatore del carico di rete passthrough esterno, aggiungi l'annotazione cloud.google.com/load-balancer-type: "Internal"
al manifest envoy-service.yaml
.
Per utilizzare un bilanciatore del carico delle applicazioni interno, consulta la documentazione sulla configurazione di Ingress per i bilanciatori del carico delle applicazioni interni.
Esegui la pulizia
Al termine del tutorial, puoi eliminare le risorse che hai creato in modo che smettano di utilizzare la quota e di generare addebiti. Le seguenti sezioni descrivono come eliminare o disattivare queste risorse.
Elimina il progetto
- 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.
Elimina le risorse
Se vuoi conservare il progetto Google Cloud che hai usato in questo tutorial, elimina le singole risorse:
In Cloud Shell, elimina il clone del repository Git locale:
cd ; rm -rf kubernetes-engine-samples/networking/grpc-gke-nlb-tutorial/
Elimina il cluster GKE:
gcloud container clusters delete envoy-grpc-tutorial \ --zone us-central1-f --async --quiet
Elimina il repository in Artifact Registry:
gcloud artifacts repositories delete envoy-grpc-tutorial-images \ --location us-central1 --async --quiet
Passaggi successivi
- Scopri di più sul networking GKE.
- Guarda alcuni esempi su come esporre i servizi gRPC ai client all'interno del tuo cluster Kubernetes.
Esplora le opzioni per Bilanciamento del carico gRPC.
Esplora architetture di riferimento, diagrammi e best practice su Google Cloud. Dai un'occhiata al nostro Centro architetture cloud.