1. 概要
この一連の Codelab(ご自分のペースで進められる実践型のチュートリアル)は、一連の移行についてガイダンスを実施することにより、Google App Engine(標準)の Java デベロッパーがアプリをモダナイズできるよう支援することを目的としています。これらの手順に沿って、アプリをよりポータブルになるように更新し、Cloud Run、App Engine への Google Cloud のコンテナ ホスティング姉妹サービス、その他のコンテナ ホスティング サービス用にコンテナ化するかどうかを決定できます。
このチュートリアルでは、Jib を使用して、Cloud Run フルマネージド サービスにデプロイするために App Engine アプリをコンテナ化する方法について説明します。Jib を使用すると、コンテナ内のアプリケーションを開発、リリース、実行するための業界でよく知られているプラットフォームである Docker イメージを作成できます。
このチュートリアルでは、App Engine から Cloud Run に移行するために必要な手順を説明するだけでなく、Java 8 App Engine アプリを Java 17 にアップグレードする方法も説明します。
アプリケーションで App Engine の以前のバンドル サービスやその他の App Engine 機能が多用されている場合は、Cloud Run に移行する前に、これらのバンドル サービスから移行するか、これらの機能を置き換えることをおすすめします。移行オプションの調査に時間がかかる場合や、当面の間、以前のバンドル サービスを引き続き使用したい場合は、新しいランタイムにアップグレードする際に、Java 11/17 用の App Engine バンドル サービスに引き続きアクセスできます。アプリの移植性が高まったら、この Codelab に戻って、アプリに手順を適用する方法を学習してください。
GCP コンソールの
- Cloud Shell を使用する
- Cloud Run、Artifact Registry、Cloud Build の各 API を有効にする
- Jib と Cloud Build を使用してアプリをコンテナ化する
- コンテナ イメージを Cloud Run にデプロイする
必要なもの
- 有効な GCP 請求先アカウントと App Engine が有効になっている Google Cloud Platform プロジェクト
- 一般的な Linux コマンドに関する実践的な知識
- App Engine アプリの開発とデプロイに関する基礎知識
- Java 17 に移行して Cloud Run にデプロイする Java 8 サーブレット アプリ(App Engine 上のアプリまたはソースのみ)
アンケート
このチュートリアルをどのように使用されますか?
Java のご利用経験はどの程度ありますか?
Google Cloud サービスの使用経験はどの程度ありますか?
2. 背景情報
App Engine や Cloud Functions などの Platform as a Service(PaaS)システムは、SysAdmin や DevOps がソリューションの構築に集中できるようにするなど、チームやアプリケーションに多くの利便性を提供します。サーバーレス プラットフォームを使用すると、アプリは必要に応じて自動的にスケールアップし、従量課金制でゼロまでスケールダウンして費用を管理し、さまざまな一般的な開発言語を使用できます。
しかし、コンテナの柔軟性も魅力的です。任意の言語、ライブラリ、バイナリを選択できるコンテナは、サーバーレスの利便性とコンテナの柔軟性の両方を実現します。これが Cloud Run のすべてです。
Cloud Run の使用方法の学習は、この Codelab の範囲外です。Cloud Run のドキュメントをご覧ください。ここでは、Cloud Run(または他のコンテナ ホスト型サービス)用に App Engine アプリをコンテナ化する方法を理解することを目的としています。先に進む前に、ユーザー エクスペリエンスが若干異なることをはじめ、いくつか知っておくべきことがあります。
この Codelab では、コンテナをビルドしてデプロイする方法を学びます。次の方法を学習します。
- Jib を使用してアプリをコンテナ化する
- App Engine 構成から移行する
- 必要に応じて、Cloud Build のビルドステップを定義します。
これには、特定の App Engine 固有の機能からの移行が含まれます。このパスに沿いたくない場合は、アプリを App Engine に保持したまま Java 11/17 ランタイムにアップグレードすることもできます。
3. セットアップ/事前作業
1. プロジェクトのセットアップ
このチュートリアルでは、新しいプロジェクトの appengine-java-migration-samples リポジトリのサンプルアプリを使用します。プロジェクトに有効な請求先アカウントがあることを確認します。
既存の App Engine アプリを Cloud Run に移行する場合は、代わりにそのアプリを使用できます。
次のコマンドを実行して、プロジェクトに必要な API を有効にします。
gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com
2. ベースライン サンプルアプリを入手する
独自のマシンまたは Cloud Shell でサンプルアプリのクローンを作成し、baseline フォルダに移動します。
このサンプルは、App Engine にデプロイすることを目的とした Java 8 のサーブレット ベースの Datastore アプリです。README の手順に沿って、App Engine デプロイ用にこのアプリを準備します。
3. (省略可)ベースライン アプリをデプロイする
以下は、Cloud Run に移行する前に App Engine でアプリが動作することを確認する場合にのみ必要です。
README.md の手順を参照してください。
gcloudCLI をインストールまたは再確認するgcloud initを使用してプロジェクトの gcloud CLI を初期化するgcloud app createを使用して App Engine プロジェクトを作成する- サンプルアプリを App Engine にデプロイする
./mvnw package appengine:deploy -Dapp.projectId=$PROJECT_ID
- アプリが App Engine で問題なく実行されることを確認する
4. Artifact Registry リポジトリを作成する
アプリをコンテナ化したら、イメージを push して保存する場所が必要になります。Google Cloud でこれを行うには、Artifact Registry を使用することをおすすめします。
gcloud を使用して、次のように migration という名前のリポジトリを作成します。
gcloud artifacts repositories create migration --repository-format=docker \
--description="Docker repository for the migrated app" \
--location="northamerica-northeast1"
このリポジトリでは docker 形式タイプが使用されていますが、複数のリポジトリ タイプを使用できます。
この時点で、ベースラインの App Engine アプリが作成され、Google Cloud プロジェクトで Cloud Run への移行の準備が整っています。
4. アプリケーション ファイルの変更
アプリで App Engine の以前のバンドル サービス、構成、その他の App Engine 専用の機能が多用されている場合は、新しいランタイムにアップグレードしながら、これらのサービスへのアクセスを継続することをおすすめします。この Codelab では、スタンドアロン サービスをすでに使用しているか、スタンドアロン サービスを使用するようにリファクタリングできるアプリケーションの移行パスについて説明します。
1. Java 17 にアップグレードする
アプリが Java 8 を使用している場合は、セキュリティ アップデートに対応し、新しい言語機能を利用できるように、11 や 17 などの新しい LTS 候補にアップグレードすることを検討してください。
まず、pom.xml のプロパティを更新して、以下を含めます。
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
これにより、プロジェクトのバージョンが 17 に設定され、Java 17 言語機能へのアクセスを希望し、コンパイルされたクラスが Java 17 JVM と互換性があることを希望することがコンパイラ プラグインに通知されます。
2. ウェブサーバーを含む
App Engine と Cloud Run の間を移行する際に考慮すべき相違点がいくつかあります。1 つの違いは、App Engine の Java 8 ランタイムがホストするアプリに Jetty サーバーを提供して管理していたのに対し、Cloud Run はそうではないことです。Spring Boot を使用して、ウェブサーバーとサーブレット コンテナを提供します。
次の依存関係を追加します。
<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 にはデフォルトで Tomcat サーバーが埋め込まれていますが、このサンプルではそのアーティファクトを除外し、Jetty を使用して、移行後のデフォルトの動作の違いを最小限に抑えます。また、Jetty のバージョンを構成して、App Engine が提供するバージョンと一致させることもできます。
<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. Spring Boot の設定
Spring Boot はサーブレットを修正なしで再利用できますが、検出可能性のために構成が必要になります。
com.example.appengine パッケージに次の MigratedServletApplication.java クラスを作成します。
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);
}
}
これには @ServletComponentScan アノテーションが含まれます。このアノテーションは(デフォルトでは現在のパッケージ内で)@WebServlets を検索し、それらを想定どおりに使用できるようにします。
4. アプリを JAR としてパッケージ化する
Jib を使用して war からアプリをコンテナ化することもできますが、アプリを実行可能な JAR としてパッケージ化すると、より簡単になります。特に、Maven をビルドツールとして使用するプロジェクトでは、jar パッケージングがデフォルトの動作であるため、構成はほとんど必要ありません。
pom.xml ファイル内の packaging タグを削除します。
<packaging>war</packaging>
次に、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. App Engine の構成、サービス、依存関係からの移行
Codelab の冒頭で説明したように、Cloud Run と App Engine は異なるユーザー エクスペリエンスを提供するように設計されています。App Engine が提供する特定の機能(Cron サービスや Task Queue サービスなど)は手動で再作成する必要があります。これについては、後のモジュールで詳しく説明します。
このサンプルアプリでは以前のバンドル サービスは使用していませんが、アプリで以前のバンドル サービスを使用している場合は、次のガイドをご覧ください。
- バンドル サービスからの移行で、適切なスタンドアロン サービスを見つける。
- XML 構成ファイルを YAML に移行する: App Engine を使用しながら Java 11/17 ランタイムに移行するユーザー向け。
以降は Cloud Run にデプロイするため、appengine-maven-plugin を削除できます。
<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. アプリケーションのコンテナ化
この時点で、ソースコードから Cloud Run にアプリを手動でデプロイできます。これは、Cloud Build をバックグラウンドで使用して、ハンズオフのデプロイ エクスペリエンスを提供する優れたオプションです。ソース デプロイについては、以降のモジュールで詳しく説明します。
または、アプリのデプロイ方法をより詳細に制御する必要がある場合は、目的のビルドステップを明示的に記述した cloudbuild.yaml ファイルを定義することで、それを実現できます。
1. cloudbuild.yaml ファイルを定義する
pom.xml と同じレベルに次の cloudbuild.yaml ファイルを作成します。
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']
Cloud Build にこれらの手順を実行するように指示すると、次の処理が行われます。
./mvnw testでテストを実行する- Jib を使用してイメージをビルド、push、タグ付けして Artifact Registry に登録する
gcloud run deployを使用してイメージを Cloud Run にデプロイする
‘visitors' は、目的のサービス名として Cloud Run に提供されます。–allow-unauthenticated フラグを使用すると、ユーザーは認証なしでウェブアプリにアクセスできます。cloudbuild.yaml ファイルで、PROJECT_ID を実際のプロジェクト ID に置き換えてください。
次に、次の IAM ポリシー バインディングを追加して、Cloud Build サービス アカウントが 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. ビルドプロセスを実行する
Cloud Build に必要なビルドステップを通知したので、ワンクリックでデプロイできます。
次のコマンドを実行します。
gcloud builds submit
プロセスが完了すると、コンテナ イメージがビルドされ、Artifact Registry に保存されて、Cloud Run にデプロイされます。
この Codelab の最後には、アプリは java17-and-cloud-run/finish のアプリと同じようになります。
このように、Java 8 App Engine アプリを Java 17 と Cloud Run に移行しました。これで、切り替えとホスティング オプションの選択に伴う作業について、より明確に理解できるようになりました。
6. 概要/クリーンアップ
これで、アプリのアップグレード、コンテナ化、移行が完了しました。これでチュートリアルは終了です。
ここから、Cloud Build でデプロイできるようになった CI/CD 機能とソフトウェア サプライ チェーンのセキュリティ機能について詳しく学習します。
省略可: サービスをクリーンアップまたは無効にする
このチュートリアルで App Engine にサンプルアプリをデプロイした場合は、課金されないようにアプリを無効にしてください。次の Codelab に進む準備ができた時点で、再度有効にできます。App Engine アプリを無効にしている間は、トラフィックが発生しないため料金は発生しませんが、Datastore の使用量が無料割り当てを超えると、課金される場合があります。上限を超えないよう削除してください。
また、移行を続けず、完全に削除したい場合は、サービスを削除するか、プロジェクトを完全にシャットダウンしてください。
7. 参考情報
App Engine 移行モジュールの Codelab に関する問題 / フィードバック
この Codelab に問題が見つかった場合は、提出する前にまず問題を検索してください。新しい問題の検索と登録を行うためのリンク:
移行に関するリソース
オンライン リソース
このチュートリアルに関連する可能性のあるオンライン リソースは次のとおりです。
App Engine
- App Engine のドキュメント
- App Engine の料金と割り当てに関する情報
- 第 1 世代と第 2 世代のプラットフォームの比較
- レガシー ランタイムの長期サポート
その他のクラウド情報
- Google Cloud の「常時無料」枠
- Google Cloud CLI(
gcloudCLI) - Google Cloud に関するすべてのドキュメント
動画
ライセンス
この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。