Module 4 : Migrer depuis Google App Engine vers Cloud Run avec Docker

Cette suite d'ateliers de programmation (tutoriels pratiques à suivre à votre rythme) est destinée à aider les développeurs Google App Engine (standard) à moderniser leurs applications en les guidant tout au long d'une série de migrations. Une fois l'opération effectuée, les utilisateurs peuvent rendre leurs applications plus portables en les conteneurisant pour Cloud Run, le service d'hébergement de conteneurs de Google Cloud étroitement lié à App Engine, ainsi que pour d'autres services d'hébergement de conteneurs.

Ce tutoriel explique comment conteneuriser des applications App Engine afin de les déployer sur le service entièrement géré Cloud Run en utilisant Docker, une plate-forme bien connue du secteur pour le développement, l'hébergement et l'exécution d'applications en conteneur. Pour les développeurs Python 2, le code de départ ("START") de ce tutoriel est l'exemple d'application Cloud NDB App Engine du module 2. Pour les développeurs Python 3, le code de départ ("START") de ce tutoriel est l'exemple d'application Cloud Datastore du module 3.

Vous apprendrez à effectuer les tâches suivantes :

  • Conteneuriser votre application à l'aide de Docker.
  • Déployer des images de conteneur dans Cloud Run.

Prérequis

Enquête

Comment allez-vous utiliser cet atelier de programmation ?

Je vais le lire uniquement Je vais le lire et effectuer les exercices

Les systèmes PaaS tels qu'App Engine et Cloud Functions offrent de nombreux avantages pour vos équipes et vos applications. Par exemple, ces plates-formes sans serveur permettent aux équipes SysAdmin/Devops de se concentrer sur la création de solutions. Votre application peut être rédigée dans de nombreux langages de développement courants et évoluer automatiquement en fonction de vos besoins, voire même jusqu'à s'interrompre entièrement pour ne plus générer aucuns frais avec la facturation à l'utilisation.

La flexibilité des conteneurs est un autre atout majeur avec la capacité d'utiliser n'importe quel langage, n'importe quelle bibliothèque et n'importe quels binaires. Découvrez Google Cloud Run pour offrir aux utilisateurs le meilleur des deux mondes, les avantages de la technologie sans serveur et la flexibilité des conteneurs.

Apprendre à utiliser Cloud Run dépasse le cadre du présent atelier de programmation. Pour cela, consultez la documentation de Cloud Run. L'objectif ici est de vous indiquer comment conteneuriser votre application App Engine pour Cloud Run (ou d'autres services). Avant de continuer, vous devez comprendre que votre expérience utilisateur sera légèrement différente. Effectivement, le travail se fait à un niveau plus bas et il n'est plus nécessaire de manipuler et de déployer le code d'application.

Au lieu de cela, vous devez apprendre à mieux connaître les conteneurs, notamment la compilation et le déploiement. Vous devez également décider des éléments à inclure dans l'image de conteneur, y compris un serveur Web car vous n'utiliserez plus le serveur Web d'App Engine. Si vous ne souhaitez pas fonctionner de cette manière, conserver vos applications sur App Engine n'est pas un mauvais choix.

Dans ce tutoriel, vous allez apprendre à conteneuriser votre application, à remplacer les fichiers de configuration App Engine par la configuration de conteneur, à déterminer ce qui doit figurer ou non dans votre conteneur et à spécifier comment démarrer votre application (la plupart de ces tâches sont gérées automatiquement par App Engine).

La migration comprend les étapes suivantes :

  1. Configuration/Préparation
  2. Conteneuriser l'application
    • Remplacer les fichiers de configuration
    • Modifier les fichiers d'application

Avant de passer à la partie principale de ce tutoriel, nous allons configurer notre projet, obtenir le code et déployer l'application de base pour nous assurer de bien utiliser du code fonctionnel.

1. Configurer le projet

Si vous avez suivi les ateliers de programmation Module 2 ou Module 3, nous vous recommandons de réutiliser le même projet et le même code. Vous pouvez également créer un projet ou réutiliser un autre projet existant. Assurez-vous que le projet dispose d'un compte de facturation actif et que App Engine (app) est activé.

2. Obtenir un exemple d'application de référence

L'une des conditions préalables à cet atelier de programmation est de disposer d'un exemple d'application fonctionnel du Module 2 ou du Module 3. Si vous n'en avez pas, suivez l'un de ces tutoriels (liens ci-dessus) avant de continuer. Si vous connaissez déjà le contenu de ces tutoriels, vous pouvez récupérer le code du module 2 ou du module 3 ci-dessous.

