Ce tutoriel explique comment exposer plusieurs services gRPC déployés sur Google Kubernetes Engine (GKE) avec une seule adresse IP externe à l'aide d'un équilibreur de charge réseau passthrough externe et du proxy Envoy. Il présente certaines des fonctionnalités avancées fournies par Envoy pour gRPC.
Présentation
gRPC est un framework RPC open source, indépendant du langage et basé sur HTTP/2, qui utilise le format Protocol Buffers pour une représentation efficace des messages sur le réseau et une sérialisation rapide. Inspiré de Stubby, le framework RPC interne à Google, gRPC permet une communication à faible latence entre microservices, et entre clients mobiles et API.
gRPC s'exécute sur HTTP/2, ce qui présente plusieurs avantages par rapport à HTTP/1.1, comme l'encodage binaire efficace, le multiplexage des requêtes et des réponses via une connexion unique, et le contrôle de flux automatique. gRPC propose également plusieurs options pour l'équilibrage de charge. Ce tutoriel porte sur les cas où les clients ne sont pas approuvés, comme par exemple les clients mobiles et les clients s'exécutant en dehors de la limite de confiance du fournisseur de services. Dans ce tutoriel, vous allez utiliser l'équilibrage de charge basé sur un proxy, l'une des options d’équilibrage de charge fournies par gRPC.
Vous allez déployer un service Kubernetes de type TYPE=LoadBalancer
, exposé sur Google Cloud en tant qu'équilibreur de charge réseau passthrough externe au niveau de la couche de transport (couche 4). Ce service fournit une adresse IP publique unique et transmet les connexions TCP directement aux backends configurés. Dans ce tutoriel, le backend est un déploiement Kubernetes d'instances Envoy.
Envoy est un proxy open source situé au niveau de la couche d'application (couche 7) qui offre de nombreuses fonctionnalités avancées. Dans ce tutoriel, vous allez l'utiliser pour mettre fin aux connexions TLS et acheminer le trafic gRPC vers le service Kubernetes approprié. Par rapport à d'autres solutions de couche d'application, telles que les ressources d'entrée Kubernetes, Envoy, lorsqu'il est utilisé directement, fournit plusieurs options de personnalisation, telles que :
- Découverte des services
- Algorithmes d'équilibrage de charge
- Transcodage de requêtes et de réponses, par exemple, au format JSON ou gRPC-Web
- Authentification des requêtes en validant les jetons JWT
- Vérifications de l'état gRPC
En combinant un équilibreur de charge réseau passthrough externe avec Envoy, vous pouvez configurer un point de terminaison (adresse IP externe) qui transfère le trafic vers un ensemble d'instances Envoy s'exécutant dans un cluster Google Kubernetes Engine. Ces instances utilisent ensuite les informations de la couche d'application en guise de proxy pour les requêtes envoyées à différents services gRPC s'exécutant dans le cluster. Les instances Envoy utilisent le DNS du cluster pour identifier et équilibrer la charge des requêtes gRPC entrantes sur les pods sains et en cours d'exécution pour chaque service. Cela signifie que le trafic est équilibré en fonction du nombre de pods par requête RPC plutôt que par connexion TCP du client.
Architecture
Dans ce tutoriel, vous allez déployer deux services gRPC (echo-grpc
et reverse-grpc
) dans un cluster Google Kubernetes Engine (GKE) et les exposer à Internet sur une adresse IP publique. Le schéma suivant illustre l'architecture permettant d'exposer ces deux services via un seul point de terminaison :
Un équilibreur de charge réseau passthrough externe accepte les requêtes entrantes provenant d'Internet (par exemple, de clients mobiles ou de clients de services extérieurs à votre entreprise). L'équilibreur de charge réseau passthrough externe effectue les tâches suivantes :
- Équilibrage de charge des connexions entrantes vers les nœuds du pool. Le trafic est transféré vers le service Kubernetes
envoy
, qui est exposé sur tous les nœuds du cluster. Le proxy réseau Kubernetes transmet ces connexions aux pods exécutant Envoy. - Vérifications de l'état HTTP sur les nœuds du cluster
Envoy effectue les tâches suivantes :
- Désactivation des connexions TLS
- Découverte des pods exécutant les services gRPC via l'interrogation du service DNS du cluster interne
- Routage et équilibrage de charge du trafic vers les pods de service gRPC
- Vérifications de l'état des services gRPC conformément au protocole de vérification de l'état gRPC
- Exposition d'un point de terminaison pour la vérification de l'état des instances Envoy par l'équilibreur de charge réseau passthrough externe
Les services gRPC echo-grpc
et reverse-grpc
sont exposés en tant que services Kubernetes sans adresse IP de cluster.
Cela signifie qu'aucune adresse clusterIP
n'est attribuée et que le proxy réseau Kubernetes n'équilibre pas le trafic vers les pods. À la place, un enregistrement DNS A contenant les adresses IP des pods est créé dans le service DNS du cluster. Envoy découvre les adresses IP du pod à partir de cette entrée DNS et répartit la charge entre elles en fonction de la règle configurée dans Envoy.
Le schéma suivant illustre les objets Kubernetes impliqués dans ce tutoriel :
Coûts
Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :
Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.
Une fois que vous avez terminé les tâches décrites dans ce document, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.
Avant de commencer
-
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.
Préparer l'environnement
Dans Cloud Shell, définissez le projet Google Cloud que vous souhaitez utiliser pour ce tutoriel :
gcloud config set project PROJECT_ID
Remplacez
PROJECT_ID
par l'ID de votre projet Google Cloud.Activez les API Artifact Registry et GKE :
gcloud services enable artifactregistry.googleapis.com \ container.googleapis.com
Créer le cluster GKE
Dans Cloud Shell, créez un cluster GKE pour exécuter vos services 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
Ce tutoriel utilise la zone
us-central1-f
. Vous pouvez définir une zone ou une région différente.Vérifiez que le contexte
kubectl
a été configuré en répertoriant les nœuds de votre cluster :kubectl get nodes --output name
Le résultat ressemble à ceci :
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
Créer le dépôt Artifact Registry
Dans Cloud Shell, créez un dépôt pour stocker les images de conteneurs :
gcloud artifacts repositories create envoy-grpc-tutorial-images \ --repository-format docker \ --location us-central1
Créez le dépôt dans la même région que le cluster GKE afin d'optimiser la latence et la bande passante réseau lorsque les nœuds extraient des images de conteneurs.
Attribuez le rôle Lecteur Artifact Registry au dépôt au compte de service Google utilisé par les VM de nœuds du 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
Ajoutez une entrée d'assistant d'identification pour le nom d'hôte du dépôt au fichier de configuration Docker dans votre répertoire d'accueil Cloud Shell :
gcloud auth configure-docker us-central1-docker.pkg.dev
L'entrée de l'assistant d'identification permet aux outils d'image de conteneur exécutés dans Cloud Shell de s'authentifier auprès de l'emplacement du dépôt Artifact Registry pour extraire et stocker des images.
Déployer les services gRPC
Pour acheminer le trafic vers plusieurs services gRPC derrière un équilibreur de charge, vous devez déployer deux exemples de services gRPC : echo-grpc
et reverse-grpc
. Ces deux services exposent une méthode unaire qui prend une chaîne dans le champ de requête content
. echo-grpc
répond avec le contenu non modifié, alors que reverse-grpc
renvoie la chaîne de contenu inversée.
Dans Cloud Shell, clonez le dépôt contenant les services gRPC, puis basculez vers le répertoire du dépôt :
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/networking/grpc-gke-nlb-tutorial/
Créez un certificat TLS autosigné et une clé privée :
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'
Créez un secret Kubernetes nommé
envoy-certs
contenant le certificat TLS autosigné et la clé privée :kubectl create secret tls envoy-certs \ --key privkey.pem --cert cert.pem \ --dry-run=client --output yaml | kubectl apply --filename -
Envoy utilise ce certificat TLS et cette clé privée lorsqu'il met fin aux connexions TLS.
Créez les images de conteneur pour les exemples d'applications
echo-grpc
etreverse-grpc
, transférez les images vers Artifact Registry, puis déployez les applications sur le cluster GKE à l'aide de Skaffold :skaffold run \ --default-repo=us-central1-docker.pkg.dev/PROJECT_ID/envoy-grpc-tutorial-images \ --module=echo-grpc,reverse-grpc \ --skip-tests
Skaffold est un outil Open Source de Google qui automatise les workflows pour le développement, la compilation, le transfert et le déploiement d'applications en tant que conteneurs.
Déployez Envoy sur le cluster GKE à l'aide de Skaffold :
skaffold run \ --digest-source=none \ --module=envoy \ --skip-tests
Vérifiez que deux pods sont prêts pour chaque déploiement :
kubectl get deployments
La sortie doit ressembler à ce qui suit. La valeur de
READY
doit être2/2
pour tous les déploiements.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
Vérifiez que
echo-grpc
,envoy
etreverse-grpc
correspondent à des services Kubernetes :kubectl get services --selector skaffold.dev/run-id
La sortie doit ressembler à ce qui suit.
echo-grpc
etreverse-grpc
doivent tous deux être définis comme suit :TYPE=ClusterIP
etCLUSTER-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
Tester les services gRPC
Vous allez utiliser l'outil de ligne de commande grpcurl
pour tester les services.
Dans Cloud Shell, installez
grpcurl
:go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
Obtenez l'adresse IP externe du service Kubernetes
envoy
et stockez-la dans une variable d'environnement :EXTERNAL_IP=$(kubectl get service envoy \ --output=jsonpath='{.status.loadBalancer.ingress[0].ip}')
Envoyez une requête à l'exemple d'application
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
Le résultat ressemble à ceci :
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'en-tête de réponse
hostname
indique le nom du podecho-grpc
ayant traité la requête. Si vous répétez cette commande plusieurs fois, vous devriez voir deux valeurs différentes pour l'en-tête de réponsehostname
, correspondant aux noms des podsecho-grpc
.Vérifiez que vous obtenez le même comportement avec le service gRPC Reverse :
grpcurl -v -d '{"content": "reverse"}' \ -proto reverse-grpc/api/reverse.proto \ -authority grpc.example.com -cacert cert.pem \ $EXTERNAL_IP:443 api.Reverse/Reverse
Le résultat ressemble à ceci :
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
Configuration d'Envoy
Pour mieux comprendre la configuration d'Envoy, vous pouvez consulter le fichier de configuration envoy/k8s/envoy.yaml
dans le dépôt Git.
La section route_config
spécifie la manière dont les requêtes entrantes sont acheminées vers les exemples d'application echo-grpc
et reverse-grpc
.
Les exemples d'applications sont définis en tant que clusters Envoy.
Les champs type: STRICT_DNS
et lb_policy: ROUND_ROBIN
de la définition de cluster spécifient qu'Envoy effectue des recherches DNS du nom d'hôte spécifié dans le champ address
et équilibre la charge sur les adresses IP dans la réponse à la résolution DNS La réponse contient plusieurs adresses IP, car les objets de service Kubernetes qui définissent les exemples d'applications spécifient des services sans interface graphique.
Le champ http2_protocol_options
indique qu'Envoy utilise le protocole HTTP/2 à destination des exemples d'applications.
Le champ grpc_health_check
de la section health_checks
indique qu'Envoy utilise le protocole de vérification d'état gRPC pour déterminer l'état des exemples d'applications.
Résoudre les problèmes
Si vous rencontrez des problèmes avec ce tutoriel, nous vous recommandons de consulter les documents ci-dessous :
- Dépannage de GKE
- Résoudre les problèmes liés aux clusters Kubernetes
- Résoudre les problèmes liés aux applications déployées sur Kubernetes
Vous pouvez également explorer l'interface d'administration Envoy pour diagnostiquer les problèmes liés à la configuration Envoy.
Pour ouvrir l'interface d'administration, exécutez la commande suivante pour configurer le transfert de port de Cloud Shell vers le port
admin
de l'un des pods Envoy :kubectl port-forward \ $(kubectl get pods -o name | grep envoy | head -n1) 8080:8090
Attendez que le résultat ci-dessous s'affiche dans la console :
Forwarding from 127.0.0.1:8080 -> 8090
Cliquez sur le bouton Aperçu Web dans Cloud Shell et sélectionnez Preview on port 8080 (Prévisualiser sur le port 8080). Une nouvelle fenêtre de navigateur s'ouvre et affiche l'interface d'administration.
Lorsque vous avez terminé, revenez à Cloud Shell et appuyez sur
Control+C
pour mettre fin au transfert de port.
Autres moyens d'acheminer le trafic gRPC
Vous pouvez modifier cette solution de différentes manières pour l'adapter à votre environnement.
Autres équilibreurs de charge de couche d'application
Certaines des fonctionnalités de couche d'application fournies par Envoy peuvent également être fournies par d'autres solutions d'équilibrage de charge :
Vous pouvez utiliser un équilibreur de charge d'application externe global ou régional au lieu d'un équilibreur de charge réseau passthrough externe et d'Envoy autogéré. L'utilisation d'un équilibreur de charge d'application externe offre plusieurs avantages par rapport à un équilibreur de charge réseau passthrough externe, tels que la fonctionnalité de gestion avancée du trafic, les certificats TLS gérés et l'intégration à d'autres produits Google Cloud tels que Cloud CDN, Google Cloud Armor et IAP.
Nous vous recommandons d'utiliser un équilibreur de charge d'application externe global ou régional si les fonctionnalités de gestion du trafic qu'il propose répondent à vos cas d'utilisation et si vous n'avez pas besoin d'assistance pour l'authentification basée sur un certificat client, également appelée authentification TLS mutuelle (mTLS). Pour en savoir plus, consultez les documents suivants :
Si vous utilisez Cloud Service Mesh ou Istio, vous pouvez utiliser leurs fonctionnalités pour acheminer et équilibrer le trafic gRPC. La passerelle d'entrée de Cloud Service Mesh et d'Istio est déployée en tant qu'équilibreur de charge réseau passthrough externe avec un backend Envoy, semblable à l'architecture déployée dans ce tutoriel. La principale différence est qu'Envoy est configuré via les objets de routage de trafic d'Istio.
Pour rendre les exemples de services de ce tutoriel routables dans le maillage de services Cloud Service Mesh ou Istio, vous devez supprimer la ligne
clusterIP: None
des fichiers manifestes des services Kubernetes (echo-service.yaml
etreverse-service.yaml
). Cela signifie que vous devez utiliser les fonctionnalités de détection de services et d'équilibrage de charge d'Anthos Service Mesh ou d'Istio au lieu des fonctionnalités similaires dans Envoy.Si vous utilisez déjà Cloud Service Mesh ou Istio, nous vous recommandons d'utiliser la passerelle d'entrée pour accéder à vos services gRPC.
Vous pouvez utiliser NGINX à la place d'Envoy, soit en tant que déploiement, soit via le contrôleur d'entrée NGINX pour Kubernetes. Envoy est utilisé dans ce tutoriel, car il offre des fonctionnalités gRPC plus avancées, telles que la compatibilité avec le protocole de vérification de l'état gRPC.
Connectivité du réseau VPC interne
Si vous souhaitez exposer les services en dehors de votre cluster GKE mais exclusivement à l'intérieur de votre réseau VPC, vous pouvez utiliser un équilibreur de charge réseau passthrough interne ou un équilibreur de charge d'application interne.
Pour utiliser un équilibreur de charge réseau passthrough interne à la place d'un équilibreur de charge réseau passthrough externe, ajoutez l'annotation cloud.google.com/load-balancer-type: "Internal"
au fichier manifeste envoy-service.yaml
.
Pour utiliser un équilibreur de charge d'application interne, consultez la documentation sur la Configuration d'Ingress pour les équilibreurs de charge d'application internes.
Effectuer un nettoyage
Une fois le tutoriel terminé, vous pouvez procéder au nettoyage des ressources que vous avez créées afin qu'elles ne soient plus comptabilisées dans votre quota et qu'elles ne vous soient plus facturées. Dans les sections suivantes, nous allons voir comment supprimer ou désactiver ces ressources.
Supprimer le projet
- 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.
Supprimer les ressources
Si vous souhaitez conserver le projet Google Cloud que vous avez utilisé dans ce tutoriel, supprimez les différentes ressources :
Dans Cloud Shell, supprimez le clone du dépôt Git local :
cd ; rm -rf kubernetes-engine-samples/networking/grpc-gke-nlb-tutorial/
Supprimez le cluster GKE :
gcloud container clusters delete envoy-grpc-tutorial \ --zone us-central1-f --async --quiet
Supprimer le dépôt dans Artifact Registry:
gcloud artifacts repositories delete envoy-grpc-tutorial-images \ --location us-central1 --async --quiet
Étapes suivantes
- Découvrez la mise en réseau GKE.
- Parcourez les exemples indiquant comment exposer des services gRPC aux clients de votre cluster Kubernetes.
Explorez les options d'équilibrage de charge gRPC.
Découvrez des architectures de référence, des schémas et des bonnes pratiques concernant Google Cloud. Consultez notre Cloud Architecture Center.