モジュール 4: Docker を使用した Google App Engine から Cloud Run への移行

この一連の Codelab(ご自分のペースで進められる実践型のチュートリアル)は、一連の移行についてガイダンスを実施することにより、Google App Engine(標準)のデベロッパーがアプリを最新化できるよう支援することを目的としています。それが完了したら、ユーザーは、Cloud Run、App Engine への Google Cloud のコンテナ ホスティング姉妹サービス、その他のコンテナ ホスティング サービス用に明示的にコンテナ化することで、アプリの移植性を高めることができます。

このチュートリアルでは、Docker を使用して、Cloud Run フルマネージド サービスにデプロイする App Engine アプリをコンテナ化する方法を説明します。これは、コンテナ内でアプリケーションを開発、出荷、実行するための業界有数のプラットフォームです。Python 2 デベロッパーの場合は、このチュートリアルでは モジュール 2 Cloud NDB App Engine サンプルアプリを使用します。Python 3 のデベロッパーの場合はモジュール 3 Cloud Datastore のサンプルを使用します。

次の方法を学習します。

  • Docker を使用してアプリをコンテナ化する
  • コンテナ イメージを Cloud Run にデプロイする

必要なもの

アンケート

この Codelab をどのように使用しますか。

全体を通して読むのみ 内容を読んで演習を完了する

App Engine や Cloud Functions などの PaaS システムは、チームとアプリケーションにとって多くの利点があります。たとえば、これらのサーバーレス プラットフォームでは、SysAdmin と DevOps がソリューションの構築に専念できます。アプリでは必要に応じた自動スケールアップが可能で、従量課金制によってゼロにスケールダウンしてコストを管理でき、さまざまな一般的な開発言語を利用できます。

しかし、コンテナの柔軟性も魅力的であり、任意の言語、ライブラリ、バイナリを選択できます。サーバーレスの利便性とコンテナの柔軟性の両方をユーザーに提供することが、Google Cloud Run の目的です。

Cloud Run の使い方については、この Codelab の対象外です。Cloud Run ドキュメントをご覧ください。ここでは、Cloud Run(またはその他のサービス)用に App Engine アプリをコンテナ化する方法について説明します。次のステップに進む前にいくつか注意点があります。ユーザー エクスペリエンスが若干異なり、アプリケーション コードの取り出しとデプロイは必要なくなるため、少しステータスが低くなります。

代わりに、コンテナの構築やデプロイなど、コンテナに関することを学ぶ必要があります。また、App Engine のウェブサーバーを使用しなくなるため、ウェブサーバーを含め、コンテナ イメージに含めるものを決定できます。このパスに沿いたくない場合は、アプリを App Engine に保持しても構いません。

このチュートリアルでは、アプリをコンテナ化し、App Engine の構成ファイルをコンテナ構成に置換して、コンテナの内容を決定し、アプリの起動方法を指定する方法を学びます。その多くは、App Engine によって自動的に処理されます。

この移行の手順は次のとおりです。

  1. セットアップ / 事前作業
  2. アプリケーションのコンテナ化
    • 構成ファイルの置換
    • アプリケーション ファイルの変更

チュートリアルの主要部分に進む前に、まずプロジェクトをセットアップし、コードを取得してから、ベースライン アプリをデプロイします。これで、作業コードを使って作業を開始できます。

1. プロジェクトをセットアップする

モジュール 2 またはモジュール 3 の Codelab を完了している場合は、その同じプロジェクト(とコード)を再利用することをおすすめします。あるいは、新しいプロジェクトを作成するか、別の既存のプロジェクトを再利用することもできます。プロジェクトにアクティブな請求先アカウントがあり、App Engine(アプリ)が有効になっていることを確認します。

2. ベースライン サンプルアプリを入手する

この Codelab の前提条件の 1 つは、機能するモジュール 2 またはモジュール 3 のサンプルアプリを用意することです。まだお持ちでない場合は、先に進む前にいずれかのチュートリアル(上のリンク)を完了してください。すでに内容に精通している場合は、以下のモジュール 2 または 3 のコーディングから開始してください。

独自のものを使用するかどうかに関わらず、モジュール 2 のコードもこのチュートリアルの Python 2 バージョンで実行します。同様に、Python 3 でモジュール 3 のコードを実行します。このモジュール 4 の Codelab では、それぞれのステップを順を追って説明します。また、オプションによっては、モジュール 4 のリポジトリ フォルダ(FINISH)に似たコードになるはずです。

