Présentation des conteneurs


Si vous ne connaissez pas du tout les charges de travail conteneurisées, ce tutoriel est fait pour vous. Il vous présente les conteneurs et l'orchestration de conteneurs en vous guidant dans la configuration d'une application simple, du code source à un conteneur s'exécutant sur GKE.

Ce tutoriel ne nécessite aucune expérience préalable avec les conteneurs ni Kubernetes. Toutefois, si vous souhaitez lire une présentation de la terminologie de base de Kubernetes avant de commencer ce tutoriel, consultez Commencer à découvrir Kubernetes (ou, si vous préférez découvrir Kubernetes sous forme de bande dessinée, consultez notre bande dessinée sur Kubernetes). Vous trouverez des ressources plus détaillées dans la section Étapes suivantes à la fin du tutoriel.

Si vous connaissez déjà les conteneurs et Kubernetes, vous pouvez ignorer ce tutoriel et commencer à découvrir GKE.

Objectifs

  1. découvrir une application "Hello World" simple et multiservice ;
  2. Exécutez l'application à partir de la source.
  3. conteneuriser l'application ;
  4. créer un cluster Kubernetes ;
  5. déployer les conteneurs sur le cluster.

Avant de commencer

Pour activer l'API Kubernetes Engine, procédez comme suit :
  1. Accédez à la page Kubernetes Engine dans la console Google Cloud .
  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. Verify that billing is enabled for your Google Cloud project.

Préparer Cloud Shell

Ce tutoriel utilise Cloud Shell, qui provisionne une machine virtuelle (VM) g1-small Compute Engine exécutant un système d'exploitation Linux basé sur Debian.

