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 des administrateurs système à temps partiel. Prenez en compte cette liste (partielle) de problèmes pour développer, déployer et gérer une application Web moderne de production :

4d018476b4a73b47.png

Je ne sais pas pour toi, mais je ne veux pas m'inquiéter pour tout ce qui concerne ! Ce que je veux vraiment penser, c'est la logique de ma candidature:

6dfd143d20e5548b.png

En résumé, c'est là qu'intervient Cloud Run : vous pouvez vous concentrer sur votre application, et confier l'administration et la maintenance à quelqu'un d'autre, à savoir Google, qui a investi des millions d'heures pour affiner et perfectionner ses compétences dans ce domaine.

Outre les difficultés administratives mentionnées ci-dessus, vous devez également gérer les aspects 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 inclure plusieurs dimensions, y compris le système d'exploitation, les bibliothèques Support, l'interpréteur ou le compilateur de langage, la configuration matérielle et de nombreux autres facteurs.
  • Distribution : passer d'une incarnation locale d'une application à une application largement partagée sur Internet nécessite souvent un changement d'environnement d'exécution, un bond en complexité et une phase d'apprentissage intensive.

Cloud Run se charge de ces problèmes et de bien d'autres. Au lieu de me croire sur parole, créons une application ensemble et découvrons à quel point il est facile de passer d'un environnement de développement local à une application cloud de production 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. En cours de route, vous découvrirez ce qu'est la conteneurisation et pourquoi elle est si utile.
  • Enfin, vous déploierez votre application dans le cloud et verrez à 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écuté n'importe où
  • Déployer votre application dans le cloud pour que tous les utilisateurs puissent 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 deviez utiliser Python, vous n'avez pas besoin d'être familiarisé avec la programmation Python pour comprendre ce qui se passe, car nous allons vous expliquer tout le code que vous utilisez.

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 gratuite. 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, un interpréteur de commandes hébergé par une machine virtuelle exécutée 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 (en dessous de la ligne de flottaison) vous explique de quoi il s'agit. Dans ce cas, cliquez sur Continuer (elle ne s'affiche plus jamais). 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 vous faciliter la tâche dans 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

Lors des étapes suivantes, vous verrez où ces services sont nécessaires (et pourquoi). Pour le moment, exécutez la commande suivante afin d'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 trouverez ensuite dans un environnement IDE semblable à Visual Studio Code, dans lequel vous pouvez créer des projets, modifier le code source, exécuter vos programmes, etc. Si votre écran est trop étroit, vous pouvez agrandir ou réduire la ligne de séparation entre la console et votre fenêtre de modification/terminal en faisant glisser la barre horizontale entre ces deux régions, mises en surbrillance ici:

8dea35450851af53.png

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

Ensuite, créez un dossier dans lequel stocker votre travail pour cet atelier. Pour ce faire, sélectionnez Fichier > Nouveau dossier, saisissez hello, puis cliquez sur OK. Tous les fichiers que vous créerez dans cet atelier, ainsi que tout le travail que vous effectuerez dans Cloud Shell, seront stockés dans ce dossier.

Créez maintenant un fichier requirements.txt. Cela indique à Python de quelles bibliothèques dépend votre application. Pour cette application Web simple, vous allez utiliser un module Python populaire permettant de 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 et 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 indiquer 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 pour vous.

Version 1: Hello World !

En utilisant la même technique, créez un autre fichier nommé main.py. Il s'agit du fichier source Python principal (et unique) de votre application. Là encore, assurez-vous que le nouveau fichier se trouve 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 au terminal et accédez au dossier du projet à l'aide de cette commande:

cd hello

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

pip3 install -r requirements.txt

À présent, lancez votre application en exécutant la commande suivante 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 commencer) 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 pour votre application en cours d'exécution, qui devrait ressembler à ceci:

b1f06501509aefb9.png

Version 2: répéter le chemin de l'URL

Revenez à l'éditeur Cloud (via le bouton Open Editor) et ajoutez la possibilité de répéter 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 de nouveau sur le bouton web preview, puis sur l'élément de menu Preview on Port 8080 pour ouvrir un onglet de navigateur Web dans votre application en cours d'exécution. Le message "Hello World!" doit de nouveau s'afficher. , mais remplacez le texte de l'URL qui suit la barre oblique par n'importe quelle chaîne de votre choix (par exemple, /your-name) et vérifiez que le message suivant s'affiche:

