Migrer de l'application Java Google App Engine vers Cloud Run avec Jib

1. Présentation

Cette série d'ateliers de programmation (tutoriels pratiques et d'auto-formation) vise à aider les développeurs Java sur Google App Engine (standard) à moderniser leurs applications en les guidant lors d'une série de migrations. En suivant ces étapes, vous pouvez mettre à jour votre application afin de la rendre plus portable, et décider de la conteneuriser pour Cloud Run, le service partenaire d'hébergement de conteneurs de Google Cloud vers App Engine, ainsi que pour d'autres services d'hébergement de conteneurs.

Ce tutoriel vous explique comment conteneuriser une application App Engine pour la déployer sur le service entièrement géré Cloud Run à l'aide de Jib. Avec Jib, vous pouvez créer des images Docker, une plate-forme bien connue dans le secteur pour le développement, le transport et l'exécution d'applications dans des conteneurs.

En plus de vous apprendre à passer d'App Engine à Cloud Run, vous apprendrez à mettre à niveau une application App Engine Java 8 vers Java 17.

Si votre application fait une utilisation intensive des anciens services groupés App Engine ou d'autres fonctionnalités App Engine, nous vous recommandons de supprimer ces services groupés ou de remplacer ces fonctionnalités avant de passer à Cloud Run. Si vous avez besoin de plus de temps pour étudier vos options de migration ou si vous souhaitez continuer à utiliser les anciens services groupés pour le moment, vous pouvez continuer à accéder aux services groupés App Engine pour Java 11/17 lors de la mise à niveau vers un environnement d'exécution plus récent. Lorsque votre application sera plus portable, revenez à cet atelier de programmation pour découvrir comment appliquer les instructions à votre application.

Vous apprendrez à

  • Utiliser Cloud Shell
  • Activer les API Cloud Run, Artifact Registry et Cloud Build
  • Conteneuriser votre application à l'aide de Jib et de Cloud Build
  • Déployer vos images de conteneurs dans Cloud Run

Prérequis

Enquête

Comment allez-vous utiliser ce tutoriel ?

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

Comment évalueriez-vous votre expérience avec Java ?

Débutant Intermédiaire Expert

Quel est votre niveau d'expérience avec les services Google Cloud ?

Débutant Intermédiaire Expert

2. Contexte

Les systèmes PaaS (Platform as a Service) tels qu'App Engine et Cloud Functions offrent de nombreux avantages à votre équipe et à votre application. Par exemple, ils permettent aux administrateurs système et aux DevOps de se concentrer sur la création de solutions. Avec les plates-formes sans serveur, votre application peut évoluer automatiquement à la hausse si nécessaire, effectuer un scaling à la baisse jusqu'à zéro avec la facturation à l'utilisation pour vous aider à maîtriser les coûts, et utiliser divers langages de développement courants.

Cependant, la flexibilité des conteneurs est également convaincante. Grâce à la possibilité de choisir n'importe quel langage, bibliothèque et binaire, les conteneurs vous offrent le meilleur des deux mondes: la commodité de l'informatique sans serveur et la flexibilité des conteneurs. C'est à cela que sert Cloud Run.