Que vous utilisiez votre application ou la nôtre, le code de départ ("START") est celui du module 2 pour la version Python 2 du présent tutoriel ou le code du module 3 pour la version Python 3. Le présent atelier de programmation du module 4 vous guide pour chaque étape jusqu'à obtenir, selon les options choisies, un code similaire au code final du dépôt du module 4 ("FINISH").

Pour Python 2, le répertoire de départ (votre code ou notre code) doit ressembler à ce qui suit :

$ ls
README.md               appengine_config.py     requirements.txt
app.yaml                main.py                 templates

Si vous utilisez votre propre code du module 2 (2.x), vous verrez également un dossier lib. Ni lib, ni appengine_config.py ne sont utilisés pour Python 3. Le répertoire de départ pour le module 3 (3.x) doit ressembler à ce qui suit :

$ ls
README.md               main.py                 templates
app.yaml                requirements.txt

3. (Re)Déployer l'application de référence

Étapes préliminaires restantes :

  1. Familiarisez-vous avec l'outil de ligne de commande gcloud
  2. Redéployez l'exemple d'application avec gcloud app deploy
  3. Vérifier que l'application s'exécute sans problème sur App Engine

Une fois ces étapes effectuées, vous êtes prêt à conteneuriser l'application.

Docker est aujourd'hui la plate-forme de conteneurisation standard dans le secteur. Comme indiqué précédemment, l'un des défis de l'utilisation de Docker est qu'il faut faire beaucoup d'efforts pour créer et entretenir un bon Dockerfile (le fichier de configuration qui détermine la façon dont vos images de conteneurs sont créées). En revanche, les packs de création nécessitent peu d'efforts car ils utilisent l'introspection pour déterminer les dépendances de votre application et optimiser le conteneur au mieux pour votre application.

Si vous connaissez déjà un peu Docker et les conteneurs mais que vous souhaitez en savoir plus sur la conteneurisation de votre application App Engine pour Cloud Run, vous êtes au bon endroit. N'hésitez pas à suivre également l'atelier de programmation du module 5 (identique à celui-ci mais avec les packs de création Google Cloud). Notre exemple d'application est très simple et suffisamment léger pour éviter certains des problèmes de Dockerfile mentionnés ci-dessus.

La procédure de migration comprend le remplacement des fichiers de configuration App Engine et la spécification de démarrage de votre application. Le tableau ci-dessous récapitule les fichiers de configuration requis pour chaque type de plate-forme. Comparez la colonne App Engine à la colonne Docker (et éventuellement à la colonne des packs de création Google Cloud) :

Description

App Engine

Docker

Buildpacks

Configuration générale

app.yaml

Dockerfile

(service.yaml)

Bibliothèques tierces

requirements.txt

requirements.txt

requirements.txt

Configuration tierce

app.yaml (plus appengine_config.py et lib [2.x uniquement])

(n/a)

(n/a)

Démarrage

(n/a) ou app.yaml (si entrypoint est utilisé)

Dockerfile

Procfile

Ignorer les fichiers

.gcloudignore et .gitignore

.gcloudignore, .gitignore et .dockerignore

.gcloudignore et .gitignore

Une fois votre application en conteneur, elle peut être déployée dans Cloud Run. Parmi les autres options de plate-forme de conteneur Google Cloud figurent Compute Engine, GKE et Anthos.

Configuration générale

La migration depuis App Engine consiste à remplacer le fichier app.yaml par un fichier Dockerfile qui explique comment créer et exécuter le conteneur. App Engine démarre automatiquement votre application mais ce n'est pas le cas de Cloud Run. Cela correspond aux commandes Dockerfile, ENTRYPOINT et CMD. Pour en savoir plus sur Dockerfile, consultez cette page de documentation de Cloud Run et découvrez un exemple de fichier Dockerfile qui démarre gunicorn.

Plutôt que d'utiliser ENTRYPOINT ou CMD dans un fichier Dockerfile, vous pouvez utiliser Procfile. Enfin, un fichier .dockerignore permet de filtrer les fichiers non-essentiels à l'application pour limiter la taille de votre conteneur. Vous en saurez plus prochainement.

Supprimer le fichier app.yaml et créer un fichier Dockerfile

