Du développement à la production en trois étapes simples avec Cloud Run

1. Introduction

Pourquoi est-il si difficile de gérer les applications ?

L'une des principales raisons est que les développeurs doivent souvent être administrateurs système à temps partiel. Voici une liste (non exhaustive) des points à prendre en compte pour développer, déployer et gérer une application Web moderne de qualité professionnelle :

4d018476b4a73b47.png

Je ne sais pas ce que vous en pensez, mais ce sont toutes des choses qui ne m'intéressent pas. Ce sur quoi je veux vraiment me concentrer, c'est la logique de mon application :

6dfd143d20e5548b.png

En résumé, c'est tout l'intérêt de Cloud Run : vous permettre de vous concentrer sur votre application et laisser à d'autres, à savoir Google, qui a investi des millions d'heures pour affiner et perfectionner ses compétences dans ce domaine, le soin de s'occuper de l'administration et de la maintenance.

En plus des difficultés administratives mentionnées ci-dessus, vous devez également faire face aux problèmes suivants :

  • Dépendances : l'environnement dans lequel votre application s'exécute doit, dans la mesure du possible, correspondre précisément à l'environnement dans lequel elle a été testée. Cela peut englober plusieurs dimensions, y compris le système d'exploitation, les bibliothèques d'assistance, l'interpréteur ou le compilateur de langage, la configuration matérielle et de nombreux autres facteurs.
  • Distribution : passer d'une version locale d'une application à une version largement partagée sur Internet nécessite souvent un changement d'environnement d'exécution, un saut quantique en termes de complexité et une courbe d'apprentissage abrupte.

Cloud Run s'en charge pour vous, ainsi que de bien d'autres aspects. Mais plutôt que de me croire sur parole, créons une application ensemble et voyons à quel point il est facile de passer d'un environnement de développement local à une application cloud de qualité professionnelle en quelques étapes simples.

Ce que vous allez effectuer...

  • Vous allez créer une application Web simple et vérifier qu'elle s'exécute comme prévu dans votre environnement de développement.
  • Vous passerez ensuite à une version conteneurisée de la même application. Vous découvrirez ce que signifie la conteneurisation et pourquoi elle est si utile.
  • Enfin, vous allez déployer votre application dans le cloud et découvrir à quel point il est facile de gérer votre service Cloud Run à l'aide de la ligne de commande et de la console Google Cloud.

Ce que vous allez apprendre...

  • Créer une application de serveur Web simple en Python
  • Empaqueter votre application dans un conteneur Docker exécutable n'importe où
  • Déployer votre application dans le cloud pour que tout le monde puisse essayer votre nouvelle création
  • Simplifier davantage les étapes ci-dessus à l'aide de buildpacks
  • Utiliser l'outil de ligne de commande Google Cloud et l'UI Web de la console Cloud

Ce dont vous avez besoin...

  • Un navigateur Web
  • Un compte Google

Cet atelier s'adresse aux développeurs de tous niveaux, y compris aux débutants. Bien que vous utilisiez Python, vous n'avez pas besoin de maîtriser la programmation Python pour comprendre le processus, car nous vous expliquerons tout le code que vous utiliserez.

2. Préparer l'atelier

5110b5081a1e1c49.png

Cette section décrit tout ce que vous devez faire pour commencer cet atelier.

Configuration de l'environnement au rythme de chacun

  1. Connectez-vous à la console Cloud, puis créez un projet ou réutilisez un projet existant. (Si vous ne possédez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.)

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Mémorisez l'ID du projet. Il s'agit d'un nom unique permettant de différencier chaque projet Google Cloud (le nom ci-dessus est déjà pris ; vous devez en trouver un autre). Il sera désigné par le nom PROJECT_ID tout au long de cet atelier de programmation.

  1. Vous devez ensuite activer la facturation dans Cloud Console pour pouvoir utiliser les ressources Google Cloud.

L'exécution de cet atelier de programmation est très peu coûteuse, voire sans frais. Veillez à suivre les instructions de la section "Nettoyer" qui indique comment désactiver les ressources afin d'éviter les frais une fois ce tutoriel terminé. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai sans frais pour bénéficier d'un crédit de 300$.

Démarrez Cloud Shell.

Dans cet atelier, vous allez travailler dans une session Cloud Shell. Cet environnement est un interpréteur de commandes hébergé sur une machine virtuelle qui s'exécute dans le cloud de Google. Vous pourriez tout aussi facilement effectuer les tâches de cette section en local sur votre propre ordinateur, mais le fait d'utiliser Cloud Shell permet à chacun de bénéficier d'une expérience reproductible dans un environnement cohérent. Après l'atelier, libre à vous de reproduire cette section sur votre ordinateur.

704a7b7491bd157.png