Python 2 モジュール 2 の開始ファイル(独自のまたは Google のもの)のディレクトリは次のようになります。

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

独自のモジュール 2(2.x)コードを使用している場合は、lib フォルダも存在します。Python 3 では libappengine_config.py も使用されません。ここでは、モジュール 3(3.x)の開始コードは次のようになります。

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

3. ベースライン アプリを(再)デプロイする

この段階で実施する必要がある残りの事前作業のステップ:

  1. gcloud コマンドライン ツールを学びなおす
  2. gcloud app deploy を使用してサンプルアプリを再デプロイする
  3. アプリが App Engine 上で問題なく動作することを確認する

これらの手順を正常に実行できたら、それをコンテナ化できます。

Docker は業界で標準的なコンテナ化プラットフォームです。前述した課題の 1 つは、コンテナ イメージのビルド方法を指定する構成ファイルとなる、効率的な Dockerfile を選ぶ必要があることです。一方 Buildpacks は、イントロスペクションを使用してアプリの依存関係を判断し、Buildpacks コンテナをアプリにとって可能な限り効率的にするため、ほとんど労力を必要としません。

コンテナや Docker についてすでに知識があり、Cloud Run 用に App Engine アプリをコンテナ化する方法について学習したい場合、ここで学ぶことができます。その後も、モジュール 5 Codelab(Cloud Buildpack と同じ)をお気軽にお試しください。Google の必要最低限機能のサンプルアプリは、前述の Dockerfile 問題のいくつかを回避するのには不十分です。

移行手順には、App Engine 構成ファイルの置き換えと、アプリの起動方法の指定が含まれます。以下の表は、各プラットフォーム タイプに必要な構成ファイルをまとめたものです。App Engine の列を Docker 列と比較します。必要に応じて Buildpack とも比較します。

説明

App Engine

Docker

Buildpacks で

全般構成

app.yaml

Dockerfile

service.yaml

サードパーティ ライブラリ

requirements.txt

requirements.txt

requirements.txt

サードパーティの構成

app.yaml(プラス appengine_config.pylib [2.x のみ])

該当なし

該当なし

起動

該当なしまたは app.yamlentrypoint を使用する場合)

Dockerfile

Procfile

ファイルを無視

.gcloudignore.gitignore

.gcloudignore.gitignore.dockerignore

.gcloudignore.gitignore

アプリをコンテナ化したら、Cloud Run にデプロイできます。Google Cloud コンテナ プラットフォームのその他のオプションには、Compute EngineGKEAnthos などがあります。

全般構成

App Engine からの移行では、app.yaml を、コンテナをビルドして実行する方法の概要を示す Dockerfile に置き換えることになります。App Engine は自動的にアプリケーションを起動しますが、Cloud Run は起動しません。これを行うには、Dockerfile ENTRYPOINT または CMD コマンドを実行します。Dockerfile の詳細については、Cloud Run のドキュメント ページ を確認し、gunicorn を生成する Dockerfile の例をご覧ください。

DockerfileENTRYPOINT または CMD を使用する代わりに、Procfile を使用する方法もあります。最後に、.dockerignore は、コンテナのサイズを抑えるためにアプリ以外のファイルを除外するのに役立ちます。詳しくは今後の更新をお待ちください。

app.yaml を削除して Dockerfile を作成する

app.yaml はコンテナで使用されていないため、今すぐ削除してください。コンテナ構成ファイルは Dockerfile です。サンプルアプリに必要なのは最小限のものだけです。使用している Python のバージョンに応じて、このコンテンツを使用して Dockerfile を作成し、NNN2 または 3 に置き換えます。

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

コンテナの開始方法を指定する ENTRYPOINT を除いて、ほとんどの Dockerfile ではコンテナの作成方法が指定されます。この場合、python main.py を呼び出して Flask 開発環境サーバーを実行します。Docker を初めて使用する場合は、FROM ディレクティブで開始されるベースイメージが示され、「slim」は最小限の Python ディストリビューションを指します。Docker Python イメージページで詳細を確認してください。

真ん中のコマンドセットで、作業ディレクトリ(/app)を作成し、アプリケーション ファイルにコピーしてから、pip install を実行してサードパーティ ライブラリをコンテナに配置します。WORKDIR は、Linux の mkdir コマンドと cd コマンドを結合します。詳しくは、WORKDIR ドキュメント をご覧ください。COPY ディレクティブと RUN ディレクティブは説明がなくてもわかります。

