モジュール 11: Google App Engine から Cloud Functions への移行

1. 概要

Serverless Migration Station の Codelab シリーズ(セルフペース型のハンズオン チュートリアル)と関連動画は、Google Cloud サーバーレス デベロッパーが主にレガシー サービスからの移行を 1 つ以上の移行を通じてガイドし、アプリをモダナイズできるようにすることを目的としています。これにより、アプリのポータビリティが高まり、選択肢と柔軟性が増し、より広範な Cloud プロダクトと統合してアクセスできるようになり、より新しい言語リリースに簡単にアップグレードできるようになります。当初は初期の Cloud ユーザー、主に App Engine(スタンダード環境)のデベロッパーを対象としていますが、Cloud FunctionsCloud Run など、その他のサーバーレス プラットフォーム(該当する場合)まで幅広くカバーしています。

アプリ全体App Engine または Cloud Run のリソースが必要になります。コードがマイクロサービスや単純な関数のみで構成されている場合は、Cloud Functions のほうが適しています。この Codelab では、シンプルな App Engine アプリを移行して(または大規模なアプリを複数のマイクロサービスに分割)、Cloud Functions にデプロイする方法について学習します。Cloud Functions は、このようなユースケースのために特別に作成された別のサーバーレス プラットフォームです。

GCP コンソールの

  • Cloud Shell を使用する
  • Google Cloud Translation API を有効にする
  • API リクエストを認証する
  • 小規模な App Engine アプリを変換して Cloud Functions で実行する
  • Cloud Functions にコードをデプロイする

必要なもの

アンケート

このチュートリアルをどのように使用されますか?

通読のみ 通読して演習を行う

Python のご利用経験はどの程度ありますか?

初心者 中級者 上級者

Google Cloud サービスの使用経験はどの程度ありますか?

<ph type="x-smartling-placeholder"></ph> 初心者 中級 上達 をご覧ください。

2. 背景情報

Google App Engine や Cloud Functions のような PaaS システムは、ユーザーにとって多くの利便性を提供します。これらのサーバーレス プラットフォームにより、技術チームは、使用するプラットフォームの調査や必要なハードウェアの量の決定に時間を費やすことなく、ビジネス ソリューションの作成に集中できます。アプリケーションは必要に応じて自動スケーリングでき、従量課金制でゼロまでスケールダウンして費用を管理できるほか、今日の一般的な開発言語にも対応しています。

しかし、フルスタックのウェブ アプリケーション開発やモバイルアプリの複雑なバックエンドが App Engine に非常に適していますが、多くの場合、デベロッパーはニュース フィードの更新やホームチームのプレーオフ ゲームの最新のスコアの取得など、いくつかの機能をオンラインにしようと試みます。どちらのシナリオにもコーディング ロジックは存在しますが、どちらも本格的な「アプリケーション」とは思えません。App Engine の処理能力が必要です。そこで Cloud Functions の出番となります。

Cloud Functions は、次のような小さなコードをデプロイするためのものです。

  • アプリ全体の一部ではない
  • 開発スタック全体では不要
  • アプリケーションまたは単一のモバイルアプリのバックエンドで 1 つのものに焦点を当てている

また、Cloud Functions を使用して、Cloud FirestoreCloud SQL などの共有共通データベースを使用して、大規模なモノリシック アプリケーションを複数のマイクロサービスに分割することもできます。また、Cloud Run で関数やマイクロサービスをコンテナ化してサーバーレスで実行することもできます。

ほぼすべての移行チュートリアルで紹介したサンプル App Engine アプリは、基本的な機能を備えた短いアプリであり、Cloud Functions でも同じように機能します。このチュートリアルでは、Cloud Functions で動作するようにアプリを変更する方法を学びます。App Engine の観点から見ると、関数はアプリ全体よりもシンプルなため、簡単に(そして速く)開始でき、オーバーヘッドも少なくて済みます。見ていきましょう。この移行の特徴は次のとおりです。

  • セットアップ / 事前作業
  • 構成ファイルを削除する
  • アプリケーション ファイルの変更

3. 設定/事前作業

