Déployer une application Web en conteneur

Ce tutoriel explique comment empaqueter une application Web dans une image de conteneur Docker et exécuter cette image sur un cluster Google Kubernetes Engine (GKE). Vous déployez ensuite l'application Web sous la forme d'un ensemble d'instances dupliquées à équilibrage de charge pouvant s'adapter aux besoins de vos utilisateurs.

Objectifs

  • Empaqueter un exemple d'application Web dans une image Docker
  • Importer l'image Docker dans Container Registry
  • Créer un cluster GKE
  • Déployer l'exemple d'application sur le cluster
  • Gérer l'autoscaling pour le déploiement
  • Exposer l'exemple d'application sur Internet
  • Déployer une nouvelle version de l'exemple d'application

Avant de commencer

Pour activer l'API Kubernetes Engine, procédez comme suit :
  1. Accédez à la page Kubernetes Engine dans Google Cloud Console.
  2. Créez ou sélectionnez un projet.
  3. Patientez le temps de l'activation de l'API et des services associés. Cette opération peut prendre plusieurs minutes.
  4. Assurez-vous que la facturation est activée pour votre projet Cloud. Découvrez comment vérifier que la facturation est activée pour votre projet.

Option A : Utiliser Cloud Shell

Vous pouvez suivre ce tutoriel avec Cloud Shell, où sont préinstallés les outils de ligne de commande gcloud, docker et kubectl utilisés ici. Si vous utilisez Cloud Shell, vous n'avez pas besoin d'installer ces outils de ligne de commande sur votre poste de travail.

Pour utiliser Cloud Shell, procédez comme suit :

  1. Accédez à Google Cloud Console.
  2. Cliquez sur le bouton Activer Cloud Shell Bouton d'activation de Cloud Shell en haut de la fenêtre de Cloud Console.

    Une session Cloud Shell s'ouvre dans un nouveau cadre en bas de Cloud Console et affiche une invite de ligne de commande.

    Session Cloud Shell

Option B : Utiliser des outils de ligne de commande localement

Si vous préférez suivre ce tutoriel sur votre poste de travail, suivez les étapes ci-dessous pour installer les outils nécessaires.

  1. Installez SDK Cloud qui inclut l'outil de ligne de commande gcloud.

  2. À l'aide de l'outil de ligne de commande gcloud, installez l'outil de ligne de commande de Kubernetes. kubectl permet de communiquer avec Kubernetes, qui est le système d'orchestration de clusters pour les clusters GKE :

    gcloud components install kubectl
  3. Installez Docker Community Edition (CE) sur votre poste de travail. Vous allez l'utiliser pour créer une image de conteneur pour l'application.

  4. Installez l'outil de contrôle de source Git pour récupérer l'exemple d'application depuis GitHub.

Créer l'image du conteneur

Dans ce tutoriel, vous allez déployer un exemple d'application Web appelé hello-app. Il s'agit d'un serveur Web écrit en Go qui répond à toutes les requêtes avec le message Hello, World! sur le port 8080.

GKE accepte les images Docker comme format de déploiement de l'application. Avant de déployer hello-app sur GKE, vous devez empaqueter le code source de hello-app en tant qu'image Docker.

Pour créer une image Docker, vous avez besoin du code source et d'un fichier Dockerfile. Un fichier Dockerfile contient des instructions sur la création de l'image.

  1. Téléchargez le code source et le fichier Dockerfile de hello-app en exécutant les commandes suivantes :

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/hello-app
    
  2. Définissez la variable d'environnement PROJECT_ID sur votre ID de projet Google Cloud (project-id). La variable PROJECT_ID associe l'image de conteneur au registre de conteneurs Container Registry de votre projet.

    export PROJECT_ID=project-id
    
  3. Vérifiez que la valeur de la variable d'environnement PROJECT_ID est correcte :

    echo $PROJECT_ID
    
  4. Créez l'image Docker de hello-app et ajoutez un tag comme suit :

    docker build -t gcr.io/${PROJECT_ID}/hello-app:v1 .
    

    Cette commande indique à Docker qu'il doit créer l'image à l'aide du fichier Dockerfile dans le répertoire actuel et lui attribuer un nom tel que gcr.io/my-project/hello-app:v1. Le préfixe gcr.io fait référence à Container Registry, où l'image est hébergée. Cette commande n'importe pas l'image.

  5. Exécutez la commande docker images pour vérifier que la compilation a réussi :

    docker images
    
    Sortie :
    REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
    gcr.io/my-project/hello-app    v1                  25cfadb1bf28        10 seconds ago      54 MB
    