Activer Cloud Shell

  1. Dans Cloud Console, cliquez sur Activer Cloud Shell 4292cbf4971c9786.png.

bce75f34b2c53987.png

Si vous n'avez jamais démarré Cloud Shell auparavant, un écran intermédiaire s'affiche en dessous de la ligne de flottaison, décrivant de quoi il s'agit. Si tel est le cas, cliquez sur Continuer. Cet écran ne s'affiche qu'une seule fois. Voici à quoi il ressemble :

70f315d7b402b476.png

Le provisionnement et la connexion à Cloud Shell ne devraient pas prendre plus de quelques minutes.

fbe3a0674c982259.png

Cette machine virtuelle contient tous les outils de développement dont vous avez besoin. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Vous pouvez réaliser une grande partie, voire la totalité, des activités de cet atelier dans un simple navigateur ou sur votre Chromebook.

Une fois connecté à Cloud Shell, vous êtes en principe authentifié et le projet est défini avec votre ID de projet.

  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list

Résultat de la commande

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud connaît votre projet :
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Si vous obtenez un résultat différent, exécutez cette commande :

gcloud config set project <PROJECT_ID>

Résultat de la commande

Updated property [core/project].

Définissez des variables d'environnement dans votre terminal pour faciliter les étapes suivantes :

export PROJ=$GOOGLE_CLOUD_PROJECT 
export APP=hello 
export PORT=8080
export REGION="us-central1"
export TAG="gcr.io/$PROJ/$APP"

Activer les API

Dans les étapes suivantes, vous verrez où ces services sont requis (et pourquoi). Mais pour l'instant, exécutez la commande ci-dessous pour autoriser votre projet à accéder aux services Cloud Build, Container Registry et Cloud Run :

gcloud services enable cloudbuild.googleapis.com         \
                       containerregistry.googleapis.com  \
                       run.googleapis.com          

Un message semblable à celui qui suit s'affiche pour vous indiquer que l'opération s'est correctement déroulée :

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

3. Créer une application Web simple

eef530b56b8e93a3.png

Commencez par cliquer sur le bouton Open Editor en haut de votre panneau Cloud Shell. Elle se présente comme suit :

9b81c8a37a6bcdd8.png

Vous vous retrouverez alors dans un environnement IDE semblable à Visual Studio Code, dans lequel vous pourrez créer des projets, modifier du code source, exécuter vos programmes, etc. Si votre écran est trop petit, vous pouvez agrandir ou réduire la ligne de séparation entre la console et votre fenêtre d'édition/de terminal en faisant glisser la barre horizontale entre ces deux régions, comme indiqué ici :

8dea35450851af53.png

Vous pouvez passer de l'éditeur au terminal et inversement en cliquant respectivement sur les boutons Open Editor et Open Terminal. Essayez maintenant de passer d'un environnement à l'autre.

Créez ensuite un dossier dans lequel stocker votre travail pour cet atelier en sélectionnant File->New Folder (Fichier->Nouveau dossier), saisissez hello, puis cliquez sur OK. Tous les fichiers que vous allez créer dans cet atelier et tout le travail que vous allez effectuer dans Cloud Shell se feront dans ce dossier.

Créez maintenant un fichier requirements.txt. Cela indique à Python les bibliothèques dont votre application dépend. Pour cette application Web simple, vous allez utiliser un module Python populaire pour créer des serveurs Web appelé Flask et un framework de serveur Web appelé gunicorn. Dans la fenêtre de l'éditeur Cloud, cliquez sur le menu Fichier > Nouveau fichier pour créer un fichier. Lorsque vous êtes invité à saisir le nom du nouveau fichier, saisissez requirements.txt, puis appuyez sur le bouton OK. Assurez-vous que le nouveau fichier se trouve dans le dossier du projet hello.

Saisissez les lignes suivantes dans le nouveau fichier pour spécifier que votre application dépend du package Python Flask et du serveur Web gunicorn.

Flask
gunicorn

Vous n'avez pas besoin d'enregistrer explicitement ce fichier, car l'éditeur Cloud enregistre automatiquement les modifications.

Version 1 : Hello world!

En utilisant la même technique, créez un autre fichier nommé main.py. Il s'agira du fichier source Python principal (et unique) de votre application. Veillez à ce que le nouveau fichier se retrouve dans le dossier du projet hello.

Insérez le code suivant dans ce fichier :

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
@app.route("/", methods=["GET"])
def say_hello():
    html = "<h1>Hello world!</h1>"
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Revenez dans le terminal et accédez au dossier du projet à l'aide de la commande suivante :

cd hello

Exécutez la commande suivante pour installer les dépendances de votre projet :

pip3 install -r requirements.txt

Lancez maintenant votre application en exécutant cette commande dans le terminal :

python3 main.py