サードパーティ ライブラリ

requirements.txt ファイルは変わりません。Flask は、Datastore クライアント ライブラリ(Cloud Datastore または Cloud NDB)と一緒に用意する必要があります。Gunicorn のような別の WSGI 準拠の HTTP サーバー(これを記載する現時点でのバージョンは 20.0.4)を使用する場合は、gunicorn==20.0.4requirements.txt に追加してください。

サードパーティの構成

Python 2 App Engine のデベロッパーは、サードパーティ ライブラリが lib フォルダにコピーされ、requirements.txt で参照され、app.yaml に項目化され、appengine_config.py によってサポートされていることを認識しています。Python 3 App Engine アプリなどのコンテナでは、requirements.txt のみが使用されるため、他のすべてのものを破棄できます。つまり、2.x App Engine アプリがある場合は、appengine_config.py とすべての lib フォルダを今すぐ削除 します。

起動

Python 2 のユーザーは App Engine のウェブサーバーをスタートアップしませんが、コンテナに移行する場合は、これを行う必要があります。そのためには、アプリの開始方法を指定する DockerfileCMD または ENTRYPOINT ディレクティブを追加します。これについては、Python 3 の場合と同じ方法のため、以下で説明します。

Python 3 を使用する場合は、handlers セクションの script: auto ディレクティブの代わりに、app.yaml ファイルを entrypoint に変換するオプションがあります。Python 3 app.yamlentrypoint を使用すると、次のようになります。

runtime: python38
entrypoint: python main.py

entrypoint ディレクティブは、サーバーの起動方法を App Engine に指示します。これは、すぐに Dockerfile へ移動させることができます(または、Buildpacks を使用する場合[モジュール 5 を参照] Procfile でアプリをコンテナ化します)。エントリポイント ディレクティブが両方のプラットフォーム間でどこに行くかを要約します。

  • Docker: Dockerfile の行: ENTRYPOINT ["python", "main.py"]
  • Buildpacks: Procfile の行: web: python main.py

テストには Flask 開発環境サーバーを使用しても問題ありませんが、アプリケーションに gunicorn のような本番環境サーバーを使用する場合は、Cloud Run クイックスタート サンプルのように ENTRYPOINT または CMD ディレクティブを指定してください。

ファイルを無視

コンテナのサイズを縮小する .dockerignore ファイルを作成し、次のような余分なファイルでコンテナ イメージを溢れさせないようにすることをおすすめします。

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

アプリケーション ファイル

モジュール 2 またはモジュール 3 アプリはすべて Python 2 ~ 3 と互換性があるため、main.py のコア コンポーネントは変更されません。数行のスタートアップ コードを追加するだけです。Cloud Run でアプリを呼び出すためにはポート 8080 を開いておく必要があるため、main.py の下部に 1 対の行を追加して開発環境サーバーを起動します。

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

Docker の構成とソースファイルの更新が完了したら、Cloud Run で実行できるようになります。その前に、サービスについて簡単に説明します。

サービスとアプリ

App Engine は主にアプリケーションをホストするために作成されていますが、マイクロサービスのコレクションから構成されるウェブサービスやアプリケーションをホスティングするためのプラットフォームでもあります。Cloud Run では、実際のサービスかウェブ インターフェースを備えたアプリケーションかに関係なく、すべてがサービスであるため、アプリケーションではなくサービスのデプロイメントとして使用を検討します。

App Engine アプリが複数のサービスで構成されている場合を除き、アプリケーションをデプロイするときに、何も名前をつける必要はありません。これは、サービス名を考える必要のある Cloud Run によって異なります。ただし、App Engine の appspot.com ドメインにはプロジェクト ID を使用します。例: https://PROJECT_ID.appspot.com、おそらくリージョン ID の略語です。例: http://PROJECT_ID.REGION_ID.r.appspot.com

ただし、Cloud Run サービスのドメインには、サービス名、リージョン ID の略語、ハッシュが含まれますが、プロジェクト ID は含まれません。例: https://SVC_NAME-HASH-REG_ABBR.a.run.app。つまり、サービス名の検討を始めましょう。

サービスをデプロイする

