1. 概要
この一連の Codelab(セルフペース型のハンズオン チュートリアル)は、Google App Engine(スタンダード)Java デベロッパーが一連の移行手順をご案内し、アプリをモダナイズできるようにすることを目的としています。以下の手順に従うことで、アプリのポータビリティを高め、Cloud Run、App Engine のコンテナ ホスティング シスターサービス、その他のコンテナ ホスティング サービス向けにコンテナ化できます。
このチュートリアルでは、Dockerfile を使用して App Engine アプリをコンテナ化し、Cloud Run フルマネージド サービスにデプロイする方法について説明します。Dockerfile は、この移行に最も実践的デプロイ方法ですが、ビルドプロセスをカスタマイズするためのオプションも多数用意されています。
App Engine から Cloud Run に移行するために必要な手順だけでなく、Java 8 App Engine アプリを Java 17 にアップグレードする方法も学習します。
移行対象のアプリケーションで App Engine の以前のバンドル サービスやその他の App Engine 固有の機能を多用している場合は、この Codelab よりも出発点として Java 11/17 用の App Engine バンドル サービスへのアクセス ガイドをご覧ください。
GCP コンソールの
- Cloud Shell を使用する
- Cloud Run、Artifact Registry、Cloud Build API を有効にする
- Docker、Docker、Cloud Build を使用してアプリをコンテナ化する
- コンテナ イメージを Cloud Run にデプロイする
必要なもの
- 有効な GCP 請求先アカウントと App Engine が有効である Google Cloud Platform プロジェクト
- 一般的な Linux コマンドに関する実践的な知識
- App Engine アプリの開発とデプロイに関する基本的な知識
- Java 17 に移行して Cloud Run にデプロイする Java 8 サーブレット アプリ(App Engine 上のアプリでもソースでもかまいません)
アンケート
このチュートリアルをどのように使用されますか?
Java の使用経験をどのように評価されますか。
Google Cloud サービスの使用経験はどの程度ありますか?
<ph type="x-smartling-placeholder">2. 背景情報
App Engine や Cloud Functions などの PaaS システムは、SysAdmin や DevOps がソリューションの構築に集中できるなど、チームとアプリケーションに多くの利便性を提供します。サーバーレスなプラットフォームにより、アプリは必要に応じて自動スケーリングでき、従量課金制でゼロにスケールダウンして費用を管理できるほか、さまざまな一般的な開発言語を使用できます。
その一方で、コンテナの柔軟性も魅力的です。コンテナでは、任意の言語、ライブラリ、バイナリを選択できるため、サーバーレスの利便性とコンテナの柔軟性という両方の長所を活用できます。これこそが、Google Cloud Run の特長です。
Cloud Run の使用方法は、この Codelab の対象外です。Cloud Run のドキュメントをご覧ください。ここでの目標は、Cloud Run(または他のコンテナホスト型サービス)向けに App Engine アプリをコンテナ化する方法を理解することです。先に進む前に、いくつか注意すべき点があります。主に、ユーザー エクスペリエンスが多少変わるということです。
この Codelab では、コンテナをビルドしてデプロイする方法を学びます。ここでは、Dockerfile を使用してアプリをコンテナ化する方法、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 アプリです。このアプリを App Engine でデプロイできるように準備する方法については、README の手順をご覧ください。
3. (省略可)ベースライン アプリをデプロイする
以下の手順は、Cloud Run に移行する前にアプリが App Engine で動作することを確認する場合にのみ必要です。
README.md の手順を参照してください。
gcloud
CLI をインストールする/再度確認する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 のみを使用します。
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 としてパッケージ化する
アプリを 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 Build に伝える準備が整いました。このコンテナ化方法では、個別のビルド構成ファイル(cloudbuild.yaml)は必要ありません。出発点として最小限の Dockerfile を定義するだけです。
日食のテムリンから
ARG JAR_FILE=JAR_FILE_MUST_BE_SPECIFIED_AS_BUILD_ARG
${JAR_FILE} の app.jar をコピー
エントリポイント ["java", "-jar","/app.jar"]
この dockerfile は、Spring Boot サービスの uber-jar 版を 1 つのレイヤにバンドルしています。これは Dockerfile コンテナ化の最もシンプルなアプローチですが、依存関係が比較的安定している場合に繰り返し回数を比較する場合は特に、多くの欠点があります。このような懸念から、このコンテナ化手法はより高度なものとみなされます。ただし、独自の dockerfile を作成すると、ベースイメージを完全に制御でき、慎重にレイヤ化されたイメージを作成することによるパフォーマンス上のメリットを享受できます。
2**。ビルドプロセスを実行する**
目的のビルドステップを Cloud Build に通知できたので、ワンクリックでデプロイできるようになりました。
次のコマンドを実行します。
gcloud builds submit --tag LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME
上記のコマンドのプレースホルダ値を次のように置き換えます。
- LOCATION: リポジトリのリージョンまたはマルチリージョンのロケーション。
- PROJECT_ID: Cloud プロジェクト ID。
- REPOSITORY: Artifact Registry リポジトリの名前。
- IMAGE_NAME: コンテナ イメージの名前。
プロセスが完了すると、コンテナ イメージがビルドされて Artifact Registry に保存され、Cloud Run にデプロイされます。
この Codelab を終えると、アプリは mod4-migrate-to-cloud-run フォルダにあるアプリと同じように表示されます。
このように、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 番目の比較をプラットフォームに
- レガシー ランタイムの長期サポート
Cloud のその他の情報
- Google Cloud「Always Free」ティア
- Google Cloud CLI(
gcloud
CLI) - Google Cloud に関するすべてのドキュメント
動画
- サーバーレス移行ステーション
- Serverless Expeditions(サーバーレス探索)
- Google Cloud Tech に登録
- Google Developers に登録します。
ライセンス
この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。