À ce stade, votre application s'exécute sur la machine virtuelle dédiée à votre session Cloud Shell. Cloud Shell inclut un mécanisme de proxy qui vous permet d'accéder aux serveurs Web (comme celui que vous venez de démarrer) exécutés sur votre machine virtuelle depuis n'importe où sur Internet.

Cliquez sur le bouton web preview, puis sur l'élément de menu Preview on Port 8080, comme suit :

fe45e0192080efd6.png

Un onglet de navigateur Web s'ouvre sur votre application en cours d'exécution, qui devrait ressembler à ceci :

b1f06501509aefb9.png

Version 2 : Écho du chemin d'URL

Revenez à l'éditeur Cloud (via le bouton Open Editor) et ajoutez la prise en charge de l'écho d'un suffixe d'URL facultatif en mettant à jour votre fichier main.py comme suit :

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])     # ← NEW
def say_hello(name="world"):               # ← MODIFIED
    html = f"<h1>Hello {name}!</h1>"       # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Revenez au terminal (via le bouton Open Terminal) et saisissez control-C (maintenez la touche Ctrl enfoncée tout en appuyant sur "C") pour arrêter l'application en cours d'exécution, puis redémarrez-la en saisissant :

python3 main.py

Cliquez à nouveau sur le bouton web preview, puis sur l'élément de menu Preview on Port 8080 pour ouvrir un onglet de navigateur Web sur votre application en cours d'exécution. Vous devriez à nouveau voir le message "Hello world!". Remplacez ensuite le texte de l'URL qui suit la barre oblique par la chaîne de votre choix (par exemple, /your-name) et vérifiez que vous voyez quelque chose comme ceci :

93b87996f88fa370.png

Version 3 : Couleurs aléatoires

Maintenant, ajoutez la prise en charge des couleurs d'arrière-plan aléatoires en revenant à l'éditeur Cloud (via le bouton Open Editor) et en mettant à jour votre fichier main.py comme suit :

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# This function decides whether foreground text should be
# displayed in black or white, to maximize fg/bg contrast.
def set_text_color(rgb):                      # ← NEW
    sum = round(                              # ← NEW
        (int(rgb[0]) * 0.299)                 # ← NEW
        + (int(rgb[1]) * 0.587)               # ← NEW
        + (int(rgb[2]) * 0.114)               # ← NEW
    )                                         # ← NEW
    return "black" if sum > 186 else "white"  # ← NEW


# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
# To verify each new invocation of these requests, the HTML document
# includes CSS styling to produce a randomly colored background.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])
def say_hello(name="world"):
    bg = random.sample(range(1, 255), 3)                       # ← NEW
    hex = (int(bg[0]) * 256) + (int(bg[1]) * 16) + int(bg[2])  # ← NEW
    fg_color = set_text_color(bg)                              # ← NEW
    bg_color = f"#{hex:06x}"                                   # ← NEW
    style = f"color:{fg_color}; background-color:{bg_color}"   # ← NEW
    html = f'<h1 style="{style}">Hello {name}!</h1>'           # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Revenez au terminal (via le bouton Open Terminal) et saisissez control-C (maintenez la touche Ctrl enfoncée tout en appuyant sur "C") pour arrêter l'application en cours d'exécution, puis redémarrez-la en saisissant :

python3 main.py

Cliquez à nouveau sur le bouton web preview, puis sur l'élément de menu Preview on Port 8080 pour ouvrir un onglet de navigateur Web sur votre application en cours d'exécution. Vous devriez voir le texte généré, avec le suffixe spécifié ou la chaîne par défaut "Hello world!", affiché devant un arrière-plan de couleur aléatoire, comme ceci :

baf8d028f15ea7f4.png

Actualisez la page plusieurs fois pour voir que la couleur de fond aléatoire change chaque fois que vous accédez à l'application.

Et voilà, votre application est terminée. Félicitations ! Dans l'étape suivante, vous apprendrez à empaqueter votre application dans un conteneur et pourquoi cela est utile.

4. Conteneuriser votre application

17cc234ec3325a8a.png

Qu'est-ce qu'un conteneur ?

Les conteneurs en général, et Docker en particulier, nous permettent de créer une boîte modulaire dans laquelle exécuter une application avec toutes ses dépendances regroupées. Le résultat est appelé "image de conteneur". Dans cette section, vous allez créer une image de conteneur que vous utiliserez pour encapsuler votre application et toutes ses dépendances.

En parlant de dépendances, lors d'une étape précédente, lorsque vous exécutiez votre application dans un environnement de développement, vous deviez exécuter pip3 install -r requirements.txt et vous assurer que le fichier requirements.txt contenait toutes vos bibliothèques dépendantes et les versions correspondantes. Avec les conteneurs, vous installez ces exigences lorsque vous générez l'image du conteneur. L'utilisateur du conteneur n'a donc pas à se soucier de l'installation.