93b87996f88fa370.png

Version 3: Couleurs aléatoires

À présent, vous pouvez ajouter 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 de nouveau sur le bouton web preview, puis sur l'élément de menu Preview on Port 8080 pour ouvrir un onglet de navigateur Web dans votre application en cours d'exécution. Le texte généré doit s'afficher, avec n'importe quel suffixe spécifié ou avec la valeur par défaut "Hello World!" , affichée devant un arrière-plan de couleur aléatoire, comme ceci:

baf8d028f15ea7f4.png

Actualisez plusieurs fois la page pour constater que la couleur d'arrière-plan aléatoire change chaque fois que vous accédez à l'application.

Votre application est maintenant terminée. Félicitations ! À l'étape suivante, vous découvrirez comment empaqueter votre application dans un conteneur et pourquoi cette opération 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 zone modulaire dans laquelle exécuter une application avec toutes ses dépendances regroupées. Le résultat est une image de conteneur. Dans cette section, vous allez créer une image de conteneur qui vous permettra d'encapsuler votre application et toutes ses dépendances.

Concernant les 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 les bibliothèques dépendantes et les versions correspondantes. Avec les conteneurs, vous installez ces exigences lorsque vous générez l'image de conteneur. Le consommateur du conteneur n'a donc pas besoin d'installer quoi que ce soit.

Cette image de conteneur constitue l'élément de base pour le déploiement de 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.

Grâce aux conteneurs, vos applications peuvent:

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

En résumé, les conteneurs offrent la possibilité d'"écrire une fois et de s'exécuter n'importe où". Une exception à cette règle est que le conteneur généré doit s'exécuter sur le type de processeur sur lequel vous l'avez créé. Toutefois, il existe également 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 appelée Docker pour créer un conteneur.

Dans l'éditeur Cloud, créez un fichier nommé Dockerfile. Ce fichier sert de plan pour construire votre image. Il indique à Docker votre environnement d'exploitation et votre code source, et explique comment installer vos dépendances, créer 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 l'image transférée vers le registre, un message SUCCESS contenant le nom de l'image s'affiche. Ce message 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.

Vous pouvez lister toutes les images de conteneurs associées à votre projet actuel à l'aide de la commande suivante:

gcloud container images list

Exécutez et testez maintenant l'application en local à partir de 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) de l'environnement hôte avec le même numéro de port à l'intérieur du conteneur en cours d'exécution. Cela vous facilite 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 sont identiques (8080). Toutefois, vous pouvez tout aussi facilement utiliser l'option -p pour mapper n'importe quel port externe arbitraire sur l'hôte à n'importe quel port interne souhaité à l'intérieur du conteneur.

L'option -e PORT=$PORT indique à Docker de rendre la variable d'environnement $PORT (définie sur 8080 ci-dessus) disponible pour l'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 "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 sembler familier : le texte généré doit s'afficher devant un arrière-plan de couleur aléatoire, comme vous l'avez fait lorsque vous avez exécuté l'application directement dans votre terminal Cloud Shell. Actualisez plusieurs fois la page pour constater que la couleur d'arrière-plan aléatoire change chaque fois que vous accédez à l'application.

Félicitations ! Vous venez d'exécuter une version conteneurisée de votre application. Dans la section suivante, sans toucher à une ligne de code, vous allez transformer votre image de conteneur en une application Web de qualité production.

5. Vers le cloud...

1b0665d94750ded6.gif

Maintenant que vous avez conteneurisé votre application, vous allez pouvoir partager ses avantages avec le reste du monde. Il est donc temps de la déployer dans le cloud. Mais vous aimeriez vraiment faire plus que simplement la partager. Vous voulez vous assurer qu'il:

  • s'exécute 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.
  • évolue automatiquement : votre application peut faire face à des niveaux de trafic importants et réduire automatiquement son encombrement lorsqu'elle n'est pas utilisée
  • réduit vos coûts en ne facturant pas les ressources que vous n'utilisez pas (vous ne payez que pour les ressources consommées lors de la réponse au trafic)
  • est accessible via un nom de domaine personnalisé. Vous avez ainsi accès à 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 affiner ce paramètre en spécifiant une configuration minimale d'instance.
  • est compatible avec le chiffrement de bout en bout à l'aide de la sécurité Web standard SSL/TLS : lorsque vous déployez un service, vous bénéficiez du chiffrement Web standard et des certificats correspondants requis sans frais et automatiquement.