Cloud Functions は Python 2 をサポートしていないため、この Codelab は Python 3 バージョンのモジュール 2 の Cloud NDB App Engine サンプルアプリから始めます。まず、プロジェクトを設定し、コードを取得してから、ベースライン アプリをデプロイして、コードが動作することを確認します。

1. プロジェクトのセットアップ

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

2. ベースラインのサンプルアプリを取得する

この Codelab の前提条件の一つは、機能するモジュール 2 のサンプルアプリがあることです。まだお持ちでない場合は、先に進む前に、上のリンク先にあるいずれかのチュートリアルを完了してください。すでにその内容に慣れている場合は、以下のモジュール 2 のコードをコピーして利用を開始してください。

皆さんのコードであれ私たちのものであれ、モジュール 2 の Python 3 コードが出発点になります。モジュール 11 の Codelab では各ステップを順に説明し、モジュール 11 のリポジトリ フォルダ(FINISH)にあるコードに似たコードで締めくくります。

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

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

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

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

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

これらのステップを正常に実行したら、これを Cloud Functions の関数に変換する準備は完了です。

4. 構成ファイルを削除する

app.yaml ファイルは、Cloud Functions では使用されていない App Engine アーティファクトであるため、今すぐ削除してください。この処理は Cloud Functions では行われないため、この作業を行わなくても問題はありません。requirements.txt はモジュール 2 と同じであるため、これが唯一の構成変更です。

Python 2 App Engine アプリを Python 3 に移植する場合は、appengine_config.pylib フォルダがあれば削除します。これらは Python 3 ランタイムでは使用されない App Engine アーティファクトです。

5. アプリケーション ファイルを変更する

アプリケーション ファイルは main.py という 1 つしかないため、Cloud Functions に移動するために必要なすべての変更はこのファイルで行われます。

インポート

ここでは関数のみを使用するため、ウェブ アプリケーション フレームワークは必要ありません。ただし、便宜上、Python ベースの Cloud Functions が呼び出されると、必要に応じてコードで使用するリクエスト オブジェクトが自動的に渡されます。(Cloud Functions チームはこれを、関数に渡される Flask リクエスト オブジェクトとして選択しました)。

ウェブ フレームワークは Cloud Functions 環境には含まれないため、アプリが他の Flask 機能を使用していない限り、Flask からのインポートは行われません。関数への変換後もテンプレートのレンダリングがまだ行われているので、flask.render_template() を呼び出す必要があるため、Flask からインポートするため、これが実際に該当します。ウェブ フレームワークがないため、Flask アプリをインスタンス化する必要がないため、app = Flask(__name__) を削除します。変更の適用前と適用後のコードは、次のようになります。

変更前:

from flask import Flask, render_template, request
from google.cloud import ndb

app = Flask(__name__)
ds_client = ndb.Client()

変更後:

from flask import render_template
from google.cloud import ndb

ds_client = ndb.Client()

アプリ オブジェクト(app)またはその他のウェブ フレームワーク インフラストラクチャに依存している場合は、それらの依存関係をすべて解決して適切な回避策を見つけるか、使用を完全に削除するかプロキシを検索する必要があります。そうして初めて、コードを Cloud Functions の関数に変換できます。それ以外の場合は、App Engine を引き続き使用するか、Cloud Run 用にアプリをコンテナ化する方が適しています。

メインハンドラ関数のシグネチャを更新する

関数のシグネチャで必要な変更は次のとおりです。

  1. アプリを Cloud Functions の関数に変換した後は Flask は使用されないため、ルート デコレータを削除します。
  2. Cloud Functions は Flask Request オブジェクトをパラメータとして自動的に渡すため、その変数を作成します。サンプルアプリでは、これを request とします。
  3. デプロイされる Cloud Functions の関数に名前を付ける必要があります。メインハンドラは、それが何であるか(ルート アプリケーション ハンドラ)を表すために、App Engine で適切に root() という名前が付けられています。Cloud Functions の関数として、この名前を使用する意味はあまりありません。代わりに、visitme という名前で Cloud Functions の関数をデプロイするため、同じく Python 関数の名前として使用します。同様に、モジュール 4 と 5 でも Cloud Run サービスに visitme という名前を付けています。