Cette image de conteneur constituera le bloc de base pour déployer votre application sur Cloud Run. Comme les conteneurs peuvent être utilisés sur presque tous les serveurs virtuels ou réels, cela nous permet de déployer votre application où vous le souhaitez, et de la déplacer d'un fournisseur de services à un autre, ou d'un environnement sur site vers le cloud.

Les conteneurs permettent de rendre vos applications :

  • reproductibles : les conteneurs sont autonomes et complets.
  • Portabilité : les conteneurs sont des blocs de construction intersectoriels qui permettent la portabilité des applications entre les fournisseurs de services cloud et les environnements.

En bref, les conteneurs permettent enfin d'écrire le code une fois et de l'exécuter n'importe où. Une exception à cette règle est que le conteneur généré est limité à l'exécution sur le type de processeur sur lequel vous l'avez créé. Toutefois, il existe des moyens de générer des versions de conteneur pour d'autres configurations matérielles.

Assez parlé, créons un conteneur ! Vous allez utiliser une technologie spécifique pour créer un conteneur, appelée Docker.

Dans l'éditeur Cloud, créez un fichier nommé Dockerfile. Ce fichier est un plan pour construire votre image. Il indique à Docker votre environnement d'exploitation et votre code source, comment installer vos dépendances, compiler votre application et exécuter votre code.

# Use an official lightweight Python image.
FROM python:3.9-slim

# Copy local code to the container image.
WORKDIR /app
COPY main.py .
COPY requirements.txt .

# Install dependencies into this container so there's no need to 
# install anything at container run time.
RUN pip install -r requirements.txt

# Service must listen to $PORT environment variable.
# This default value facilitates local development.
ENV PORT 8080

# Run the web service on container startup. Here you use the gunicorn
# server, with one worker process and 8 threads. For environments 
# with multiple CPU cores, increase the number of workers to match 
# the number of cores available.
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 main:app

Dans le terminal cloud, créez votre image de conteneur à l'aide de Cloud Build en exécutant la commande suivante :

gcloud builds submit --tag $TAG

Une fois le transfert dans le registre terminé, un message SUCCESS contenant le nom de l'image s'affiche. Il devrait ressembler à ceci : gcr.io/<project-id>/hello. L'image est désormais stockée dans Google Container Registry et peut être réutilisée quand et où vous le souhaitez.

Exécutez la commande suivante pour lister toutes les images de conteneur associées à votre projet actuel :

gcloud container images list

Exécutez et testez l'application en local depuis Cloud Shell à l'aide des commandes docker suivantes :

docker run -p $PORT:$PORT -e PORT=$PORT $TAG

L'option -p $PORT:$PORT indique à Docker de mapper le port externe $PORT (défini sur 8080 ci-dessus) dans l'environnement hôte sur le même numéro de port à l'intérieur du conteneur en cours d'exécution. Cela vous simplifie la vie, car le code du serveur que vous écrivez et le numéro de port externe auquel vous vous connectez lorsque vous testez votre application seront les mêmes (8080). Toutefois, vous pouvez tout aussi bien utiliser l'option -p pour mapper n'importe quel port externe arbitraire sur l'hôte à n'importe quel port interne souhaité dans le conteneur.

L'option -e PORT=$PORT indique à Docker de rendre la variable d'environnement $PORT (définie sur 8080 ci-dessus) disponible pour votre application exécutée dans le conteneur.

Vous êtes maintenant prêt à tester votre application en pointant un navigateur Web vers le code Python exécuté dans le conteneur. Dans la fenêtre Cloud Shell, cliquez sur l'icône "Aperçu sur le Web", puis sélectionnez "Prévisualiser sur le port 8080", comme vous l'avez fait à l'étape précédente.

Le résultat devrait vous être familier : vous devriez voir le texte généré devant un arrière-plan de couleur aléatoire, comme lorsque vous avez exécuté l'application directement dans votre terminal Cloud Shell. Actualisez la page plusieurs fois pour voir que la couleur de fond aléatoire change chaque fois que vous accédez à l'application.

Félicitations ! Vous avez maintenant exécuté une version conteneurisée de votre application. Dans la section suivante, sans toucher une seule ligne de code, vous allez transformer votre image de conteneur en une application Web de qualité professionnelle.

5. Vers le cloud…

1b0665d94750ded6.gif