次のコマンドを実行してコンテナ イメージをビルドし、Cloud Run にデプロイします。プロンプトが表示されたら、リージョンを選択して未認証の接続を許可してテストを容易にし、デプロイするサービスの名前が SVC_NAME であるリージョンを適切に選択します。

$ 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

ブラウザで指定された URL にアクセスして、デプロイが成功したことを確認します。

gcloud コマンドが示すように、ユーザーは以下に示すように、さまざまなデフォルト設定をセットして出力とインタラクティビティを下げることができます。たとえば、すべてのインタラクションを回避するには、代わりに次の 1 行のデプロイ コマンドを使用できます。

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

これを使用する場合は、上記でインタラクティブに行ったようなインデックス付きメニューの選択ではなく、必ず同じサービス名 SVC_NAME と目的の REGION の名前を選択してください。

アプリが App Engine の場合と同様に Cloud Run で動作することを確認します。上記の Codelab を実行せずにこのシリーズに入った場合、アプリ自体は変更されません。メイン Web ページへのすべての訪問が登録され(/)、サイトに必要回数アクセスすると、次のようになります。

visitme アプリ

これで、コードが 2.x または 3.x である モジュール 4 リポジトリ フォルダの内容と一致するはずです。このモジュール 4 の Codelab はこれで終了です。

オプション: クリーンアップ

次の移行 Codelab に進む準備が整うまで、課金されるのを回避するためのクリーンアップを行うにはどうすればよいでしょうか。別のプロダクトを使用しているため、Cloud Run の価格ガイドをご確認ください。

オプション: サービスの無効化

次のチュートリアルに進む準備ができていない場合は、サービスを無効にして、追加料金が発生しないようにします。次の Codelab に進む準備ができたら、再度有効にできます。アプリケーションが無効になっている間、料金のかかるトラフィックは発生しません。ただし、もう 1 つの課金対象は、Datastore の使用量です。無料割り当て量を超過した場合は課金が発生するため、上限を超えないよう削除してください。

また、移行を続けず、完全に削除したい場合は、サービスを削除するか、プロジェクトを完全にシャットダウンしてください。

次のステップ

これでアプリのコンテナ化が完了しました。これでチュートリアルは終了です。ここからは、モジュール 5 Codelab(以下のリンク)から Cloud Buildpack を使用して同じ操作を行うか、別の App Engine の移行を行う方法を学びます。

  • まだ移行していない場合は、Python 3 に移行します。サンプルアプリはすでに 2.x と 3.x と互換性があるため、Docker ユーザーは Dockerfile を更新して Python 3 イメージを使用するようにしてください。
  • モジュール 5: Cloud Buildpacks を使用して Cloud Run に移行する
    • Cloud Buildpacks を使用して Cloud Run で実行するようにアプリをコンテナ化する
    • Docker、コンテナ、または Dockerfile についての知識は必要ありません
    • アプリを Python 3 に移行済みであることが必要です
  • モジュール 7: App Engine の push タスクキュー([push] タスクキューを使用する場合に必要)
    • App Engine taskqueue プッシュタスクをモジュール 1 アプリに追加する
    • モジュール 8 で Cloud Tasks に移行するユーザーの準備を行う
  • モジュール 3:
    • Cloud NDB から Cloud Datastore に Datastore アクセスをモダナイズする
    • これは、Python 3 App Engine アプリと App Engine 以外のアプリに使用されるライブラリです
  • モジュール 6: Cloud Firestore への移行
    • Cloud Firestore に移行して Firebase の機能にアクセスする
    • Cloud Firestore は Python 2 をサポートしていますが、この Codelab は Python 3 でのみ使用できます。

App Engine 移行モジュールの Codelab に関する問題 / フィードバック

この Codelab に問題が見つかった場合は、提出する前にまず問題を検索してください。新しい問題の検索と作成を行うためのリンク:

移行に関するリソース

モジュール 2 と 3(開始)とモジュール 4(終了)のリポジトリ フォルダへのリンクを以下の表に示します。これらのファイルには、すべての App Engine Codelab 移行のリポジトリからアクセスすることもできます。このクローンの作成、および ZIP ファイルのダウンロードも可能です。

Codelab

Python 2

Python 3

モジュール 2

コード

コード

モジュール 3

コード

コード

モジュール 4

コード

コード

App Engine リソースと Cloud Run リソース

この特定の移行に関する追加リソースは以下のとおりです。