Exécuter le conteneur localement (facultatif)

  1. Testez votre image de conteneur à l'aide de votre moteur Docker local :

    docker run --rm -p 8080:8080 gcr.io/${PROJECT_ID}/hello-app:v1
    
  2. Si vous utilisez Cloud Shell, cliquez sur le bouton Aperçu sur le Web Bouton "Aperçu sur le Web", puis sélectionnez le numéro de port 8080. GKE ouvre l'URL d'aperçu sur son service proxy dans une nouvelle fenêtre de navigateur.

  3. Sinon, ouvrez une nouvelle fenêtre de terminal (ou un onglet Cloud Shell), puis exécutez la commande suivante pour vérifier que le conteneur fonctionne et répond aux requêtes par "Hello, World!" :

    curl http://localhost:8080

    Une fois que vous avez obtenu une réponse positive, vous pouvez fermer le conteneur en appuyant sur Ctrl+C dans l'onglet où la commande docker run est exécutée.

Transférer l'image Docker dans Container Registry

Vous devez importer l'image de conteneur dans un registre afin que votre cluster GKE puisse la télécharger et l'exécuter. Dans Google Cloud, Container Registry est disponible par défaut.

  1. Configurez l'outil de ligne de commande Docker pour qu'il s'authentifie auprès de Container Registry :

    gcloud auth configure-docker
    
  2. Transférez l'image Docker que vous venez de créer dans Container Registry :

    docker push gcr.io/${PROJECT_ID}/hello-app:v1
    

Créer un cluster GKE

Maintenant que l'image Docker est stockée dans Container Registry, créez un cluster GKE pour exécuter hello-app. Un cluster GKE est constitué d'un pool d'instances de VM Compute Engine exécutant Kubernetes, le système d'orchestration de clusters Open Source exploité par GKE.

Cloud Shell

  1. Définissez vos options d'ID de projet et de zone Compute Engine pour l'outil gcloud :

    gcloud config set project $PROJECT_ID
    gcloud config set compute/zone compute-zone

    Choisissez la zone la plus proche de vous.

  2. Créez un cluster nommé hello-cluster :

    gcloud container clusters create hello-cluster
    

    La création et la vérification de l'état de votre cluster GKE peuvent prendre quelques minutes.

  3. Une fois cette opération terminée, exécutez la commande suivante pour afficher les trois instances de VM de nœud de calcul du cluster :

    gcloud compute instances list
    
    Sortie :
    NAME                                           ZONE        MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
    gke-hello-cluster-default-pool-d8b498d3-0d6r  us-east1-b   e2-medium                   10.142.0.4   35.237.4.149   RUNNING
    gke-hello-cluster-default-pool-d8b498d3-k29m  us-east1-b   e2-medium                   10.142.0.3   34.75.248.193  RUNNING
    gke-hello-cluster-default-pool-d8b498d3-vcrj  us-east1-b   e2-medium                   10.142.0.2   35.196.51.235  RUNNING
    

Console

  1. Accédez au menu Google Kubernetes Engine de Cloud Console.

    Accéder au menu Google Kubernetes Engine

  2. Cliquez sur  Créer.

  3. Dans la section Paramètres de base du cluster, saisissez le nom hello-cluster.

  4. Définissez la zone en choisissant une zone Compute Engine dans le menu déroulant.

  5. Cliquez sur Create (Créer). Cette opération crée un cluster GKE avec 3 nœuds.

  6. Attendez que le cluster soit créé. Lorsque le cluster est prêt, une coche verte apparaît à côté de son nom.

Déployer l'exemple d'application sur GKE

Vous êtes maintenant prêt à déployer l'image Docker que vous avez créée sur votre cluster GKE.

Kubernetes représente les applications sous forme de pods, qui sont des unités évolutives contenant un ou plusieurs conteneurs. Le pod est la plus petite unité déployable dans Kubernetes. Généralement, vous déployez les pods sous la forme d'un ensemble d'instances dupliquées pouvant être mises à l'échelle et réparties sur votre cluster. Pour déployer un ensemble d'instances dupliquées, vous pouvez utiliser un déploiement Kubernetes.

Dans cette section, vous allez créer un déploiement Kubernetes pour exécuter hello-app sur votre cluster. Ce déploiement possède des instances dupliquées (pods). Un pod de déploiement ne contient qu'un seul conteneur : l'image Docker hello-app. Vous allez également créer une ressource HorizontalPodAutoscaler qui adapte le nombre de pods et le fait passer de 3 à un nombre compris entre 1 et 5, en fonction de la charge du processeur.