更新前と変更後は次のとおりです。

変更前:

@app.route('/')
def root():
    'main application (GET) handler'
    store_visit(request.remote_addr, request.user_agent)
    visits = fetch_visits(10)
    return render_template('index.html', visits=visits)

変更後:

def visitme(request):
    'main application (GET) handler'
    store_visit(request.remote_addr, request.user_agent)
    visits = fetch_visits(10)
    return render_template('index.html', visits=visits)

これで、必要な更新はすべて完了です。行った変更はアプリケーションの「インフラストラクチャ」にのみ影響するできます。コアとなるアプリケーション コードに変更を加える必要はなく、アプリの機能は一切変更されていません。以下は、この点を説明するために行われた変更を画像で表したものです。

668f30e3865b27a9.png

ローカルでの開発とテスト

App Engine には dev_appserver.py ローカル開発用サーバーがありますが、Cloud Functions には Functions Framework があります。このフレームワークを使用すると、ローカルで開発とテストを行うことができます。コードは Cloud Functions にデプロイできるだけでなく、Compute EngineCloud Run などの他のコンピューティング プラットフォームにデプロイすることも、Knative をサポートするオンプレミスまたはハイブリッド クラウド システムにデプロイすることもできます。Functions Framework へのその他のリンクについては、以下をご覧ください。

6. ビルドとデプロイ

Cloud Functions へのデプロイは App Engine とは若干異なります。requirements.txt の外部で構成ファイルは使用されないため、コードに関する詳細情報をコマンドラインで指定する必要があります。次のコマンドを使用して、Python 3.10 で実行される新しい HTTP トリガー Cloud Functions をデプロイします。

$ gcloud functions deploy visitme --runtime python310 --trigger-http --allow-unauthenticated

出力は次のようになることが想定されます。

Deploying function (may take a while - up to 2 minutes)...⠛
For Cloud Build Logs, visit: https://console.cloud.google.com/cloud-build/builds;region=REGION/f5f6fc81-1bb3-4cdb-8bfe?project=PROJECT_ID
Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 256
buildId: f5f6fc81-1bb3-4cdb-8bfe
buildName: projects/PROJECT_ID/locations/REGION/builds/f5f6fc81-1bb3-4cdb-8bfe
dockerRegistry: CONTAINER_REGISTRY
entryPoint: visitme
httpsTrigger:
  securityLevel: SECURE_OPTIONAL
  url: https://REGION-PROJECT_ID.cloudfunctions.net/visitme
ingressSettings: ALLOW_ALL
labels:
  deployment-tool: cli-gcloud
name: projects/PROJECT_ID/locations/REGION/functions/visitme
runtime: python310
serviceAccountEmail: PROJECT_ID@appspot.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/uploads-853031211983.REGION.cloudfunctions.appspot.com/8c923758-cee8-47ce-8e97-5720a5301c34.zip
status: ACTIVE
timeout: 60s
updateTime: '2022-05-16T18:28:06.153Z'
versionId: '8'

関数がデプロイされたら、デプロイ出力の URL を使用してアプリにアクセスします。URL の形式は REGION-PROJECT_ID.cloudfunctions.net/visitme です。出力は、以前に App Engine にデプロイしたときと同じになるはずです。

2732ae9218f011a2.png

このシリーズの他の Codelab や動画と同様に、アプリのベースライン機能は変更されません。目的は、1 つのモダナイゼーション手法を適用し、アプリを以前と同じように動作させながら、新しいインフラストラクチャを活用することです。たとえば、以前の App Engine レガシー サービスから代替 Cloud スタンドアロン プロダクトに移行する場合や、このチュートリアルの場合のように、アプリを別の Google Cloud サーバーレス プラットフォームに移行する場合などです。

7. 概要/クリーンアップ

