Cloud Service Mesh est un outil puissant de gestion et de surveillance des applications distribuées. Pour tirer le meilleur parti de Cloud Service Mesh, il est utile de comprendre ses abstractions sous-jacentes, y compris les conteneurs et Kubernetes. Ce tutoriel explique comment préparer une application pour Cloud Service Mesh du code source à un conteneur s'exécutant sur GKE, jusqu'au point juste avant d'installer Cloud Service Mesh.
Si vous connaissez déjà les concepts de Kubernetes et du maillage de services, vous pouvez ignorer ce tutoriel et passer directement au guide d'installation de Cloud Service Mesh.
Télécharger l'exemple de code
Téléchargez le code source
helloserver:git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samplesAccédez au répertoire de l'exemple de code :
cd anthos-service-mesh-samples/docs/helloserver
Explorer l'application multiservice
L'exemple d'application est écrit dans Python et comporte deux composants qui communiquent à l'aide de REST :
server: un serveur simple avec un point de terminaisonGET,/, qui affiche "hello world" dans la console.loadgen: script qui envoie le trafic versserver, avec un nombre configurable de requêtes par seconde (RPS).
Exécuter l'application à partir de la source
Pour vous familiariser avec l'exemple d'application, exécutez-le dans Cloud Shell.
À partir du répertoire
sample-apps/helloserver, exécutez la commandeserver:python3 server/server.pyAu démarrage,
serveraffiche les éléments suivants :INFO:root:Starting server...
Ouvrez une autre fenêtre de terminal pour pouvoir envoyer des requêtes vers
server. Cliquez sur pour ouvrir une autre session.Envoyez une requête vers
server:curl http://localhost:8080Le
serverrépond :Hello World!
Dans le répertoire dans lequel vous avez téléchargé l'exemple de code, accédez au répertoire qui contient le fichier
loadgen:cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/helloserver/loadgen
Créez les variables d'environnement suivantes :
export SERVER_ADDR=http://localhost:8080 export REQUESTS_PER_SECOND=5Lancez
virtualenv:virtualenv --python python3 envActivez l'environnement virtuel :
source env/bin/activateInstallez les éléments requis pour
loadgen:pip3 install -r requirements.txtExécutez la commande
loadgen:python3 loadgen.pyAu démarrage,
loadgengénère un message semblable à celui-ci :Starting loadgen: 2019-05-20 10:44:12.448415 5 request(s) complete to http://localhost:8080
Dans l'autre fenêtre de terminal, le
serverécrit des messages dans la console, comme suit :127.0.0.1 - - [21/Jun/2019 14:22:01] "GET / HTTP/1.1" 200 - INFO:root:GET request, Path: / Headers: Host: localhost:8080 User-Agent: python-requests/2.22.0 Accept-Encoding: gzip, deflate Accept: */*
Du point de vue de la mise en réseau, l'ensemble de l'application s'exécute désormais sur le même hôte. De ce fait, vous pouvez utiliser
localhostpour envoyer des requêtes versserver.Pour arrêter
loadgenetserver, saisissezCtrl-cdans chaque fenêtre de terminal.Dans la fenêtre de terminal
loadgen, désactivez l'environnement virtuel :deactivate
Conteneuriser l'application
Pour exécuter l'application sur GKE, vous devez empaqueter l'exemple d'application (server et loadgen) dans des conteneurs. Un conteneur permet de regrouper une application de manière à l'isoler de l'environnement sous-jacent.
Pour conteneuriser l'application, vous avez besoin d'un fichier Dockerfile. Dockerfile est un fichier texte qui définit les commandes nécessaires pour assembler le code source de l'application et ses dépendances dans un image Docker). Après avoir créé l'image, vous l'importez vers un registre de conteneurs, tel que Docker Hub ou Container Registry.
L'exemple est fourni avec Dockerfile pour server et loadgen avec toutes les commandes requises pour créer les images. Voici le fichier Dockerfile pour server :
- La commande
FROM python:3-slim as basedemande à Docker d'utiliser la dernière image Python 3 comme image de base. - La commande
COPY . .copie les fichiers sources dans le répertoire de travail actuel (dans ce cas, simplementserver.py) dans le système de fichiers du conteneur. - Le fichier
ENTRYPOINTdéfinit la commande utilisée pour exécuter le conteneur. Dans ce cas, la commande est presque identique à celle que vous avez utilisée pour exécuterserver.pyà partir du code source. - La commande
EXPOSEindique queserverécoute sur le port8080. Cette commande n'expose aucun port, mais sert de documentation pour ouvrir le port8080lorsque vous exécutez le conteneur.
Préparation pour la conteneurisation de l'application
Définissez les variables d'environnement suivantes. Remplacez
PROJECT_IDpar l'ID de votre projetGoogle Cloud .export PROJECT_ID="PROJECT_ID"
export GCR_REPO="asm-ready"
Vous utilisez les valeurs
PROJECT_IDetGCR_REPOpour baliser l'image Docker lors de la création, puis la transférer vers votre Container Registry privé.Définissez le projet Google Cloud par défaut pour Google Cloud CLI.
gcloud config set project $PROJECT_ID
Définissez la zone par défaut pour Google Cloud CLI.
gcloud config set compute/zone us-central1-bAssurez-vous que le service Container Registry est activé dans votre projetGoogle Cloud .
gcloud services enable containerregistry.googleapis.com
Conteneurisation de server
Accédez au répertoire dans lequel se trouve l'exemple
server:cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/helloserver/server/
Créez l'image à l'aide de
Dockerfileet des variables d'environnement que vous avez définies précédemment :docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1 .L'option
-treprésente le tag Docker. Il s'agit du nom de l'image que vous utilisez lorsque vous déployez le conteneur.Stockez l'image dans Container Registry :
docker push gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1
Conteneurisation de loadgen
Accédez au répertoire où se trouve l'exemple
loadgen:cd ../loadgenCréez l'image comme suit :
docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1 .Stockez l'image dans Container Registry :
docker push gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1
Répertoriage des images
Obtenez la liste des images du dépôt pour confirmer que les images ont été envoyées :
gcloud container images list --repository gcr.io/$PROJECT_ID/asm-ready
La commande répond avec les noms d'image que vous venez de transférer :
NAME gcr.io/PROJECT_ID/asm-ready/helloserver gcr.io/PROJECT_ID/asm-ready/loadgen
Créer un cluster GKE
Vous pouvez exécuter ces conteneurs sur la VM Cloud Shell à l'aide de la commande docker run. Cependant, en production, vous devez orchestrer les conteneurs de manière plus unifiée. Par exemple, vous avez besoin d'un système qui s'assure que les conteneurs sont toujours en cours d'exécution, et vous avez besoin d'un moyen pour effectuer un scaling à la hausse et démarrer les instances supplémentaires d'un conteneur pour gérer l'augmentation du trafic.
Vous pouvez utiliser GKE pour exécuter des applications en conteneur. GKE est une plate-forme d'orchestration de conteneurs qui connecte les VM pour former un cluster. Chaque VM est appelée nœud. Les clusters GKE sont basés sur le système de gestion de clusters Open Source Kubernetes. Les mécanismes de Kubernetes vous permettent d'interagir avec votre cluster.
Pour créer un cluster GKE, procédez comme suit :
Créez le cluster :
gcloud container clusters create asm-ready \ --cluster-version latest \ --machine-type=n1-standard-4 \ --num-nodes 4
La commande
gcloudcrée un cluster dans le projetGoogle Cloud et la zone que vous avez définis précédemment. Pour exécuter Cloud Service Mesh, nous vous recommandons d'utiliser au moins quatre nœuds et le type de machine n1-standard-4.La commande permettant la création d'un cluster prend quelques minutes. Lorsque le cluster est prêt, la commande affiche un message semblable à celui-ci :
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS asm-ready us-central1-b 1.13.5-gke.10 203.0.113.1 n1-standard-2 1.13.5-gke.10 4 RUNNING
Fournissez les identifiants à l'outil de ligne de commande
kubectlafin de pouvoir l'utiliser pour gérer le cluster :gcloud container clusters get-credentials asm-readyVous pouvez maintenant utiliser
kubectlpour communiquer avec Kubernetes. Par exemple, vous pouvez exécuter la commande suivante pour obtenir l'état des nœuds :kubectl get nodesLa commande répond avec une liste des nœuds, semblable à la suivante :
NAME STATUS ROLES AGE VERSION gke-asm-ready-default-pool-dbeb23dc-1vg0 Ready <none> 99s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-36z5 Ready <none> 100s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-fj7s Ready <none> 99s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-wbjw Ready <none> 99s v1.13.6-gke.13
Comprendre les concepts clés de Kubernetes
Le schéma suivant illustre l'application s'exécutant sur GKE :
Avant de déployer les conteneurs sur GKE, vous pouvez passer en revue certains concepts clés de Kubernetes. La fin de ce tutoriel fournit des liens vous permettant d'en savoir plus sur chaque concept.
Nœuds et clusters : dans GKE, un nœud est une VM. Sur d'autres plates-formes Kubernetes, un nœud peut être une machine physique ou virtuelle. Un cluster est un ensemble de nœuds pouvant être traités ensemble, comme une seule machine, sur laquelle vous déployez une application conteneurisée.
Pods : dans Kubernetes, les conteneurs s'exécutent dans un pod. Un pod est l'unité atomique de Kubernetes. Un pod contient un ou plusieurs conteneurs. Vous déployez les conteneurs
serveretloadgenchacun dans leur propre pod. Lorsqu'un pod exécute plusieurs conteneurs (par exemple, un serveur d'applications et un serveur proxy), les conteneurs sont gérés comme une seule entité et partagent les ressources du pod.Déploiements : un déploiement est un objet Kubernetes qui représente un ensemble de pods identiques. Un déploiement exécute plusieurs instances dupliquées des pods répartis entre les nœuds d'un cluster. Un déploiement remplace automatiquement tous les pods qui échouent ou ne répondent pas.
Service Kubernetes : l'exécution du code d'application dans GKE modifie la mise en réseau entre
loadgenetserver. Lorsque vous avez exécuté les services dans une VM Cloud Shell, vous pouvez envoyer des requêtes àserverà l'aide de l'adresselocalhost:8080. Une fois le déploiement effectué sur GKE, les pods sont programmés pour s'exécuter sur les nœuds disponibles. Par défaut, vous ne pouvez pas contrôler le nœud sur lequel le pod est en cours d'exécution. Par conséquent, les pods ne disposent pas d'adresses IP stables.Pour obtenir une adresse IP pour
server, vous devez définir une abstraction de mise en réseau au-dessus des pods appelés service Kubernetes. Un service Kubernetes fournit un point de terminaison de mise en réseau stable pour un ensemble de pods. Il existe plusieurs types de services.serverutiliseLoadBalancer, qui expose une adresse IP externe afin que vous puissiez accéder àserveren dehors du cluster.Kubernetes dispose également d'un système DNS intégré qui attribue des noms DNS (par exemple,
helloserver.default.cluster.local) aux services. Cela permet aux pods du cluster d'atteindre d'autres pods du cluster avec une adresse stable. Vous ne pouvez pas utiliser ce nom DNS en dehors du cluster, par exemple depuis Cloud Shell.
Fichiers manifestes Kubernetes
Lorsque vous avez exécuté l'application à partir du code source, vous avez utilisé une commande impérative : python3 server.py
Impérative, car elle s'appuie sur l'action : "faire cela".
En revanche, Kubernetes fonctionne sur un modèle déclaratif. Cela signifie que, plutôt que de dire exactement à Kubernetes ce qu'il faut faire, vous indiquez à Kubernetes l'état souhaité. Par exemple, Kubernetes démarre et arrête les pods selon les besoins afin que l'état réel du système corresponde à l'état souhaité.
Vous spécifiez l'état souhaité dans un ensemble de fichiers manifestes ou de fichiers YAML. Un fichier YAML contient la spécification pour un ou plusieurs objets Kubernetes.
L'exemple contient un fichier YAML pour server et loadgen. Chaque fichier YAML spécifie l'état souhaité pour l'objet et le service de déploiement de Kubernetes.
Serveur
kindindique le type d'objet.metadata.namespécifie le nom du déploiement.- Le premier champ
speccontient une description de l'état souhaité. spec.replicasspécifie le nombre de pods souhaités.- La section
spec.templatedéfinit un modèle de pod. Dans la spécification pour les pods, le champimagecorrespond au nom de l'image à extraire de Container Registry.
Le service est défini comme suit :
LoadBalancer: les clients envoient des requêtes à l'adresse IP d'un équilibreur de charge réseau, qui possède une adresse IP stable et qui est accessible en dehors du cluster.targetPort: rappelez-vous que la commandeEXPOSE 8080deDockerfilen'expose pas de ports. Exposez le port8080afin d'atteindre le conteneurserveren dehors du cluster. Dans ce cas,hellosvc.default.cluster.local:80(nom abrégé :hellosvc) correspond au port8080de l'adresse IP du podhelloserver).port: numéro de port utilisé par les autres services du cluster lors de l'envoi de requêtes.
Générateur de charge
L'objet Déploiement dans loadgen.yaml est semblable à server.yaml. Une différence notable est que l'objet Déploiement contient une section appelée env. Cette section définit les variables d'environnement requises par loadgen, que vous avez définies précédemment lors de l'exécution de l'application à partir de la source.
Étant donné que loadgen n'accepte pas les requêtes entrantes, le champ type est défini sur ClusterIP. Ce type fournit une adresse IP stable que les services du cluster peuvent utiliser, mais qui n'est pas exposée aux clients externes.
Déployer les conteneurs sur GKE
Accédez au répertoire où se trouve l'exemple
server:cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/helloserver/server/
Ouvrez
server.yamldans un éditeur de texte.Remplacez le nom du champ
imagepar le nom de votre image Docker.image: gcr.io/PROJECT_ID/asm-ready/helloserver:v0.0.1
Remplacez
PROJECT_IDpar l'ID du projet Google Cloud .Enregistrez et fermez le fichier
server.yaml.Déployez le fichier YAML sur Kubernetes :
kubectl apply -f server.yamlEn cas de réussite, la commande renvoie la réponse suivante :
deployment.apps/helloserver created service/hellosvc created
Accédez au répertoire où se trouve
loadgen.cd ../loadgenOuvrez
loadgen.yamldans un éditeur de texte.Remplacez le nom du champ
imagepar le nom de votre image Docker.image: gcr.io/PROJECT_ID/asm-ready/loadgen:v0.0.1
Remplacez
PROJECT_IDpar l'ID du projet Google Cloud .Enregistrez et fermez
loadgen.yaml, puis fermez l'éditeur de texte.Déployez le fichier YAML sur Kubernetes :
kubectl apply -f loadgen.yamlEn cas de réussite, la commande renvoie la réponse suivante :
deployment.apps/loadgenerator created service/loadgensvc created
Vérifiez l'état des pods :
kubectl get podsLa commande renvoie un état semblable au suivant :
NAME READY STATUS RESTARTS AGE helloserver-69b9576d96-mwtcj 1/1 Running 0 58s loadgenerator-774dbc46fb-gpbrz 1/1 Running 0 57s
Récupérez les journaux de l'application à partir du pod
loadgen. RemplacezPOD_IDpar l'identifiant de la sortie précédente.kubectl logs loadgenerator-POD_ID
Récupérez les adresses IP externes de
hellosvc:kubectl get serviceLa réponse de la commande est semblable à la suivante :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hellosvc LoadBalancer 10.81.15.158 192.0.2.1 80:31127/TCP 33m kubernetes ClusterIP 10.81.0.1 <none> 443/TCP 93m loadgensvc ClusterIP 10.81.15.155 <none> 80/TCP 4m52s
Envoyez une requête à
hellosvc. RemplacezEXTERNAL_IPpar l'adresse IP externe de votrehellosvc.curl http://EXTERNAL_IP
Prêt pour Cloud Service Mesh
Vous avez maintenant déployé l'application sur GKE. loadgen peut utiliser le DNS Kubernetes (hellosvc:80) pour envoyer des requêtes à server, et vous pouvez envoyer des requêtes à server avec une adresse IP externe. Bien que Kubernetes vous fournisse de nombreuses fonctionnalités, certaines informations concernant les services sont manquantes :
- Comment les services interagissent-ils ? Quelle est la relation entre les services ? Comment le trafic circule-t-il entre les services ? Vous savez que
loadgenenvoie des requêtes àserver, mais imaginez que vous ne connaissez pas l'application. Vous ne pouvez pas répondre à ces questions en consultant la liste des pods en cours d'exécution sur GKE. - Statistiques : combien de temps faut-il pour que
serverréponde aux requêtes entrantes ? Combien de requêtes par seconde (RPS) sont entrantes versserver? Existe-t-il des réponses d'erreur ? - Informations de sécurité : le trafic est-il compris entre
loadgenet leserverbrutHTTPou mTLS ?
Cloud Service Mesh peut répondre à ces questions. Cloud Service Mesh est une version gérée par Google Clouddu projet Istio Open Source. Cloud Service Mesh fonctionne en plaçant un proxy side-car Envoy dans chaque pod. Le proxy Envoy intercepte tout le trafic entrant et sortant vers les conteneurs d'applications. Cela signifie que server et loadgen disposent chacune d'un proxy side-car Envoy, et tout le trafic de loadgen vers server est diffusé par les proxys Envoy. Les connexions entre ces proxys Envoy forment le maillage de services. Cette architecture de maillage de services fournit une couche de contrôle en plus de Kubernetes.
Étant donné que les proxys Envoy s'exécutent dans leurs propres conteneurs, vous pouvez installer Cloud Service Mesh sur un cluster GKE sans apporter de modifications importantes à votre code d'application. Cependant, il existe plusieurs moyens clés avec lesquels vous avez préparé l'application pour être instrumentée avec Cloud Service Mesh :
- Services pour tous les conteneurs : les déploiements
serveretloadgensont associés à un service Kubernetes. Mêmeloadgen, qui ne reçoit aucune requête entrante, dispose d'un service. - Les ports des services doivent être nommés : bien que GKE vous permette de définir des ports de service sans nom, Cloud Service Mesh vous demande de fournir un nom pour un port correspondant au protocole du port. Dans le fichier YAML, le port pour
serverest nomméhttp, carserverutilise le protocole de communicationHTTP. SiserviceutilisegRPC, vous devez nommer le portgrpc. - Les déploiements sont libellés : cela vous permet d'utiliser les fonctionnalités de gestion du trafic de Cloud Service Mesh, telles que la division du trafic entre les différentes versions du même service.
Installer Cloud Service Mesh
Consultez le guide d'installation de Cloud Service Mesh et suivez les instructions pour installer Cloud Service Mesh sur votre cluster.