Von der Java-Anwendung von Google App Engine zu Cloud Run mit Docker migrieren

1. Übersicht

Diese Reihe von Codelabs (selbstgesteuerte, praktische Anleitungen) soll Google App Engine-Java-Entwicklern (Standard) helfen, ihre Apps zu modernisieren. Dazu werden sie durch eine Reihe von Migrationen geführt. Wenn Sie diese Schritte ausführen, können Sie Ihre App so aktualisieren, dass sie portabler ist. Außerdem können Sie sie für Cloud Run, den Container-Hosting-Dienst von Google Cloud, der App Engine ähnelt, und andere Container-Hosting-Dienste containerisieren.

In dieser Anleitung erfahren Sie, wie Sie eine App Engine-Anwendung für die Bereitstellung im vollständig verwalteten Cloud Run-Dienst mit einem Dockerfile containerisieren. Dockerfiles sind die praktischste Bereitstellungsmethode für diese Migration, bieten aber auch die meisten Optionen zum Anpassen des Build-Prozesses.

Sie erfahren nicht nur, welche Schritte erforderlich sind, um von App Engine zu Cloud Run zu migrieren, sondern auch, wie Sie eine Java 8-App Engine-Anwendung auf Java 17 aktualisieren.

Wenn die Anwendung, die Sie migrieren möchten, intensiv gebündelte App Engine-Legacy-Dienste oder andere App Engine-spezifische Funktionen nutzt, ist die Anleitung Auf gebündelte App Engine-Dienste für Java 11/17 zugreifen möglicherweise ein besserer Ausgangspunkt als dieses Codelab.

Lerninhalte

  • Cloud Shell verwenden
  • Cloud Run API, Artifact Registry API und Cloud Build API aktivieren
  • Anwendung mit Docker und Cloud Build containerisieren
  • Container-Images in Cloud Run bereitstellen

Voraussetzungen

Umfrage

Wie werden Sie diese Anleitung verwenden?

Nur lesen Lesen und Übungen durchführen

Wie würden Sie Ihre Erfahrung mit Java bewerten?

Anfänger Mittelstufe Fortgeschrittene

Wie würden Sie Ihre Erfahrungen mit Google Cloud-Diensten bewerten?

Anfänger Mittelstufe Fortgeschritten

2. Hintergrund

PaaS-Systeme wie App Engine und Cloud Functions bieten viele Vorteile für Ihr Team und Ihre Anwendung, z. B. können sich Systemadministratoren und DevOps auf die Entwicklung von Lösungen konzentrieren. Mit serverlosen Plattformen kann Ihre App bei Bedarf automatisch skaliert werden. Sie kann auch auf null skaliert werden, wobei die Abrechnung nach Nutzung erfolgt, um die Kosten im Blick zu behalten. Außerdem können Sie eine Vielzahl gängiger Entwicklungssprachen verwenden.

Die Flexibilität von Containern ist jedoch auch überzeugend. Da Sie jede Sprache, Bibliothek und jedes Binärprogramm auswählen können, bieten Container das Beste aus beiden Welten: den Komfort von Serverless und die Flexibilität von Containern. Genau darum geht es bei Google Cloud Run.

Die Verwendung von Cloud Run ist nicht Gegenstand dieses Codelabs. Informationen dazu finden Sie in der Cloud Run-Dokumentation. Ziel ist es, dass Sie sich damit vertraut machen, wie Sie Ihre App Engine-Anwendung für Cloud Run (oder andere containerbasierte Dienste) in einen Container packen. Bevor Sie fortfahren, sollten Sie einige Dinge wissen, vor allem, dass sich die Benutzeroberfläche leicht ändert.

In diesem Codelab erfahren Sie, wie Sie Container erstellen und bereitstellen. Sie erfahren, wie Sie Ihre Anwendung mit einem Dockerfile in einen Container packen, die App Engine-Konfiguration migrieren und optional Build-Schritte für Cloud Build definieren. Dazu müssen Sie bestimmte App Engine-spezifische Funktionen aufgeben. Wenn Sie diesen Weg nicht gehen möchten, können Sie stattdessen auch auf eine Java 11/17-Laufzeit aktualisieren und Ihre Apps in App Engine behalten.

3. Einrichtung/Vorbereitung

1. Projekt einrichten

Für diese Anleitung verwenden Sie eine Beispielanwendung aus dem Repository appengine-java-migration-samples in einem brandneuen Projekt. Prüfen Sie, ob das Projekt ein aktives Rechnungskonto hat.

Wenn Sie eine vorhandene App Engine-Anwendung zu Cloud Run migrieren möchten, können Sie diese Anwendung stattdessen verwenden.

Führen Sie den folgenden Befehl aus, um die erforderlichen APIs für Ihr Projekt zu aktivieren:

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

2. Beispiel-App für die Baseline herunterladen

Klonen Sie die Beispiel-App entweder auf Ihrem eigenen Computer oder in der Cloud Shell und rufen Sie dann den Ordner baseline auf.