En déployant votre application sur Google Cloud Run, vous bénéficiez de tout ce qui précède et de bien d'autres.

Déployer votre application dans Cloud Run

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

def say_hello(name="world"):

par:

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 boîte de dialogue ci-dessus, vous avez défini une région par défaut via la variable d'environnement REGION.

Recréez votre image de conteneur et déployez votre application conteneurisée sur 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 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 obtenue dans Google Container Registry, le service Cloud Run peut la rechercher 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)"

Le résultat devrait ressembler à ceci:

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

Ce lien est une URL dédiée, avec la sécurité TLS, à votre service Cloud Run. Ce lien est permanent (tant que vous ne désactivez pas votre service) et peut être utilisé partout sur Internet. Il n'utilise pas le mécanisme de proxy de Cloud Shell mentionné précédemment, qui dépend d'une machine virtuelle temporaire.

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

Félicitations ! Votre application s'exécute désormais dans Google Cloud. Sans que vous ayez à vous en préoccuper, votre application est accessible au public, avec le chiffrement TLS (HTTPS) et un scaling automatique jusqu'à des niveaux de trafic époustouflants.

Mais je pense que ce processus pourrait être encore plus facile...

6. Créer le conteneur automatiquement

C'est plutôt cool, mais que faire si je ne veux même pas penser aux Dockerfiles et aux conteneurs ? Et si, comme la plupart des développeurs, je voulais simplement me concentrer sur l'écriture du code de mon application et laisser quelqu'un d'autre s'occuper de sa conteneurisation. Vous avez de la chance, car Cloud Run est compatible avec une norme Open Source appelée Buildpacks, qui existe pour la même raison: automatiser le processus de fabrication d'un conteneur à partir d'un ensemble de fichiers sources.

Notez que dans certains cas, un développeur peut préférer utiliser un Dockerfile explicite, par exemple s'il souhaite bénéficier d'un haut niveau de personnalisation dans la création de son conteneur. Toutefois, pour des cas courants comme cet exercice, les buildpacks fonctionnent bien et évitent d'avoir à créer manuellement un Dockerfile. Modifions à présent votre code pour utiliser des buildpacks.

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

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

par:

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

Utilisons maintenant les buildpacks pour créer 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 de compilation comment exécuter votre application dans le conteneur généré automatiquement. Avec ces instructions, vous n'avez même plus besoin d'un Dockerfile. Pour vérifier cela, supprimez votre 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 à la commande 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 (dot dans --source . est un raccourci pour le répertoire actuel). Comme le service gère implicitement l'image de conteneur, vous n'avez pas besoin de spécifier une image dans cette commande gcloud.

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

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

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

7. Dois-je utiliser la ligne de commande ?

Non ! Comme 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 voir.
  • Interface utilisateur Web enrichie, accessible via la console Cloud, compatible avec un style d'interaction de type "pointer-cliquer" intuitif.
  • Par programmation, en utilisant les bibliothèques clientes Google disponibles pour de nombreux langages courants, y compris Java, C#, Python, Go, JavaScript, Ruby, C/C++, etc.

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

Un résumé de vos services Cloud Run devrait alors s'afficher, comme ceci:

b335e7bf0a3af845.png

Cliquez sur "Créer un service" pour lancer le processus de déploiement:

51f61a8ddc7a4c0b.png

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

8a17baa45336c4c9.png

Saisissez cette URL pour l'image de conteneur: gcr.io/cloudrun/hello (un conteneur conçu par Google à des fins de test), puis cliquez sur "Paramètres avancés" pour voir quelques-uns des nombreux paramètres de configuration disponibles. Pour n'en citer que quelques-uns que vous pouvez personnaliser:

  • numéro de port et 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 et
  • Autres: paramètre du délai avant expiration de la requête, nombre maximal de requêtes par conteneur, HTTP/2

Cliquez sur "Suivant" pour faire avancer la boîte de dialogue. La boîte de dialogue suivante vous permet de spécifier le mode de déclenchement du service. Dans "Entrée", 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 libres, 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 définir des paramètres plus restrictifs pour votre application, mais restons simples pour cet exercice d'apprentissage.

Cliquez 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 indique le déploiement le plus récent (date/heure et par qui) ainsi que certains paramètres de configuration clés. Cliquez sur le lien du nom du service pour afficher les détails de 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 nouveau service Cloud Run, sélectionnez l'onglet REVISIONS pour découvrir comment 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 la capture d'écran de l'exemple ci-dessous:

a599fa88d00d6776.png

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

5fd1b1f8e1f11d40.png

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

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

folder , comme ceci:

8a756c6157face3a.png

Une fois la sélection effectuée, faites défiler la page jusqu'en bas, puis cliquez sur le bouton DEPLOY. Vous venez de déployer une nouvelle révision de votre application. Pour vous en assurer, accédez de nouveau à l'URL de votre service et vérifiez que le message coloré "Hello from Cloud Run with Buildpacks!" s'affiche. de votre application Web.

Comme vous pouvez le voir, l'onglet "Revisions" (Révisions) fournit un résumé de chaque révision déployée. Vous devriez maintenant voir deux révisions pour ce service. Vous pouvez sélectionner une révision donnée en cliquant sur la case d'option située à gauche de son nom. Un récapitulatif des détails de la révision s'affiche alors sur le côté droit de l'écran. En sélectionnant ces boutons, vous pouvez voir que vos deux révisions sont dérivées 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 possibilité d'ajuster le volume de trafic envoyé à une révision donnée présente plusieurs cas d'utilisation intéressants:

  • test Canary d'une nouvelle version de votre application sur une petite partie du trafic entrant
  • rétablir le trafic d'une version problématique vers une révision précédente
  • Tests A/B

Vous trouverez le bouton MANAGE TRAFFIC ici:

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 ceci:

8c37d4f115d9ded4.png

Cliquez sur le bouton ENREGISTRER, puis vérifiez la répartition 50/50 en accédant plusieurs fois à l'URL de votre service. Vérifiez qu'en moyenne, la moitié de vos requêtes sont diffusé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!").

D'autres onglets de la page "Détails du service" permettent de surveiller les performances, le trafic et les journaux. Ils fournissent des informations précieuses sur l'efficacité et l'efficacité de votre service. Vous avez également la possibilité d'affiner l'accès à votre service via la section "Autorisations" . Prenez quelques instants pour explorer les onglets de cette page afin de vous faire une idée des fonctionnalités disponibles.

Interface programmatique

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

8. Tester votre application

198ada162d1f0bf1.png

Au cours de cette dernière étape, vous allez exécuter un test de charge artificielle pour tester votre application et observer comment elle évolue en fonction de la demande entrante. Vous allez utiliser un outil nommé hey, préinstallé dans Cloud Shell, 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 la commande suivante 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 réduire la charge à environ 1 000 requêtes par seconde.
  • -c 200 : alloue 200 nœuds de calcul parallèles.
  • -z 30s : exécute le test de charge pendant 30 secondes
  • assurez-vous d'utiliser l'URL de votre service comme dernier argument de cette ligne de commande.

Les résultats de votre test doivent se présenter comme suit:

 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écapitulatif nous indique plusieurs éléments intéressants:

  • 32 918 demandes ont été envoyées à environ 1 000/seconde pendant 30 secondes.
  • Aucune erreur ne s'est produite (200 réponses HTTP seulement).
  • La latence moyenne était de 180 ms.
  • La latence minimale était de 107 ms, et dans le pire des cas de 3,3 s
  • La latence du 90e centile était de 244 ms.

Si vous consultez l'onglet METRICS de la console Cloud Run, vous pouvez voir la partie 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.

Vous pouvez soit supprimer votre projet GCP pour éviter que des frais ne vous soient facturés, ce qui interrompra la facturation de toutes les ressources utilisées dans ce projet, ou supprimer simplement votre image de conteneur à l'aide de 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 venez de créer et de déployer une application de production Cloud Run. Par la même occasion, vous avez découvert les conteneurs et appris à créer votre propre conteneur. Vous avez également 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 désormais comment partager vos excellentes créations avec le monde entier !

Je voudrais vous poser une question importante:

Une fois que votre application fonctionne 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 niveau production proposés par Cloud Run ?

Bien entendu, la réponse est 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 êtes susceptible de passer plus de temps à vous familiariser avec Google Cloud, rejoignez le programme Google Cloud Innovators dès aujourd'hui !

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

Le programme Google Cloud Innovators est sans frais et inclut:

  • Discussions, sessions AMA et sessions sur la feuille de route en direct 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 la visioconférence
  • 500 crédits d'ateliers et de formations sur Skills Boost

Cliquez ici pour vous inscrire.