Cloud Shell

  1. Créez un déploiement Kubernetes pour votre image Docker hello-app.

    kubectl create deployment hello-app --image=gcr.io/${PROJECT_ID}/hello-app:v1
    
  2. Définissez le nombre de référence d'instances dupliquées de déploiement sur 3.

    kubectl scale deployment hello-app --replicas=3
    
  3. Créez une ressource HorizontalPodAutoscaler pour votre déploiement.

    kubectl autoscale deployment hello-app --cpu-percent=80 --min=1 --max=5
    
  4. Pour afficher les pods créés, exécutez la commande suivante :

    kubectl get pods
    
    Sortie :
    NAME                         READY   STATUS    RESTARTS   AGE
    hello-app-784d7569bc-hgmpx   1/1     Running   0          10s
    hello-app-784d7569bc-jfkz5   1/1     Running   0          10s
    hello-app-784d7569bc-mnrrl   1/1     Running   0          15s
    

Console

  1. Accédez au menu "Charges de travail" de Google Kubernetes Engine dans Cloud Console.

    Accéder au menu Charges de travail

  2. Dans le menu "Charges de travail", cliquez sur Déployer.

  3. Dans la fenêtre "Créer un déploiement" qui s'affiche, cliquez sur Image de conteneur existante.

  4. Dans le menu déroulant, cliquez sur l'image hello-app que vous avez transférée dans Container Registry.

  5. Cliquez sur Afficher YAML. Un fichier de configuration YAML s'ouvre. Il représente les deux ressources de l'API Kubernetes sur le point d'être déployées dans votre cluster : un déploiement et sa ressource HorizontalPodAutoscaler.

  6. Cliquez sur Déployer.

  7. Attendez que les pods de déploiement soient prêts. Les engrenages bleus indiquent que votre cluster GKE est en train de déployer les trois pods hello-app, et des coches vertes s'affichent une fois que les pods ont été déployés avec succès.

  8. Attendez que les pods soient prêts, puis accédez à Kubernetes Engine et sélectionnez "Charges de travail". Cliquez sur hello-app et faites défiler la page jusqu'à la section Pods gérés pour afficher trois pods hello-app.

Exposer l'exemple d'application sur Internet

Bien que des adresses IP individuelles soient attribuées aux pods, ces adresses IP ne sont accessibles qu'à partir de votre cluster. En outre, les pods GKE sont conçus pour être éphémères, et démarrer ou s'arrêter en fonction des besoins du scaling. Et lorsqu'un pod se bloque en raison d'une erreur, GKE le redéploie automatiquement en lui attribuant une nouvelle adresse IP à chaque fois.

Cela signifie que pour tout déploiement, l'ensemble d'adresses IP correspondant à l'ensemble actif de pods est dynamique. Nous avons besoin d'un moyen de 1) regrouper les pods sous un nom d'hôte statique et 2) d'exposer un groupe de pods à l'extérieur du cluster, sur Internet.

Les services Kubernetes permettent de résoudre ces deux problèmes. Les services regroupent les pods sous une seule adresse IP statique, accessible depuis n'importe quel pod du cluster. GKE attribue également un nom d'hôte DNS à cette adresse IP statique, par exemple : hello-app.default.svc.cluster.local.

Le type de service par défaut dans GKE est appelé ClusterIP, où le service obtient une adresse IP accessible uniquement à partir du cluster. Pour exposer un service Kubernetes en dehors du cluster, créez un service de type LoadBalancer. Ce type de service génère une adresse IP d'équilibreur de charge externe pour un ensemble de pods, accessible via Internet.

Dans cette section, vous exposez le déploiement hello-app sur Internet à l'aide d'un service de type LoadBalancer.

Cloud Shell

  1. Utilisez la commande kubectl expose pour générer un service Kubernetes pour le déploiement hello-app.

    kubectl expose deployment hello-app --name=hello-app-service --type=LoadBalancer --port 80 --target-port 8080
    

    Ici, l'option --port spécifie le numéro de port configuré sur l'équilibreur de charge, et l'option --target-port spécifie le numéro de port sur lequel le conteneur hello-app écoute.

  2. Exécutez la commande suivante pour obtenir les détails du service pour hello-app-service.

    kubectl get service
    
    Sortie :
    NAME                 CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
    hello-app-service    10.3.251.122    203.0.113.0     80:30877/TCP     10s
    
  3. Copiez l'adresse EXTERNAL_IP dans le presse-papiers (par exemple, 203.0.113.0).

Console

  1. Accédez au menu "Charges de travail" de Google Kubernetes Engine dans Cloud Console.

    Accéder au menu Charges de travail

  2. Cliquez sur hello-app.

  3. Sur la page "Informations sur le déploiement", cliquez sur Exposer.

  4. Dans le menu "Exposer un déploiement", définissez le port cible sur 8080. Il s'agit du port sur lequel le conteneur hello-app écoute.

  5. Cliquez sur Exposer pour générer un service Kubernetes pour hello-app, appelé hello-app-service.

  6. Attendez que l'équilibreur de charge externe soit créé. Un engrenage bleu en rotation apparaît dans Google Cloud Console. Lorsque l'équilibreur de charge est prêt, vous êtes redirigé vers la page "Détails du service" pour hello-app-service.

  7. Faites défiler la page jusqu'au champ Points de terminaison externes, puis copiez l'adresse dans le presse-papiers.