Le fichier app.yaml n'étant pas utilisé dans les conteneurs, supprimez-le dès maintenant. Le fichier de configuration du conteneur est le fichier Dockerfile, et notre exemple d'application ne requiert qu'un fichier très simple. Créez le fichier Dockerfile avec ce contenu, en remplaçant NNN par 2 ou 3 en fonction de la version de Python que vous utilisez :

FROM python:NNN-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
ENTRYPOINT ["python", "main.py"]

La plupart des fichiers Dockerfile spécifient comment créer le conteneur à l'exception de ENTRYPOINT qui indique comment démarrer le conteneur, dans le cas présent en appelant python main.py pour démarrer le serveur de développement Flask. Si vous débutez avec Docker, l'instruction FROM indique l'image de base utilisée pour démarrer et "slim" fait référence à une distribution Python minimale. Pour en savoir plus, consultez la page Images Python pour Docker.

L'ensemble de commandes intermédiaire crée le répertoire de travail (/app), copie les fichiers d'application, puis exécute pip install pour intégrer les bibliothèques tierces dans le conteneur. WORKDIR combine les commandes Linux mkdir et cd. Pour en savoir plus, consultez la documentation de WORKDIR. Les instructions COPY et RUN sont explicites.

Bibliothèques tierces

Le fichier requirements.txt peut rester identique. Flask doit y être présent avec votre bibliothèque cliente Datastore (Cloud Datastore ou Cloud NDB). Si vous souhaitez utiliser un autre serveur HTTP compatible WSGI tel que Gunicorn (la version à jour au moment de la rédaction de cet article est la 20.0.4), ajoutez gunicorn==20.0.4 au fichier requirements.txt.

Configuration tierce

Les développeurs App Engine Python 2 savent que les bibliothèques tierces sont copiées dans le dossier lib, référencées dans requirements.txt ou classées dans app.yaml et qu'elles sont compatibles avec appengine_config.py. Comme les conteneurs tels que les applications App Engine Python 3 n'utilisent que le fichier requirements.txt, tous les autres éléments peuvent être supprimés. Si vous avez une application App Engine 2.x, supprimez dès maintenant appengine_config.py et tout dossier lib.

Démarrage

Bien que les utilisateurs de Python 2 n'aient pas l'habitude de démarrer le serveur Web d'App Engine, cela s'avère nécessaire pour utiliser un conteneur. Pour ce faire, ajoutez une directive CMD ou ENTRYPOINT dans votre fichier Dockerfile en spécifiant comment démarrer votre application (la version de cette procédure pour les utilisateurs de Python 3 est présentée plus loin dans le présent article).

Les utilisateurs de Python 3 ont la possibilité de convertir leurs fichiers app.yaml de manière à utiliser un entrypoint plutôt que des directives script: auto dans leur section handlers. Si vous utilisez un entrypoint dans votre fichier app.yaml Python 3, il doit ressembler à ce qui suit :

runtime: python38
entrypoint: python main.py

L'instruction entrypoint indique à App Engine comment démarrer le serveur. Vous pouvez le déplacer presque directement dans votre Dockerfile (ou Procfile si vous utilisez des packs de création Google Cloud [voir le module 5] pour conteneuriser votre application). Pour résumer l'emplacement d'une instruction "entrypoint" entre les deux plates-formes :

  • Docker : ligne dans Dockerfile : ENTRYPOINT ["python", "main.py"]
  • Packs de création Google Cloud : ligne dans Procfile : web: python main.py

L'utilisation du serveur de développement Flask est parfaitement adaptée pour les tests mais si vous utilisez un serveur de production comme gunicorn pour votre application, veillez à faire pointer votre directive ENTRYPOINT ou CMD vers ce serveur comme dans l'exemple de démarrage rapide Cloud Run

Ignorer les fichiers

Nous vous recommandons de créer un fichier .dockerignore afin de réduire la taille de votre conteneur et de ne pas l'encombrer de fichiers superflus comme ceux-ci :

*.md
*.pyc
*.pyo
.git/
.gitignore
__pycache__

Dossiers d'application

Toutes les applications du module 2 et du module 3 sont entièrement compatibles avec Python 2 et 3, ce qui signifie qu'il n'y a pas de modification des composants de base du fichier main.py. Nous n'ajouterons que quelques lignes de code de démarrage. Ajoutez deux lignes en bas de main.py pour démarrer le serveur de développement car Cloud Run nécessite d'ouvrir le port 8080 pour pouvoir appeler votre application :