Maintenant que vous avez conteneurisé votre application, vous allez vouloir partager cette merveille avec le reste du monde. Il est donc temps de la déployer dans le cloud. Mais vous aimeriez faire plus que simplement le partager. Vous souhaitez vous assurer que :

  • fonctionne de manière fiable : vous bénéficiez d'une tolérance aux pannes automatique en cas de plantage d'un ordinateur exécutant votre application.
  • Il s'adapte automatiquement : votre application peut gérer de gros volumes de trafic et réduit automatiquement son empreinte lorsqu'elle n'est pas utilisée.
  • minimise vos coûts en ne vous facturant pas les ressources que vous n'utilisez pas. Vous n'êtes facturé que pour les ressources consommées lors de la réponse au trafic.
  • est accessible via un nom de domaine personnalisé : vous disposez d'une solution en un clic pour attribuer un nom de domaine personnalisé à votre service.
  • offre un excellent temps de réponse. Les démarrages à froid sont raisonnablement réactifs, mais vous pouvez les affiner en spécifiant une configuration d'instance minimale.
  • accepte le chiffrement de bout en bout à l'aide de la sécurité Web SSL/TLS standard : lorsque vous déployez un service, vous bénéficiez sans frais et automatiquement du chiffrement Web standard et des certificats requis correspondants.

En déployant votre application sur Google Cloud Run, vous bénéficiez de tous les avantages ci-dessus et plus encore.

Déployer votre application sur Cloud Run

Commençons par modifier votre application pour que vous puissiez distinguer la nouvelle révision de l'ancienne. Pour ce faire, modifiez le fichier main.py afin que le message par défaut passe de "Hello world!" à "Hello from Cloud Run!". En d'autres termes, remplacez cette ligne dans main.py :

def say_hello(name="world"):

par celle-ci :

def say_hello(name="from Cloud Run"):

Cloud Run est régional, ce qui signifie que l'infrastructure qui exécute vos services Cloud Run est située dans une région spécifique, et gérée par Google pour être disponible de manière redondante dans toutes les zones de cette région. Dans la section "Configuration" ci-dessus, vous avez défini une région par défaut à l'aide de la variable d'environnement REGION.

Recréez votre image de conteneur et déployez votre application conteneurisée dans Cloud Run à l'aide de la commande suivante :

gcloud builds submit --tag $TAG
gcloud run deploy "$APP"   \
  --image "$TAG"           \
  --platform "managed"     \
  --region "$REGION"       \
  --allow-unauthenticated
  • Vous pouvez également définir une région par défaut avec gcloud config set run/region $REGION.
  • L'option --allow-unauthenticated rend le service accessible au public. Pour éviter les requêtes non authentifiées, utilisez plutôt --no-allow-unauthenticated.

L'image spécifiée ici est l'image Docker que vous avez créée à la dernière étape. Grâce au service Cloud Build, qui a stocké l'image résultante dans Google Container Registry, le service Cloud Run peut la trouver et la déployer pour vous.

Patientez quelques instants jusqu'à la fin du déploiement. En cas de réussite, la ligne de commande affiche l'URL du service :