Das Beispiel ist eine Servlet-basierte Datastore-Anwendung in Java 8, die für die Bereitstellung in App Engine vorgesehen ist. Folgen Sie der Anleitung in der README-Datei, um diese App für die App Engine-Bereitstellung vorzubereiten.

3. (Optional) Referenz-App bereitstellen

Das Folgende ist nur erforderlich, wenn Sie bestätigen möchten, dass die App in App Engine funktioniert, bevor wir zu Cloud Run migrieren.

Folgen Sie der Anleitung in der Datei README.md:

  1. gcloud-Befehlszeile installieren/sich damit vertraut machen
  2. Initialisieren Sie die gcloud CLI für Ihr Projekt mit gcloud init.
  3. Erstelle das App Engine-Projekt mit gcloud app create
  4. Beispielanwendung in App Engine bereitstellen
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
  1. Prüfen, ob die App problemlos auf App Engine ausgeführt wird

4. Artifact Registry-Repository erstellen

Nachdem Sie Ihre App in einen Container gepackt haben, benötigen Sie einen Ort, an dem Sie Ihre Images per Push übertragen und speichern können. Die empfohlene Methode hierfür in Google Cloud ist die Artifact Registry.

Erstellen Sie das Repository mit dem Namen migration mit gcloud:

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

In diesem Repository wird der Formattyp docker verwendet. Es sind jedoch mehrere Repository-Typen verfügbar.

An diesem Punkt haben Sie Ihre App Engine-Basisanwendung und Ihr Google Cloud-Projekt ist für die Migration zu Cloud Run vorbereitet.

4. Anwendungsdateien ändern

Wenn Ihre App die gebündelten Legacy-Dienste, die Konfiguration oder andere App Engine-Funktionen stark nutzt, empfehlen wir, weiter auf diese Dienste zuzugreifen, während Sie auf die neue Laufzeit aktualisieren. In diesem Codelab wird ein Migrationspfad für Anwendungen beschrieben, die bereits eigenständige Dienste verwenden oder die sich ohne Weiteres so umgestalten lassen.

1. Upgrade auf Java 17

Wenn Ihre App Java 8 verwendet, sollten Sie ein Upgrade auf einen späteren LTS-Kandidaten wie 11 oder 17 in Betracht ziehen, um Sicherheitsupdates zu erhalten und auf neue Sprachfunktionen zugreifen zu können.

Aktualisieren Sie zuerst die Attribute in Ihrem pom.xml und fügen Sie Folgendes hinzu:

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

Dadurch wird die Projektversion auf 17 festgelegt, das Compiler-Plug-in wird darüber informiert, dass Sie auf die Sprachfunktionen von Java 17 zugreifen möchten, und die kompilierten Klassen sollen mit der Java 17-JVM kompatibel sein.

2. Webserver einbinden

Es gibt eine Reihe von Unterschieden zwischen App Engine und Cloud Run, die bei der Migration zwischen den beiden Plattformen berücksichtigt werden sollten. Ein Unterschied besteht darin, dass die Java 8-Laufzeit von App Engine einen Jetty-Server für die gehosteten Apps bereitgestellt und verwaltet hat, Cloud Run jedoch nicht. Wir verwenden Spring Boot, um einen Webserver und einen Servlet-Container bereitzustellen.

Fügen Sie die folgenden Abhängigkeiten hinzu:

<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 bettet standardmäßig einen Tomcat-Server ein. In diesem Beispiel wird dieses Artefakt jedoch ausgeschlossen und Jetty verwendet, um Unterschiede im Standardverhalten nach der Migration zu minimieren.

3. Spring Boot-Einrichtung

Spring Boot kann Ihre Servlets ohne Änderungen wiederverwenden, es ist jedoch eine Konfiguration erforderlich, damit sie erkannt werden.

Erstellen Sie die folgende MigratedServletApplication.java-Klasse im Paket 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);
    }
}

Beachten Sie, dass dies die @ServletComponentScan-Annotation umfasst, die standardmäßig im aktuellen Paket nach @WebServlets sucht und diese wie erwartet zur Verfügung stellt.

4. App als JAR-Datei verpacken

Es ist zwar möglich, Ihre App aus einer WAR-Datei zu containerisieren, aber es ist einfacher, wenn Sie Ihre App als ausführbare JAR-Datei verpacken. Das erfordert nicht viel Konfiguration, insbesondere bei Projekten, die Maven als Build-Tool verwenden, da die JAR-Paketierung das Standardverhalten ist.

Entfernen Sie das packaging-Tag in der Datei pom.xml:

<packaging>war</packaging>

Fügen Sie als Nächstes spring-boot-maven-plugin hinzu:

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

5. Von App Engine-Konfiguration, -Diensten und -Abhängigkeiten migrieren