L'apprentissage de l'utilisation de Cloud Run n'entre pas dans le cadre de cet atelier de programmation. abordés dans la documentation Cloud Run. L'objectif est de vous familiariser avec la conteneurisation de votre application App Engine pour Cloud Run (ou d'autres services hébergés par des conteneurs). Avant de continuer, vous devez prendre connaissance de quelques informations : votre expérience utilisateur sera légèrement différente.

Dans cet atelier de programmation, vous apprendrez à créer et à déployer des conteneurs. Vous allez apprendre à effectuer les opérations suivantes :

  • Conteneuriser votre application avec Jib
  • Abandon de la configuration App Engine
  • et, éventuellement, définir des étapes de compilation pour Cloud Build.

Cela implique d'abandonner certaines fonctionnalités spécifiques à App Engine. Si vous préférez ne pas suivre cette procédure, vous pouvez toujours passer à un environnement d'exécution Java 11/17 tout en conservant vos applications sur App Engine.

3. Configuration/Préparation

1. Configurer le projet

Pour ce tutoriel, vous allez utiliser un exemple d'application du dépôt appengine-java-migration-samples sur un tout nouveau projet. Assurez-vous que le projet dispose d'un compte de facturation actif.

Si vous avez l'intention de déplacer une application App Engine existante vers Cloud Run, vous pouvez l'utiliser pour suivre la procédure.

Exécutez la commande suivante pour activer les API nécessaires pour votre projet:

gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com

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

Clonez l'application exemple sur votre propre machine ou dans Cloud Shell, puis accédez au dossier baseline.

Cet exemple est une application de datastore Java 8 basée sur des servlets et conçue pour être déployée sur App Engine. Suivez les instructions du fichier README pour préparer cette application pour le déploiement d'App Engine.

3. (Facultatif) Déployer une application de référence

Les étapes suivantes ne sont nécessaires que si vous souhaitez vérifier que l'application fonctionne sur App Engine avant la migration vers Cloud Run.

Reportez-vous aux étapes décrites dans le fichier README.md:

  1. Installer/Se familiariser avec la CLI gcloud
  2. Initialiser la gcloud CLI pour votre projet avec gcloud init
  3. Créer le projet App Engine avec gcloud app create
  4. Déployer l'exemple d'application sur App Engine
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
  1. Vérifier que l'application s'exécute sans problème sur App Engine

4. Créer un dépôt Artifact Registry

Après avoir conteneurisé votre application, vous aurez besoin d'un emplacement pour transférer et stocker vos images. Pour ce faire, nous vous recommandons d'utiliser Artifact Registry sur Google Cloud.

Créez le dépôt nommé migration avec gcloud comme suit:

gcloud artifacts repositories create migration --repository-format=docker \
--description="Docker repository for the migrated app" \
--location="northamerica-northeast1"

Notez que ce dépôt utilise le type de format docker, mais qu'il existe plusieurs types de dépôts.

À ce stade, vous disposez de votre application App Engine de référence et votre projet Google Cloud est prêt à la migrer vers Cloud Run.

4. Modifier les fichiers de l'application

Si votre application fait une utilisation intensive des anciens services groupés, de la configuration ou d'autres fonctionnalités spécifiques à App Engine d'App Engine, nous vous recommandons de continuer à accéder à ces services pendant la mise à niveau vers le nouvel environnement d'exécution. Cet atelier de programmation présente un chemin de migration pour les applications qui utilisent déjà des services autonomes, ou qui peuvent être refactorisées pour le faire.

1. Mettre à niveau vers Java 17

Si votre application fonctionne avec Java 8, envisagez de passer à une version LTS ultérieure (version 11 ou 17, par exemple) pour vous tenir informé des mises à jour de sécurité et accéder aux nouvelles fonctionnalités du langage.

Commencez par mettre à jour les propriétés de votre pom.xml pour inclure les éléments suivants:

<properties>
    <java.version>17</java.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
</properties>

La version du projet sera alors définie sur 17, le plug-in de compilation vous indiquera que vous souhaitez accéder aux fonctionnalités du langage Java 17 et que les classes compilées doivent être compatibles avec la JVM Java 17.

2. Inclure un serveur Web

Il existe un certain nombre de différences entre App Engine et Cloud Run qu'il convient de prendre en compte avant de passer de l'une à l'autre. La différence réside dans le fait que si l'environnement d'exécution Java 8 d'App Engine fournissait et gérait un serveur Jetty pour les applications qu'il hébergeait, ce n'est pas le cas de Cloud Run. Nous utiliserons Spring Boot pour nous fournir un serveur Web et un conteneur de servlet.

Ajoutez les dépendances suivantes :

<dependencies>
<!-- ... -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
       <version>2.6.6</version>
       <exclusions>
           <!-- Exclude the Tomcat dependency -->
           <exclusion>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-tomcat</artifactId>
           </exclusion>
       </exclusions>
   </dependency>
   <!-- Use Jetty instead -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-jetty</artifactId>
       <version>2.6.6</version>
   </dependency>
<!-- ... -->
</dependencies>

Spring Boot intègre un serveur Tomcat par défaut, mais cet exemple exclut cet artefact et s'en tient à Jetty afin de minimiser les différences de comportement par défaut après la migration. Nous pouvons également configurer la version de Jetty pour qu'elle corresponde à celle fournie par App Engine par défaut.

<properties>
    <java.version>17</java.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <jetty.version>9.4.46.v20220331</jetty.version>
</properties>

3. Configuration de Spring Boot

Bien que Spring Boot puisse réutiliser vos servlets sans les modifier, une certaine configuration est nécessaire pour améliorer la visibilité.

Créez la classe MigratedServletApplication.java suivante dans le package com.example.appengine:

package com.example.appengine;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@ServletComponentScan
@SpringBootApplication
@EnableAutoConfiguration
public class MigratedServletApplication {
    public static void main(String[] args) {
        SpringApplication.run(MigratedServletApplication.class, args);
    }
}

Notez que cela inclut l'annotation @ServletComponentScan, qui recherchera tous les @WebServlets (dans le package actuel par défaut) et les rendra disponibles comme prévu.

4. Empaqueter l'application en tant que fichier JAR

Bien qu'il soit possible de conteneuriser votre application avec Jib à partir d'une guerre, il est plus facile de l'empaqueter dans un fichier JAR exécutable. Cela ne nécessitera pas beaucoup de configuration, en particulier pour les projets utilisant Maven comme outil de compilation, car le packaging JAR est le comportement par défaut.

Supprimez la balise packaging dans le fichier pom.xml:

<packaging>war</packaging>

Ensuite, ajoutez spring-boot-maven-plugin:

<plugins>
<!-- ... -->
  <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>2.6.6</version>
  </plugin>
<!-- ... -->
</plugins>

5. Abandon de la configuration, des services et des dépendances App Engine

Comme indiqué au début de l'atelier de programmation, Cloud Run et App Engine sont conçus pour offrir des expériences utilisateur différentes. Certaines fonctionnalités prêtes à l'emploi d'App Engine, telles que les services Cron et Task Queue, doivent être recréées manuellement. Elles seront abordées plus en détail dans les modules suivants.

L'application exemple n'utilise pas les anciens services groupés. Toutefois, les utilisateurs dont les applications le font peuvent consulter les guides suivants:

Étant donné que vous allez désormais déployer sur Cloud Run, appengine-maven-plugin peut être supprimé:

<plugin>
 <groupId>com.google.cloud.tools</groupId>
 <artifactId>appengine-maven-plugin</artifactId>
 <version>2.4.1</version>
 <configuration>
   <!-- can be set w/ -DprojectId=myProjectId on command line -->
   <projectId>${app.projectId}</projectId>
   <!-- set the GAE version or use "GCLOUD_CONFIG" for an autogenerated GAE version -->
   <version>GCLOUD_CONFIG</version>
 </configuration>
</plugin>

5. Conteneuriser l'application

À ce stade, vous pouvez déployer manuellement votre application sur Cloud Run directement à partir de votre code source. Il s'agit d'une excellente option qui utilise Cloud Build en arrière-plan pour fournir une expérience de déploiement simplissime. Nous aborderons les déploiements sources plus en détail dans les modules suivants.

Si vous avez besoin de plus de contrôle sur le déploiement de votre application, vous pouvez également définir un fichier cloudbuild.yaml qui définit explicitement les étapes de compilation que vous souhaitez effectuer:

1. Définir un fichier cloudbuild.yaml

Créez le fichier cloudbuild.yaml suivant au même niveau que pom.xml:

steps:
  # Test your build
  - name: maven:eclipse-temurin
    entrypoint: mvn
    args: ["test"]
  # Build with Jib
  - name: maven:eclipse-temurin
    entrypoint: mvn
    args: [ "compile", "com.google.cloud.tools:jib-maven-plugin:3.2.1:build", "-Dimage=northamerica-northeast1-docker.pkg.dev/PROJECT_ID/migration/visitors:jib"]
  # Deploy to Cloud Run
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: gcloud
    args: [ 'run', 'deploy', 'visitors', '--image', 'northamerica-northeast1-docker.pkg.dev/PROJECT_ID/migration/visitors:jib', '--region', 'northamerica-northeast1', '--allow-unauthenticated']

Une fois que nous avons indiqué à Cloud Build de suivre ces étapes, il:

  1. Exécuter vos tests avec ./mvnw test
  2. Créer votre image, la transférer et lui ajouter des tags dans Artifact Registry avec Jib
  3. Déployer l'image dans Cloud Run avec gcloud run deploy

Notez que ‘visitors' est fourni à Cloud Run comme nom de service souhaité. L'option –allow-unauthenticated permet aux utilisateurs d'accéder à l'application Web sans exiger d'authentification. Veillez à remplacer PROJECT_ID par l'ID de votre projet dans le fichier cloudbuild.yaml .

Ajoutez ensuite les liaisons de stratégie IAM suivantes pour autoriser le compte de service Cloud Build à accéder à Artifact Registry:

export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)" )

gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
--role=roles/run.admin \
--project=$PROJECT_ID
gcloud iam service-accounts add-iam-policy-binding $PROJECT_NUMBER-compute@developer.gserviceaccount.com \
--member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
--role roles/iam.serviceAccountUser --project=$PROJECT_ID

2. Exécuter le processus de compilation

Maintenant que vous avez indiqué à Cloud Build les étapes de compilation souhaitées, vous êtes prêt pour un déploiement en un clic.

Exécutez la commande suivante :

gcloud builds submit

Une fois le processus terminé, votre image de conteneur a été créée, stockée dans Artifact Registry et déployée dans Cloud Run.

À la fin de cet atelier de programmation, votre application devrait ressembler à celle de java17-and-cloud-run/finish.

Et voilà ! Vous avez migré avec succès une application App Engine Java 8 vers Java 17 et Cloud Run. Vous comprenez désormais mieux le travail à effectuer pour changer d'application et choisir entre différentes options d'hébergement.

6. Résumé/Nettoyage

Félicitations ! Vous venez de mettre à niveau, de conteneuriser et de migrer votre application. C'est la fin de ce tutoriel !

À partir de là, l'étape suivante consiste à en apprendre davantage sur les fonctionnalités de sécurité CI/CD et de la chaîne d'approvisionnement logicielle disponibles maintenant et que vous pouvez déployer avec Cloud Build:

Facultatif: Nettoyer et/ou désactiver le service

Si vous avez déployé l'exemple d'application sur App Engine au cours de ce tutoriel, n'oubliez pas de désactiver l'application afin d'éviter que des frais ne vous soient facturés. Lorsque vous serez prêt à passer à l'atelier de programmation suivant, vous pourrez le réactiver. Lorsque les applications App Engine sont désactivées, elles n'enregistrent aucun trafic et ne génèrent pas de frais. Toutefois, l'utilisation de Datastore peut être facturable si elle dépasse son quota sans frais. Vous devez donc supprimer suffisamment de données pour passer sous cette limite.

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

7. Ressources supplémentaires

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 pour la migration

Ressources en ligne

Vous trouverez ci-dessous des ressources en ligne qui peuvent vous être utiles pour ce tutoriel:

App Engine

Autres informations sur le cloud

Vidéos

Licence

Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.