Maintenant que les pods hello-app sont exposés sur Internet via un service Kubernetes, vous pouvez ouvrir un nouvel onglet de navigateur et accéder à l'adresse IP du service que vous avez copiée dans le presse-papiers. Un message Hello, World! s'affiche, accompagné d'un champ Hostname. Le nom d'hôte (Hostname) correspond à l'un des trois pods hello-app qui diffusent votre requête HTTP dans votre navigateur.

Déployer une nouvelle version de l'exemple d'application

Dans cette section, vous allez mettre à niveau hello-app vers une nouvelle version en créant et en déployant une nouvelle image Docker sur votre cluster GKE.

La fonctionnalité de mise à jour progressive de GKE vous permet de mettre à jour vos déploiements sans temps d'arrêt. Lors d'une mise à jour progressive, votre cluster GKE remplace progressivement les pods hello-app existants par des pods contenant l'image Docker pour la nouvelle version. Pendant la mise à jour, votre service d'équilibrage de charge n'achemine le trafic que vers les pods disponibles.

  1. Revenez dans Cloud Shell, où vous avez cloné le code source et le fichier Dockerfile de hello-app. Créez une nouvelle version du code source de hello-app en mettant à jour main.go de manière à signaler une nouvelle version, 2.0.0.

  2. Créez une nouvelle image Docker pour hello-app et ajoutez-y un tag.

    docker build -t gcr.io/${PROJECT_ID}/hello-app:v2 .
    
  3. Stocker l'image dans Container Registry

    docker push gcr.io/${PROJECT_ID}/hello-app:v2
    

Vous êtes maintenant prêt à mettre à jour le déploiement Kubernetes de hello-app pour utiliser une nouvelle image Docker.

Cloud Shell

  1. Appliquez une mise à jour progressive au déploiement existant avec une mise à jour d'image :

    kubectl set image deployment/hello-app hello-app=gcr.io/${PROJECT_ID}/hello-app:v2
    
  2. Observez les pods en cours d'exécution utilisant l'image v1 s'arrêter, et les nouveaux pods utilisant l'image v2 démarrer.

    watch kubectl get pods
    
    Sortie :
    NAME                        READY   STATUS    RESTARTS   AGE
    hello-app-89dc45f48-5bzqp   1/1     Running   0          2m42s
    hello-app-89dc45f48-scm66   1/1     Running   0          2m40s
    
  3. Dans un autre onglet, accédez de nouveau à l'adresse IP externe hello-app-service. La Version doit maintenant être définie sur 2.0.0..

Console

  1. Accédez au menu "Charges de travail" de Google Kubernetes Engine dans Cloud Console.

    Accéder au menu Charges de travail

  2. Cliquez sur hello-app.

  3. Sous Actions, cliquez sur Mettre à jour progressivement.

  4. Dans la fenêtre qui s'affiche, définissez le champ Image sur gcr.io/[YOUR_PROJECT_ID]/hello-app:v2.

  5. Cliquez sur Mettre à jour pour lancer la mise à jour progressive.

  6. Revenez à la vue "Déploiement" pour hello-app, puis faites défiler la page jusqu'à Révisions actives. Vous devriez maintenant voir deux révisions, 1 et 2. La révision 1 correspond au déploiement initial que vous avez créé précédemment. La révision 2 correspond à la mise à jour progressive que vous venez de démarrer.

  7. Après quelques instants, actualisez la page. Sous Pods gérés, toutes les instances dupliquées de hello-app correspondent désormais à la révision 2.

  8. Dans un autre onglet, accédez de nouveau à l'adresse IP externe hello-app-service. La Version doit maintenant être définie sur 2.0.0..

Nettoyer

Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et les ressources individuelles.

  1. Supprimez le service : cette étape annule l'allocation de l'équilibreur de charge Cloud créé pour le service :

    kubectl delete service hello-app-service
  2. Supprimez le cluster : cette étape supprime les ressources qui constituent le cluster, telles que les instances de calcul, les disques et les ressources réseau :

    gcloud container clusters delete hello-cluster
  3. Supprimer vos images de conteneurs : cette étape supprime les images Docker que vous avez transférées vers Container Registry.

     gcloud container images delete gcr.io/${PROJECT_ID}/hello-app:v1  --force-delete-tags --quiet
     gcloud container images delete gcr.io/${PROJECT_ID}/hello-app:v2  --force-delete-tags --quiet
    

Étape suivante