Deploying container to Cloud Run service [hello] in project [PROJECT_ID...
✓ Deploying new service... Done.                                   
  ✓ Creating Revision... Revision deployment finished. Waiting for health check...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [hello] revision [hello-...] has been deployed and is serving 100 percent of traffic.
Service URL: https://hello-....a.run.app

Vous pouvez également récupérer l'URL de votre service à l'aide de cette commande :

gcloud run services describe hello  \
  --platform managed                \
  --region $REGION                  \
  --format "value(status.url)"

Vous devriez obtenir un résultat semblable à celui-ci :

https://hello-....a.run.app

Ce lien est une URL dédiée, avec sécurité TLS, pour votre service Cloud Run. Ce lien est permanent (tant que vous n'avez pas désactivé votre service) et peut être utilisé n'importe où sur Internet. Il n'utilise pas le mécanisme de proxy de Cloud Shell mentionné précédemment, qui dépendait d'une machine virtuelle temporaire.

Cliquez sur le Service URL en surbrillance pour ouvrir un onglet de navigateur Web vers votre application en cours d'exécution. Le résultat doit afficher le message "Hello from Cloud Run!" sur un arrière-plan de couleur aléatoire.

Félicitations ! Votre application s'exécute désormais dans le cloud de Google. Votre application est disponible publiquement, avec un chiffrement TLS (HTTPS) et une mise à l'échelle automatique pour gérer des niveaux de trafic incroyables.

Mais je pense que ce processus pourrait être encore plus simple…

6. Créer automatiquement le conteneur

Tout cela est très intéressant, mais que se passe-t-il si je ne veux même pas penser aux Dockerfiles et aux conteneurs ? Que se passe-t-il si, comme la plupart des développeurs, je souhaite simplement me concentrer sur l'écriture du code de mon application et laisser quelqu'un d'autre se soucier de la conteneurisation ? Bonne nouvelle : Cloud Run est compatible avec une norme Open Source appelée Buildpacks, qui existe précisément pour automatiser le processus de fabrication d'un conteneur à partir d'une collection de fichiers sources.

Notez que dans certains cas, un développeur peut préférer utiliser un fichier Dockerfile explicite, par exemple s'il souhaite un haut degré de personnalisation dans la façon dont son conteneur est construit. Toutefois, pour les cas courants comme cet exercice, les buildpacks fonctionnent bien et évitent d'avoir à créer manuellement un fichier Dockerfile. Modifions votre code pour utiliser des buildpacks.

Commençons par modifier votre application pour que vous puissiez distinguer la nouvelle révision de l'ancienne. Pour ce faire, modifiez le fichier main.py de sorte que le message par défaut passe de "Hello from Cloud Run!" à "Hello from Cloud Run with Buildpacks!". En d'autres termes, remplacez cette ligne dans main.py :

def say_hello(name="from Cloud Run"):

par celle-ci :

def say_hello(name="from Cloud Run with Buildpacks"):

Maintenant, profitons des buildpacks en créant un fichier nommé Procfile. Créez ce fichier dans l'éditeur Cloud et insérez cette ligne de texte :

web: python3 main.py

Cela indique au système buildback comment exécuter votre application dans le conteneur généré automatiquement. Avec cette instruction, vous n'avez même plus besoin de fichier Dockerfile. Pour vérifier cela, supprimez votre fichier Dockerfile et exécutez la commande suivante dans le terminal Cloud Shell :

gcloud beta run deploy "$APP"  \
    --source .                 \
    --platform "managed"       \
    --region "$REGION"         \
    --allow-unauthenticated

Cette commande est semblable à celle que vous avez exécutée pour déployer votre application à la dernière étape, mais cette fois-ci, vous avez remplacé l'option --image par l'option --source .. Cela indique à la commande gcloud que vous souhaitez qu'elle utilise des buildpacks pour créer votre image de conteneur, en fonction des fichiers sources qu'elle trouve dans le répertoire actuel (le dot dans --source . est une abréviation pour le répertoire actuel). Étant donné que le service s'occupe implicitement de l'image de conteneur, vous n'avez pas besoin de spécifier d'image dans cette commande gcloud.

Une fois encore, vérifiez que ce déploiement a fonctionné en cliquant sur Service URL pour ouvrir un onglet de navigateur Web sur votre application en cours d'exécution et assurez-vous que votre service affiche "Hello from Cloud Run with Buildpacks!" sur un arrière-plan de couleur aléatoire.

Notez qu'en utilisant des buildpacks pour fabriquer votre Dockerfile, vous avez essentiellement réduit les trois étapes faciles à deux :

  1. Créez une application dans votre environnement de développement.
  2. Déployez exactement le même code dans le cloud avec une seule commande.

7. Dois-je utiliser la ligne de commande ?

Non ! Comme pour presque tous les services Google Cloud, il existe trois façons d'interagir avec Cloud Run :

  • L'outil de ligne de commande gcloud, que vous venez de découvrir.
  • Une interface utilisateur Web enrichie, via la console Cloud, qui prend en charge un style d'interaction intuitif par pointeur et clic.
  • De manière programmatique, à l'aide des bibliothèques clientes Google disponibles pour de nombreux langages courants, y compris Java, C#, Python, Go, JavaScript, Ruby, C/C++ et d'autres.

Déployons une instance supplémentaire de votre application Cloud Run à l'aide de l'interface utilisateur de la console. Accédez à la page de destination du service Cloud Run via le menu en haut à gauche :

e2b4983b38c81796.png

Vous devriez ensuite voir un récapitulatif de vos services Cloud Run, comme celui-ci :

b335e7bf0a3af845.png

Cliquez sur le lien "Create Service" (Créer un service) pour lancer le processus de déploiement :

51f61a8ddc7a4c0b.png

Saisissez "hello-again" comme nom de service, conservez la plate-forme de déploiement et la région par défaut, puis cliquez sur "Suivant".

8a17baa45336c4c9.png

Saisissez l'URL de l'image du conteneur : gcr.io/cloudrun/hello. Il s'agit d'un conteneur créé par Google à des fins de test. Cliquez sur le menu déroulant "Paramètres avancés" pour afficher certains des nombreux paramètres de configuration disponibles. Voici quelques exemples d'éléments que vous pouvez personnaliser :

  • le numéro de port et le point d'entrée du conteneur (qui remplacera le point d'entrée spécifié lors de la création du conteneur).
  • Matériel : mémoire et nombre de processeurs
  • Scaling : nombre minimal et maximal d'instances
  • variables d'environnement
  • Autres : paramètre de délai avant expiration des requêtes, nombre maximal de requêtes par conteneur, HTTP/2

Cliquez sur le bouton "Suivant" pour passer à la boîte de dialogue suivante. La boîte de dialogue suivante vous permet de spécifier comment votre service est déclenché. Pour "Ingress", sélectionnez "Autoriser tout le trafic", et pour "Authentification", sélectionnez "Autoriser le trafic non authentifié".

e78281d1cff3418.png

Il s'agit des paramètres les plus ouverts, car ils permettent à n'importe qui d'accéder à votre application Cloud Run, depuis n'importe où sur l'Internet public, sans spécifier d'identifiants d'authentification. Vous pouvez choisir des paramètres plus restrictifs pour votre application, mais restons simples pour cet exercice d'apprentissage.

Cliquez ensuite sur le bouton Create pour créer votre service Cloud Run. Après quelques secondes, votre nouveau service devrait apparaître dans la liste récapitulative des services Cloud Run. La ligne récapitulative fournit le déploiement le plus récent (date/heure et auteur) ainsi que certains paramètres de configuration clés. Cliquez sur le lien du nom du service pour afficher plus de détails sur votre nouveau service.

Pour valider votre service, cliquez sur l'URL affichée en haut de la page récapitulative, comme indiqué dans l'exemple ci-dessous :

6c35cf0636dddc51.png

L'écran qui s'affiche devrait ressembler à ce qui suit :

3ba6ab4fe0da1f84.png

Maintenant que vous avez déployé un service Cloud Run, sélectionnez l'onglet REVISIONS pour découvrir différentes façons de gérer plusieurs déploiements.

2351ee7ec4a356f0.png

Pour déployer de nouvelles révisions directement depuis la console, vous pouvez cliquer sur le bouton EDIT & DEPLOY NEW REVISION, comme indiqué dans l'exemple de capture d'écran ci-dessous :

a599fa88d00d6776.png

Cliquez sur ce bouton pour créer une révision. À côté de l'URL du conteneur, cliquez sur le bouton SELECT, comme illustré ci-dessous :

5fd1b1f8e1f11d40.png

Dans la boîte de dialogue qui s'affiche, recherchez l'application Web simple que vous avez déployée à partir de Cloud Build à l'aide de Buildpacks, puis cliquez sur "Sélectionner". Veillez à choisir l'image de conteneur sous

gcr.io/<project>/cloud-run-source-deploy

folder , comme suit :

8a756c6157face3a.png

Une fois la langue sélectionnée, faites défiler la page jusqu'en bas, puis cliquez sur le bouton DEPLOY. Vous avez déployé une nouvelle révision de votre application. Pour le vérifier, accédez de nouveau à l'URL de votre service et assurez-vous que l'application Web "Hello from Cloud Run with Buildpacks!" colorée s'affiche.

Comme vous pouvez le voir, l'onglet "Révisions" fournit un récapitulatif de chaque révision que vous avez déployée. Vous devriez maintenant voir deux révisions pour ce service. Vous pouvez sélectionner une révision en cliquant sur le bouton radio à gauche de son nom. Un récapitulatif des détails de la révision s'affiche alors sur la droite de l'écran. En sélectionnant ces boutons, vous pouvez voir que vos deux révisions sont issues de deux images de conteneur différentes.

Le bouton MANAGE TRAFFIC vous permet de modifier la distribution des requêtes entrantes envoyées à une révision donnée. Cette capacité à affiner la quantité de trafic envoyée à une révision donnée permet plusieurs cas d'utilisation intéressants :

  • Tester une nouvelle version de votre application avec une petite partie du trafic entrant
  • rediriger le trafic d'une version problématique vers une révision précédente.
  • Tests A/B

Voici où trouver le bouton MANAGE TRAFFIC :

519d3c22ae028287.png

Configurez une répartition du trafic à 50/50 entre vos deux révisions en spécifiant une répartition du trafic à 50/50 comme suit :

8c37d4f115d9ded4.png

Cliquez maintenant sur le bouton "SAVE" (ENREGISTRER), puis vérifiez la répartition 50/50 en accédant plusieurs fois à l'URL de votre service. Assurez-vous qu'en moyenne, la moitié de vos requêtes sont traitées par la révision actuelle ("Hello from Cloud Run with Buildpacks!") et l'autre moitié par la révision précédente ("It's running!").

Les autres onglets de la page "Détails du service" vous permettent de surveiller les performances, le trafic et les journaux. Vous obtenez ainsi des informations précieuses sur la charge de travail de votre service et son efficacité. Vous pouvez également affiner l'accès à votre service via l'onglet "Autorisations". Prenez quelques instants pour explorer les onglets de cette page et découvrir les fonctionnalités disponibles.

Interface programmatique

Comme indiqué précédemment, vous pouvez également créer, déployer et gérer vos services Cloud Run de manière programmatique. Pour les tâches manuelles, cette option est plus avancée que la ligne de commande ou la console Web, mais c'est sans aucun doute la meilleure solution pour automatiser les services Cloud Run. Vous pouvez utiliser les bibliothèques clientes Google dans plusieurs langages de programmation courants.

8. Tester votre application

198ada162d1f0bf1.png

Lors de cette dernière étape, vous allez exécuter un test de charge artificielle pour tester la résistance de votre application et observer comment elle évolue en fonction de la demande entrante. Vous allez utiliser un outil appelé hey, qui est préinstallé dans Cloud Shell et qui nous permet d'exécuter des tests de charge et de présenter les résultats.

Exécuter le test

Dans le terminal Cloud Shell, exécutez cette commande pour effectuer un test de charge :

hey -q 1000 -c 200 -z 30s https://hello-...run.app

Les arguments de la commande sont interprétés comme suit :

  • -q 1000 : essayez de générer la charge à environ 1 000 requêtes par seconde.
  • -c 200 : allouer 200 workers parallèles
  • -z 30s : exécute le test de charge pendant 30 secondes
  • Veillez à utiliser l'URL de votre service comme dernier argument de cette ligne de commande.

Les résultats de votre test devraient ressembler à ceci :

 Summary:
 Total:        30.2767 secs
 Slowest:      3.3633 secs
 Fastest:      0.1071 secs
 Average:      0.1828 secs
 Requests/sec: 1087.2387
 Total data:   3028456 bytes
 Size/request: 92 bytes

Response time histogram:
 0.107 [1]     |
 0.433 [31346] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 0.758 [1472]  |■■
 1.084 [82]    |
 1.410 [4]     |
...

Latency distribution:
...
 50% in 0.1528 secs
 75% in 0.1949 secs
 90% in 0.2442 secs
 95% in 0.4052 secs
 99% in 0.7062 secs

Details (average, fastest, slowest):
...
 req write:    0.0000 secs, 0.0000 secs, 0.0232 secs
 resp wait:    0.1824 secs, 0.1070 secs, 3.2953 secs
 resp read:    0.0000 secs, 0.0000 secs, 0.0010 secs
Status code distribution:
 [200] 32918 responses

Ce résumé nous indique plusieurs éléments intéressants :

  • 32 918 requêtes ont été envoyées à environ 1 000 requêtes par seconde pendant 30 secondes.
  • Aucune erreur n'a été détectée (seulement des réponses HTTP 200).
  • La latence moyenne était de 180 ms.
  • La latence minimale était de 107 ms et la latence maximale de 3, 3 s.
  • La latence au 90e centile était de 244 ms.

Si vous consultez l'onglet METRICS de la console Cloud Run, vous pouvez voir le côté serveur de l'histoire des performances :

e635c6831c468dd3.png

9. Nettoyage

Bien que le service Cloud Run ne soit pas facturé lorsqu'il n'est pas utilisé, il se peut que des frais vous incombent pour le stockage de l'image de conteneur générée.

Afin d'éviter que des frais ne vous soient facturés, vous pouvez soit supprimer votre projet GCP, ce qui interrompra la facturation de toutes les ressources qui y ont été utilisées, soit supprimer votre image de conteneur en exécutant la commande suivante :

gcloud container images delete $TAG

Pour supprimer vos services Cloud Run, utilisez les commandes suivantes :

gcloud run services delete hello --platform managed --region $REGION --quiet
gcloud run services delete hello-again --platform managed --region $REGION --quiet

10. Bravo !

9a31f4fdbbf1ddcb.png

Félicitations ! Vous avez réussi à créer et à déployer une application Cloud Run de production. Vous avez également découvert les conteneurs et appris à créer le vôtre. Vous avez vu à quel point il est facile de déployer votre application avec Cloud Run, à l'aide de l'outil de ligne de commande gcloud et de la console Cloud. Vous savez maintenant comment partager vos brillantes créations avec le monde entier.

Je voudrais vous laisser avec une question importante :

Une fois votre application opérationnelle dans votre environnement de développement, combien de lignes de code avez-vous dû modifier pour la déployer dans le cloud, avec tous les attributs de qualité de production offerts par Cloud Run ?

La réponse est bien sûr zéro. :)

Ateliers de programmation à découvrir :

Autres fonctionnalités intéressantes à découvrir…

Documents de référence...

11. Incitation à l'action

Logo Google Cloud

Si vous avez apprécié cet atelier de programmation et que vous prévoyez de passer plus de temps à utiliser Google Cloud, nous vous recommandons vivement de rejoindre Google Cloud Innovators dès aujourd'hui !

Logo du badge de membre général du programme Innovators

Google Cloud Innovators est sans frais et inclut :

  • Discussions en direct, sessions AMA et interventions dédiées à la feuille de route pour découvrir les dernières actualités directement auprès des Googleurs
  • les dernières actualités Google Cloud directement dans votre boîte de réception ;
  • Badge numérique et arrière-plan de visioconférence
  • 500 crédits d'ateliers et de formations sur Skills Boost

Cliquez ici pour vous inscrire.