これで、この小さな App Engine アプリを Cloud Functions の関数に変換できました。別の適切なユースケースとして、大規模なモノリシック App Engine アプリを一連のマイクロサービスに分割し、それぞれを Cloud Functions の関数として作成します。これは、より「プラグアンドプレイ」を実現する、より現代的な開発手法です。コンポーネント(" JAM スタック)スタイル。「混在とマッチング」と「コードの再利用」という 2 つの目標がありますが、もう一つのメリットは、これらのマイクロサービスが時間の経過とともにデバッグされ続けることです。つまり、コードが安定し、全体的なメンテナンス費用を削減できます。

クリーンアップ

この Codelab を完了したら、課金が発生しないように、モジュール 2 の App Engine アプリを一時的または永続的に無効にできます。App Engine プラットフォームには無料の割り当てがあるため、使用量ティアを超えない限り、課金されることはありません。Datastore についても同様です。詳細については、Cloud Datastore の料金ページをご覧ください。

App Engine や Cloud Functions などのプラットフォームにデプロイすると、わずかなビルドとストレージの費用が発生します。一部のリージョンでは、Cloud BuildCloud Storage に独自の無料の割り当てがあります。ビルドはその割り当ての一部を消費します。特に地域にこのような無料枠がない場合は、潜在的な費用を最小限に抑えるためにストレージの使用量に注意してください。

残念ながら、Cloud Functions には機能。コードをバックアップして、関数を削除します。後でいつでも同じ名前で再デプロイできます。ただし、他の移行 Codelab を続行せず、すべてを完全に削除したい場合は、Cloud プロジェクトをシャットダウンしてください。

次のステップ

このチュートリアル以外にも、参照できる他の移行モジュールには、Cloud Run 用の App Engine アプリのコンテナ化が含まれます。モジュール 4 とモジュール 5 の Codelab へのリンクをご覧ください。

  • モジュール 4: Docker を使用して Cloud Run に移行する
  • Docker を使用して、Cloud Run で実行できるようにアプリをコンテナ化します。
  • この移行により、引き続き Python 2 を使用できます。
  • モジュール 5: Cloud Buildpack を使用して Cloud Run に移行する
  • Cloud Build を使用して Cloud Run で実行するようにアプリをコンテナ化します。
  • Docker、コンテナ、Dockerfile についての知識は何も必要ありません。
  • すでに Python 3 に移行しているアプリが必要です(Buildpacks では Python 2 はサポートされていません)。

他のモジュールの多くは、App Engine バンドル サービスから Cloud スタンドアロン サービスに移行する方法をデベロッパーに紹介することに重点を置いています。

コンテナ化がアプリケーション開発ワークフローの一部になっている場合、特に CI/CD(継続的インテグレーション/継続的デリバリーまたはデプロイ)パイプラインで構成されている場合は、Cloud Functions ではなく Cloud Run への移行を検討してください。Docker を使用してアプリをコンテナ化する場合はモジュール 4 を、コンテナ、Docker の知識、Dockerfile を使用せずにアプリをコンテナ化する場合はモジュール 5 をご覧ください。Cloud Functions と Cloud Run のどちらを検討しても、別のサーバーレス プラットフォームへの切り替えは任意です。変更を行う前に、アプリやユースケースに最適なオプションを検討することをおすすめします。

次に検討する移行モジュールに関係なく、Serverless Migration Station のすべてのコンテンツ(Codelab、動画、ソースコード(利用可能な場合))には、オープンソース リポジトリからアクセスできます。リポジトリの README には、検討すべき移行や関連する「順序」に関するガイダンスも用意されています。概要をまとめたものです

8. 参考情報

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

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

移行に関するリソース

以下の表に、モジュール 8(START)とモジュール 9(FINISH)のリポジトリ フォルダへのリンクを示します。これらは、すべての App Engine Codelab 移行用のリポジトリからもアクセスでき、ZIP ファイルのクローンを作成したりダウンロードしたりできます。

Codelab

Python 3

モジュール 2

コード

モジュール 11

コード

オンライン リソース

このチュートリアルに関連する可能性のあるオンライン リソースは次のとおりです。

App Engine

Cloud Functions

Cloud のその他の情報

動画

ライセンス

この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。