Wie zu Beginn des Codelabs erwähnt, sind Cloud Run und App Engine für unterschiedliche Nutzer konzipiert. Bestimmte Funktionen, die App Engine standardmäßig bietet, z. B. die Dienste Cron und Task Queue, müssen manuell neu erstellt werden. Sie werden in späteren Modulen genauer behandelt.

In der Beispiel-App werden keine gebündelten Legacy-Dienste verwendet. Nutzer, deren Apps dies tun, können sich die folgenden Anleitungen ansehen:

Da Sie die Bereitstellung ab sofort in Cloud Run vornehmen, kann appengine-maven-plugin entfernt werden:

<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. Anwendung containerisieren

Jetzt können Sie Cloud Build mitteilen, wie der Container Ihrer Anwendung erstellt werden soll. Bei dieser Containerisierungsmethode ist keine separate Build-Konfigurationsdatei (cloudbuild.yaml) erforderlich. Wir können einfach ein minimales Dockerfile als Ausgangspunkt definieren:

FROM eclipse-temurin

ARG JAR_FILE=JAR_FILE_MUST_BE_SPECIFIED_AS_BUILD_ARG

COPY ${JAR_FILE} app.jar

ENTRYPOINT ["java", "-jar","/app.jar"]

In diesem Dockerfile wird die Uber-Jar-Version Ihres Spring Boot-Dienstes in einer einzigen Ebene gebündelt. Dies ist der einfachste Ansatz für die Dockerfile-Containerisierung, hat aber eine Reihe von Nachteilen, insbesondere wenn Abhängigkeiten relativ stabil sind. Bedenken wie dieses sind der Grund, warum diese Containerisierungsmethode als anspruchsvoller gilt. Der Vorteil ist jedoch, dass Sie mit einem eigenen Dockerfile die vollständige Kontrolle über Ihr Basis-Image haben und von den Leistungsvorteilen eines sorgfältig geschichteten Images profitieren.

2**. Build-Prozess ausführen**

Nachdem Sie Cloud Build über die gewünschten Build-Schritte informiert haben, können Sie die Bereitstellung mit einem Klick starten.

Führen Sie dazu diesen Befehl aus:

gcloud builds submit --tag LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME

Ersetzen Sie die Platzhalterwerte im obigen Befehl durch Folgendes:

  • LOCATION: Der regionale oder multiregionale Standort für Ihr Repository.
  • PROJECT_ID: Ihre Cloud-Projekt-ID.
  • REPOSITORY: Der Name Ihres Artifact Registry-Repositorys.
  • IMAGE_NAME: Der Name Ihres Container-Images.

Nach Abschluss des Vorgangs wurde Ihr Container-Image erstellt, in Artifact Registry gespeichert und in Cloud Run bereitgestellt.

Am Ende dieses Codelabs sollte Ihre App genauso aussehen wie die im Ordner „mod4-migrate-to-cloud-run“.

Das war schon alles. Sie haben eine Java 8-App Engine-Anwendung erfolgreich zu Java 17 und Cloud Run migriert und wissen jetzt besser, was bei einem Wechsel und der Auswahl von Hosting-Optionen zu tun ist.

6. Zusammenfassung/Bereinigung

Herzlichen Glückwunsch! Sie haben Ihre App aktualisiert, in einen Container gepackt und migriert. Damit ist dieses Tutorial abgeschlossen.

Als Nächstes sollten Sie sich mit den CI/CD- und Softwarelieferketten-Sicherheitsfunktionen vertraut machen, die Ihnen jetzt zur Verfügung stehen, da Sie mit Cloud Build bereitstellen können:

Optional: Dienst bereinigen und/oder deaktivieren

Wenn Sie die Beispiel-App im Rahmen dieser Anleitung in App Engine bereitgestellt haben, denken Sie daran, die App zu deaktivieren, um Gebühren zu vermeiden. Wenn Sie mit dem nächsten Codelab fortfahren möchten, können Sie es wieder aktivieren. Wenn App Engine-Apps deaktiviert sind, fallen keine Gebühren für Zugriffe an. Die Datastore-Nutzung kann jedoch in Rechnung gestellt werden, wenn sie das kostenlose Kontingent überschreitet. Löschen Sie daher genügend Daten, um dieses Limit einzuhalten.

Wenn Sie die Migrationen nicht fortsetzen und alles vollständig löschen möchten, können Sie entweder Ihren Dienst löschen oder Ihr Projekt vollständig beenden.

7. Zusätzliche Ressourcen

Probleme/Feedback zu Codelabs für das App Engine-Migrationsmodul

Wenn Sie Probleme mit diesem Codelab feststellen, suchen Sie bitte zuerst nach Ihrem Problem, bevor Sie es melden. Links zum Suchen und Erstellen neuer Probleme:

Migrationsressourcen

Onlineressourcen

Unten finden Sie Online-Ressourcen, die für diese Anleitung relevant sein könnten:

App Engine

Andere Cloud-Informationen

Videos

Lizenz

Dieser Text ist mit einer Creative Commons Attribution 2.0 Generic License lizenziert.