if __name__ == '__main__':
    import os
    app.run(debug=True, threaded=True, host='0.0.0.0',
            port=int(os.environ.get('PORT', 8080)))

Une fois les mises à jour de la configuration Docker et des fichiers sources, vous êtes prêt à exécuter votre conteneur sur Cloud Run. Mais avant cela, parlons brièvement des services.

Services ou applications

Bien qu'App Engine ait été créé principalement pour héberger des applications, il s'agit également d'une plate-forme permettant d'héberger des services Web ou des applications composées d'un ensemble de microservices. Dans Cloud Run, tout est un service, qu'il s'agisse d'un service réel ou d'une application dotée d'une interface Web. Nous vous recommandons donc de penser en termes de services plutôt qu'en termes d'applications.

À moins que votre application App Engine ne soit constituée de plusieurs services, vous n'avez pas à effectuer de dénomination particulière lors du déploiement de vos applications. Cela change dans Cloud Run, car vous devez trouver un nom de service. Le domaine appspot.com d'App Engine inclut l'ID de projet, par exemple https://PROJECT_ID.appspot.com, et parfois une abréviation de l'ID de région, par exemple http://PROJECT_ID.REGION_ID.r.appspot.com.

Le domaine d'un service Cloud Run inclut le nom du service, l'abréviation de région et une valeur de hachage, mais pas l'ID de projet, par exemple https://SVC_NAME-HASH-REG_ABBR.a.run.app. En résumé, commencez dès à présent à réfléchir à un nom de service !

Déployer le service

Exécutez la commande ci-dessous pour compiler votre image de conteneur et la déployer dans Cloud Run. Lorsque vous y êtes invité, sélectionnez votre région et autorisez les connexions non authentifiées pour faciliter les tests puis choisissez une région appropriée, où SVC_NAME est le nom du service que vous déployez.

$ gcloud beta run deploy SVC_NAME --source .
Please choose a target platform:
 [1] Cloud Run (fully managed)
 [2] Cloud Run for Anthos deployed on Google Cloud
 [3] Cloud Run for Anthos deployed on VMware
 [4] cancel
Please enter your numeric choice:  1

To specify the platform yourself, pass `--platform managed`. Or, to make this the default target platform, run `gcloud config set run/platform managed`.

Please specify a region:
 [1] asia-east1
 [2] asia-east2
 [3] asia-northeast1
 [4] asia-northeast2
 [5] asia-northeast3
 [6] asia-south1
 [7] asia-southeast1
 [8] asia-southeast2
 [9] australia-southeast1
 [10] europe-north1
 [11] europe-west1
 [12] europe-west2
 [13] europe-west3
 [14] europe-west4
 [15] europe-west6
 [16] northamerica-northeast1
 [17] southamerica-east1
 [18] us-central1
 [19] us-east1
 [20] us-east4
 [21] us-west1
 [22] us-west2
 [23] us-west3
 [24] us-west4
 [25] cancel
Please enter your numeric choice: <select your numeric region choice>

To make this the default region, run `gcloud config set run/region REGION`.

Allow unauthenticated invocations to [SVC_NAME] (y/N)?  y