L'utilisation de Cloud Shell présente les avantages suivants :

  • Un environnement de développement Python 3 (y compris virtualenv) est entièrement configuré.
  • Les outils de ligne de commande gcloud, docker, git et kubectl utilisés dans ce tutoriel sont déjà installés.
  • Vous avez le choix entre plusieurs éditeurs de texte intégrés :

    • L'éditeur Cloud Shell, auquel vous accédez en cliquant sur Ouvrir l'éditeur en haut de la fenêtre Cloud Shell.

    • Emacs, Vim ou Nano, auxquels vous accédez depuis la ligne de commande dans Cloud Shell.

  • In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    Télécharger l'exemple de code

    1. Téléchargez le code source helloserver :

      git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
      
    2. Accé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 en Python. Il comporte les composants suivants qui communiquent à l'aide de REST :

    • server : un serveur de base avec un point de terminaison GET, / , qui affiche "hello world" dans la fenêtre du terminal.
    • loadgen : script qui envoie le trafic vers server, avec un nombre configurable de requêtes par seconde (RPS).

    Exemple d'application

    Exécuter l'application à partir de la source

    Pour vous familiariser avec l'exemple d'application, exécutez-le dans Cloud Shell :

    1. À partir du répertoire sample-apps/helloserver, exécutez la commande server :

      python3 server/server.py
      

      Au démarrage, server affiche les éléments suivants :

      INFO:root:Starting server...
      
    2. Ouvrez une autre fenêtre de terminal pour pouvoir envoyer des requêtes vers server. Pour ce faire dans Cloud Shell, cliquez sur Ouvrir un nouvel onglet pour ouvrir une autre session.

    3. Dans la nouvelle fenêtre de terminal, envoyez une requête à server :

      curl http://localhost:8080
      

      Le résultat de server est le suivant :

      Hello World!
      
    4. Dans le même onglet, accédez au répertoire contenant le script loadgen :

      cd anthos-service-mesh-samples/docs/helloserver/loadgen
    5. Créez les variables d'environnement suivantes :

      export SERVER_ADDR=http://localhost:8080
      export REQUESTS_PER_SECOND=5
      
    6. Lancez virtualenv :

      virtualenv --python python3 env
      
    7. Activez l'environnement virtuel :

      source env/bin/activate
      
    8. Installez les éléments requis pour loadgen :

      pip3 install -r requirements.txt
      
    9. Exécutez l'application loadgen pour générer du trafic pour le server :

      python3 loadgen.py
      

      Au démarrage, le résultat de loadgen ressemble à ce qui suit :

      Starting loadgen: 2024-10-11 09:49:51.798028
      5 request(s) complete to http://localhost:8080
      
    10. Ouvrez maintenant la fenêtre de terminal qui exécute server. Des messages semblables aux suivants doivent s'afficher :

      127.0.0.1 - - [11/Oct/2024 09:51:28] "GET / HTTP/1.1" 200 -
      INFO:root:GET request,
      Path: /
      Headers:
      Host: localhost:8080
      User-Agent: python-requests/2.32.3
      Accept-Encoding: gzip, deflate
      Accept: */*
      Connection: keep-alive
      

      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, ce qui vous permet d'utiliser localhost pour envoyer des requêtes à server.

    11. Pour arrêter loadgen et server, appuyez sur Ctrl-c dans chaque fenêtre de terminal.

    12. 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 les deux composants de l'exemple d'application dans des conteneurs. Un conteneur est un package qui contient tous les éléments nécessaires pour que votre application s'exécute dans n'importe quel environnement. Ce tutoriel utilise Docker pour conteneuriser l'application.

    Pour conteneuriser l'application avec Docker, vous avez besoin d'un fichier Dockerfile. Un 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 une image de conteneur. Après avoir créé l'image, vous l'importez vers un registre de conteneurs, tel qu'Artifact Registry.

    Le code source de ce tutoriel inclut un Dockerfile pour server et loadgen avec toutes les commandes requises pour créer les images. Voici le fichier Dockerfile pour server :

    FROM python:3.13-slim as base
    FROM base as builder
    RUN apt-get -qq update \
        && apt-get install -y --no-install-recommends \
            g++ \
        && rm -rf /var/lib/apt/lists/*
    
    # Enable unbuffered logging
    FROM base as final
    ENV PYTHONUNBUFFERED=1
    
    RUN apt-get -qq update \
        && apt-get install -y --no-install-recommends \
            wget
    
    WORKDIR /helloserver
    
    # Grab packages from builder
    COPY --from=builder /usr/local/lib/python3.* /usr/local/lib/
    
    # Add the application
    COPY . .
    
    EXPOSE 8080
    ENTRYPOINT [ "python", "server.py" ]
    

    Dans ce fichier, vous pouvez voir les éléments suivants :

    • L'instruction FROM python:3-slim as base indique à Docker d'utiliser la dernière image Python 3 comme image de base.
    • L'instruction COPY . . copie les fichiers sources du répertoire de travail actuel (dans ce cas, server.py) dans le système de fichiers du conteneur.
    • Le fichier ENTRYPOINT définit l'instruction utilisée pour exécuter le conteneur. Dans cet exemple, l'instruction est semblable à celle que vous avez utilisée pour exécuter server.py à partir du code source.
    • L'instruction EXPOSE indique que server écoute sur le port 8080. Cette instruction n'expose aucun port, mais sert de documentation pour ouvrir le port 8080 lorsque vous exécutez le conteneur.

    Préparer l'application en conteneur

    Avant de conteneuriser l'application, vous devez configurer les outils et services que vous allez utiliser :

    1. Définissez le projet Google Cloud par défaut pour Google Cloud CLI.

      gcloud config set project PROJECT_ID
    2. Définissez la région par défaut pour Google Cloud CLI.

      gcloud config set compute/region us-central1
      

    Créer le dépôt

    Pour créer un dépôt pour les images de conteneurs Docker dans Artifact Registry :

    1. Assurez-vous que le service Artifact Registry est activé dans votre projetGoogle Cloud .

      gcloud services enable artifactregistry.googleapis.com
      
      
    2. Créez le dépôt Artifact Registry :

      gcloud artifacts repositories create container-intro --repository-format=docker \
          --location=us-central1 \
          --description="My new Docker repository"
      
    3. Configurez l'authentification de Docker à Artifact Registry à l'aide de Google Cloud CLI :

      gcloud auth configure-docker us-central1-docker.pkg.dev
      

    Conteneurisation de server

    Il est maintenant temps de conteneuriser votre application. Commencez par conteneuriser le server "hello world" et transférez l'image vers Artifact Registry :

    1. Accédez au répertoire où se trouve l'exemple server :

      cd ~/anthos-service-mesh-samples/docs/helloserver/server/
    2. Créez l'image à l'aide de Dockerfile :

      docker build -t us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1 .
      
      • Remplacez PROJECT_ID par l'ID de votre projet Google Cloud .

      L'option -t représente le tag Docker. Il s'agit du nom de l'image que vous utilisez lorsque vous déployez le conteneur.

    3. Transférez l'image vers Artifact Registry :

      docker push us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1
      

    Conteneurisation de loadgen

    Ensuite, conteneurisez le service de générateur de charge de la même manière :

    1. Accédez au répertoire où se trouve l'exemple loadgen :

      cd ../loadgen
      
    2. Créez l'image comme suit :

      docker build -t us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1 .
      
    3. Transférez l'image vers Artifact Registry :

      docker push us-central1-docker.pkg.dev/PROJECT_ID/container-intro/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 us-central1-docker.pkg.dev/PROJECT_ID/container-intro
    

    Le résultat doit lister les noms des images que vous avez transférées, comme suit :

    NAME
    us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver
    us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen
    

    Créer un cluster GKE

    À ce stade, vous pouvez simplement exécuter les conteneurs sur la VM Cloud Shell à l'aide de la commande docker run. Toutefois, pour exécuter des charges de travail de production fiables, vous devez gérer les conteneurs de manière plus unifiée. Par exemple, vous devez vous assurer que les conteneurs redémarrent en cas d'échec, 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.

    GKE peut vous aider à répondre à ces besoins. 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 exécuter les conteneurs sur GKE, vous devez d'abord créer un cluster, puis vous y connecter :

    1. Créez le cluster :

      gcloud container clusters create-auto container-intro
      

      La commande gcloud crée un cluster dans le projet Google Cloud par défaut et la région que vous avez définis précédemment.

      La commande permettant la création d'un cluster prend quelques minutes. Lorsque le cluster est prêt, le résultat ressemble à ce qui suit :

       NAME: container-intro
       LOCATION: us-central1
       MASTER_VERSION: 1.30.4-gke.1348000
       MASTER_IP: 34.44.14.166
       MACHINE_TYPE: e2-small
       NODE_VERSION: 1.30.4-gke.1348000
       NUM_NODES: 3
       STATUS: RUNNING
      
    2. Fournissez les identifiants à l'outil de ligne de commande kubectl afin de pouvoir l'utiliser pour gérer le cluster :

      gcloud container clusters get-credentials container-intro
      

    Examiner les 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 fichier appelé manifeste. Les fichiers manifestes sont écrits dans des langages tels que YAML ou JSON, et contiennent la spécification d'un ou de plusieurs objets Kubernetes.

    L'exemple contient un fichier manifeste pour server et loadgen. Chaque fichier manifeste spécifie l'état souhaité pour l'objet de déploiement Kubernetes (qui gère l'exécution de votre conteneur, empaqueté pour la gestion en tant que pod Kubernetes) et le service (qui fournit une adresse IP pour le pod). Un pod est la plus petite unité de calcul déployable que vous pouvez créer et gérer dans Kubernetes. Il contient un ou plusieurs conteneurs.

    Le schéma suivant illustre l'application s'exécutant sur GKE :

    Application conteneurisée exécutée sur GKE

    Pour en savoir plus sur les pods, les déploiements et les services, consultez Commencer à découvrir Kubernetes ou les ressources à la fin de cette page.

    Serveur

    Commencez par examiner le fichier manifeste de l'server "hello world" :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: helloserver
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: helloserver
      template:
        metadata:
          labels:
            app: helloserver
        spec:
          containers:
          - image: gcr.io/google-samples/istio/helloserver:v0.0.1
            imagePullPolicy: Always
            name: main
          restartPolicy: Always
          terminationGracePeriodSeconds: 5

    Ce fichier manifeste contient les champs suivants :

    • kind indique le type d'objet.
    • metadata.name spécifie le nom du déploiement.
    • Le premier champ spec contient une description de l'état souhaité.
    • spec.replicas spécifie le nombre de pods souhaités.
    • La section spec.template définit un modèle de pod. Dans la spécification pour les pods, le champ image correspond au nom de l'image à extraire d'Artifact Registry. À l'étape suivante, vous allez remplacer cette image par celle que vous venez de créer.

    Le Service hellosvc est défini comme suit :

    apiVersion: v1
    kind: Service
    metadata:
      name: hellosvc
    spec:
      ports:
      - name: http
        port: 80
        targetPort: 8080
      selector:
        app: helloserver
      type: LoadBalancer
    • 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 commande EXPOSE 8080 de Dockerfile n'expose pas de ports. Exposez le port 8080 afin d'atteindre le conteneur server en dehors du cluster. Dans ce cas, hellosvc.default.cluster.local:80 (nom abrégé : hellosvc ) correspond au port 8080 de l'adresse IP du pod helloserver).
    • 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 la spécification de pod pour le déploiement loadgen comporte un champ appelé 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.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: loadgenerator
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: loadgenerator
      template:
        metadata:
          labels:
            app: loadgenerator
        spec:
          containers:
          - env:
            - name: SERVER_ADDR
              value: http://hellosvc:80/
            - name: REQUESTS_PER_SECOND
              value: '10'
            image: gcr.io/google-samples/istio/loadgen:v0.0.1
            imagePullPolicy: Always
            name: main
            resources:
              limits:
                cpu: 500m
                memory: 512Mi
              requests:
                cpu: 300m
                memory: 256Mi
          restartPolicy: Always
          terminationGracePeriodSeconds: 5

    Étant donné que loadgen n'accepte pas les requêtes entrantes, le champ type est défini sur ClusterIP. Ce type de service fournit une adresse IP stable que les entités du cluster peuvent utiliser, mais qui n'est pas exposée aux clients externes.

    apiVersion: v1
    kind: Service
    metadata:
      name: loadgensvc
    spec:
      ports:
      - name: http
        port: 80
        targetPort: 8080
      selector:
        app: loadgenerator
      type: ClusterIP

    Déployer les conteneurs sur GKE

    Pour déployer les conteneurs, vous appliquez les fichiers manifestes qui spécifient l'état souhaité à l'aide de kubectl.

    Déployer server

    1. Accédez au répertoire où se trouve l'exemple server :

      cd ~/anthos-service-mesh-samples/docs/helloserver/server/
    2. Ouvrez server.yaml dans l'éditeur Cloud Shell (ou l'éditeur de texte de votre choix).

    3. Remplacez le nom du champ image par le nom de votre image Docker.

      image: us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1
      

      Remplacez PROJECT_ID par l'ID de votre projet Google Cloud .

      • Si vous utilisez l'éditeur Cloud Shell, le fichier est enregistré automatiquement. Revenez à la fenêtre de terminal en cliquant sur Ouvrir le terminal.
      • Si vous utilisez un éditeur de texte dans Cloud Shell, enregistrez et fermez server.yaml.
    4. Déployez le fichier manifeste sur Kubernetes :

      kubectl apply -f server.yaml
      

      Le résultat ressemble à ce qui suit :

      deployment.apps/helloserver created
      service/hellosvc created
      

    Déployer loadgen

    1. Accédez au répertoire où se trouve loadgen.

      cd ../loadgen
      
    2. Ouvrez loadgen.yaml dans un éditeur de texte, comme précédemment.

    3. Encore une fois, remplacez le nom du champ image par le nom de votre image Docker.

      image: us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1
      

      Remplacez PROJECT_ID par l'ID de votre projet Google Cloud .

      • Si vous utilisez l'éditeur Cloud Shell, le fichier est enregistré automatiquement. Revenez à la fenêtre de terminal en cliquant sur Ouvrir le terminal.
      • Si vous utilisez un éditeur de texte dans Cloud Shell, enregistrez et fermez loadgen.yaml.
    4. Déployez le fichier manifeste sur votre cluster :

      kubectl apply -f loadgen.yaml
      

      En cas de réussite, la commande renvoie la réponse suivante :

      deployment.apps/loadgenerator created
      service/loadgensvc created
      

    Vérifier votre déploiement

    Après avoir déployé vos fichiers manifestes sur le cluster, vérifiez que vos conteneurs ont bien été déployés :

    1. Vérifiez l'état des pods de votre cluster :

      kubectl get pods
      

      La 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
      
    2. Récupérez les journaux de l'application à partir du pod loadgen. Remplacez POD_ID par l'identifiant du pod du générateur de charge de la sortie précédente.

      kubectl logs POD_ID
      
    3. Récupérez les adresses IP externes de hellosvc :

      kubectl get service hellosvc
      

      Le résultat ressemble à ce qui suit :

      NAME         TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
      hellosvc     LoadBalancer   10.81.15.158   192.0.2.1       80:31127/TCP   33m
      
    4. Envoyez une requête à hellosvc. Remplacez EXTERNAL_IP par l'adresse IP externe de votre hellosvc.

      curl http://EXTERNAL_IP
      

      Un message "Hello World!" doit s'afficher.

    Effectuer un nettoyage

    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 supprimez les ressources individuelles.

    Si vous ne souhaitez pas supprimer l'intégralité du projet :

    • Supprimez le cluster GKE. La suppression du cluster supprime toutes les ressources qui le constituent, telles que les instances Compute Engine, les disques et les ressources réseau.

       gcloud container clusters delete container-intro
      
    • Supprimez le dépôt Artifact Registry :

       gcloud artifacts repositories delete container-intro --location=us-central1
      

    Étapes suivantes