Building using Dockerfile and deploying container to Cloud Run service [SVC_NAME] in project [PROJECT_ID] region [REGION]
✓ Building and deploying new service... Done.
  ✓ Uploading sources...
  ✓ Building Container... Logs are available at [https://console.cloud.google.com/cloud-build/builds/BUILD-HASH?project=PROJECT_NUM].
  ✓ Creating Revision... Deploying Revision.
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [SVC_NAME] revision [SVC_NAME-00001-vos] has been deployed and is serving 100 percent of traffic.
Service URL: https://SVC_NAME-HASH-REG_ABBR.a.run.app

Accédez à l'URL spécifiée avec votre navigateur pour vérifier que le déploiement a bien réussi.

Comme l'indique la commande gcloud, les utilisateurs peuvent définir divers paramètres par défaut pour réduire la sortie et l'interactivité, comme illustré ci-dessus. Par exemple, pour éviter toutes les interactions, vous pouvez utiliser la commande de déploiement en une ligne suivante :

$ gcloud beta run deploy SVC_NAME --source . --platform managed --region REGION --allow-unauthenticated

Si vous l'utilisez, assurez-vous d'utiliser le même nom de service SVC_NAME et le nom REGION souhaité plutôt que la sélection de menu indexée comme nous l'avons fait précédemment de manière interactive.

Vérifiez que l'application fonctionne aussi bien sur Cloud Run que dans App Engine. Si vous avez consulté cette série sans suivre les ateliers de programmation précédents, l'application elle-même ne change pas. Elle enregistre toutes les visites sur la page Web principale (/) et ressemble à ceci une fois que vous avez consulté le site suffisamment de fois :

Application Visitme

Votre code doit maintenant correspondre au contenu du dépôt du module 4, qu'il s'agisse d'une version 2.x ou 3.x. Bravo ! Vous avez terminé l'atelier de programmation du module 4.

Facultatif : Effectuer un nettoyage

Que diriez-vous d'un bon nettoyage pour éviter que des frais vous soient facturés tant que vous n'êtes pas prêt à passer à l'atelier de programmation suivant sur la migration ? Comme vous utilisez maintenant un autre produit, consultez la grille tarifaire de Cloud Run.

Facultatif : désactiver le service

Si vous n'êtes pas encore prêt à passer au tutoriel suivant, désactivez votre service pour éviter des frais supplémentaires. Lorsque vous serez prêt à passer au prochain atelier de programmation, vous pourrez le réactiver. Tant que votre application est désactivée, elle ne génère aucun trafic, donc aucuns frais. Toutefois, si vous dépassez le quota gratuit, votre utilisation de Datastore vous sera facturée alors supprimez suffisamment d'éléments pour rester dans la limite.

En revanche, si vous ne souhaitez pas poursuivre vos migrations et que vous souhaitez tout supprimer complètement, vous pouvez supprimer votre service ou arrêter le projet complètement.

Étapes suivantes

Félicitations ! Vous venez de conteneuriser votre application et ce tutoriel est désormais terminé. Vous pouvez maintenant découvrir comment faire la même chose avec les packs de création Google Cloud dans l'atelier de programmation du module 5 (lien ci-dessous), ou comment effectuer une autre migration App Engine :

  • Migrez vers Python 3 si ce n'est pas déjà fait. L'exemple d'application est déjà compatible 2.x et 3.x. La seule modification est que les utilisateurs Docker doivent mettre à jour leur fichier Dockerfile pour utiliser une image Python 3.
  • Module 5 : Migrer vers Cloud Run avec les packs de création Cloud
    • Conteneurisez votre application pour qu'elle s'exécute sur Cloud Run avec les packs de création Cloud.
    • Il n'est pas nécessaire de déjà connaître Docker, de conteneurs ou les Dockerfile.
    • Vous devez avoir déjà effectué la migration de votre application vers Python 3.
  • Module 7 : files d'attente d'envoi de tâches App Engine (obligatoire si vous utilisez des files d'attente de tâches d'envoi de tâches [push])
    • Ajoutez des tâches push taskqueue App Engine à l'application du module 1.
    • Préparez les utilisateurs à migrer vers Cloud Tasks dans le module 8.
  • Module 3 :
    • Modernisez l'accès au Datastore en passant de Cloud NDB à Cloud Datastore.
    • Il s'agit de la bibliothèque utilisée pour les applications Python 3 App Engine ou autres.
  • Module 6 : Migrer vers Cloud Firestore
    • Migrer vers Cloud Firestore pour utiliser les fonctionnalités de Firebase.
    • Bien que Cloud Firestore soit compatible avec Python 2, cet atelier de programmation n'est disponible que pour Python 3.

Problèmes/commentaires concernant le module de migration App Engine en atelier de programmation

Si vous rencontrez des problèmes avec cet atelier de programmation, commencez par faire une recherche avant de les signaler. Liens vers la recherche et la création d'un signalement :

Ressources de migration

Vous trouverez dans le tableau ci-dessous des liens vers les dossiers de dépôt correspondant aux modules 2 et 3 ("START") ainsi qu'au module 4 ("FINISH"). Vous pouvez également y accéder depuis le dépôt pour toutes les migrations d'ateliers de programmation App Engine que vous pouvez cloner ou télécharger sous forme de fichier ZIP.

Atelier de programmation

Python 2

Python 3

Module 2

code

(code)

Module 3

(code)

code

Module 4

code

code

Ressources App Engine et Cloud Run

Vous trouverez ci-dessous d'autres ressources concernant cette migration spécifique :