G-gen の佐々木です。当記事では Google Cloud (旧称 GCP) のサーバーレス コンピューティング プロダクトの1つである Google App Engine (GAE) を解説します。
- Google App Engine (GAE) とは
- App Engine アプリのコンポーネント
- インフラストラクチャ
- デプロイと実行環境
- スタンダード環境
- フレキシブル環境
- その他の Computing プロダクトとの比較
Google App Engine (GAE) とは
Google App Engine (GAE) は Google Cloud のプロダクトの中でも最初期から提供されている PaaS(Platform as a Service)であり、アプリケーションを稼働させるためのマネージドな実行基盤を提供するサービスです。GAE とも略されますが、当記事では以降、App Engine と記載します。
App Engine ではアプリケーションのコードと設定ファイルをデプロイするだけで、Google Cloud 上でアプリケーションを実行することができます。ユーザーが VM やコンテナといった実行基盤の運用をする必要がなく、オートスケーリングや障害発生時のオートヒーリングなどの機能が提供されます。
- 参考 : App Engine
App Engine アプリのコンポーネント
アプリケーション
当記事では、App Engine にホストしたアプリケーションのことを App Engine アプリと呼びます。
App Engine アプリを開発するには、まずプロジェクト内にアプリケーションというリソースを作成します。App Engine はこのアプリケーションを最上位のリソースとして、サービス、バージョン、インスタンスというリソースが連なる階層型のリソース構成となっています。
アプリケーションはサービス以下のリソースを束ねるだけでなく、App Engine アプリの設定、認証情報、アプリケーションのメタデータのコレクションを作成、管理することができるコンポーネントであり、それらはアプリケーション作成時に指定したリージョンに格納されます。
サービス
アプリケーションは最低1つのサービスリソースを持ちます。App Engine アプリを単一のサービスで実行することもできますが、複数のサービスで1つのアプリを構成することで、マイクロサービスのようにアプリの機能を分離することができます。
各サービスはアプリのソースコードとそれに対応する App Engine 構成ファイルで構成されます。サービスをデプロイするたびに、サービス内にバージョンが追加されていきます。
バージョン
デプロイされたサービスはバージョンリソースとしてバージョニングされており、バージョン間でトラフィック移行を行うことで、特定のバージョンに対してトラフィックのルーティングを素早く切り替えることができます。
また、トラフィック分割により複数バージョンに対してトラフィックをルーティングすることもできます。これらの機能により、App Engine アプリのテストやロールバックを容易に行うことができます。
インスタンス
バージョンは1つ以上のインスタンスで実行され、負荷に応じてスケーリングすることができます。
インスタンスの実行基盤は App Engine の実行環境(後述)により異なります。スタンダード環境では Google のインフラストラクチャ上で実行されるコンテナインスタンス、フレキシブル環境ではユーザープロジェクトの VPC で起動される Compute Engine 仮想マシン上の Docker コンテナで実行されます。
後述する App Engine の実行環境によって、インスタンスの実行基盤は異なります。
インフラストラクチャ
可用性
App Engine はリージョナルサービスであり、App Engine アプリを実行するインフラストラクチャはユーザーが指定したリージョンに配置され、自動的にリージョン内のすべてのゾーンで冗長化されます。
参考 : App Engine のロケーション
ストレージ
App Engine アプリは基本的にインスタンスに状態を持たない(ステートレス)設計となるため、データは App Engine の外に保存します。
リレーショナルデータベースとして Cloud SQL、NoSQL データベースとして Firestore、オブジェクトストレージとして Cloud Storage の使用が推奨されています。
- 参考 : データとファイルのストレージについて
また、スタンダード環境では /tmp ディレクトリに対して一時ファイルの読み書きを行うことができます。このディレクトリに保存されたファイルはすべてインスタンスのメモリに格納されます。
- 参考 : 一時ファイルの読み取りと書き込み
セキュリティ
他の Google Cloud サービスへのアクセス制御
App Engine アプリでは、バージョン単位でサービスアカウントを設定することで、他の Google Cloud サービスのアクセス権限を付与することができます。
Compute Engine 同様、編集者(role/editor)
ロールをもつデフォルトのサービスアカウントが提供されていますが、最小権限の原則に従ったユーザー管理のサービスアカウントを使用することが推奨されています。
- 参考 : アクセス制御の設定(スタンダード環境)](https://cloud.google.com/appengine/docs/standard/access-control?hl=ja&tab=go)
カスタムドメインの使用
App Engine アプリでは、デフォルトで生成される appspot.com
ドメインの URL を使用することで HTTPS によるアクセスを行うことができます。
また、App Engine の機能でマネージド SSL 証明書を発行することで、HTTPS アクセスにカスタムドメインを使用することもできます。
- 参考 : アプリのセキュリティの概要
上り(内向き)設定
以下の3種類の上り(内向き)設定により、App Engine アプリへのネットワークアクセスを制限することができます。
設定名 | 許可するアクセス元 |
---|---|
内部 | ・同一プロジェクト内の VM ・共有 VPC ・サーバーレス VPC アクセスコネクタ(スタンダード環境) |
内部と Cloud Load Balancing | ・ 内部の設定で許可されているもの ・外部アプリケーションロードバランサ |
すべて | すべて |
デフォルトでは、インターネット上のすべてのリソースが App Engine アプリにアクセスすることができます。
- 参考 : 上り(内向き)設定
App Engine ファイアウォール
App Engine ファイアウォールを使用することで、App Engine アプリにリクエストを送信できる IP アドレス範囲を制限することができます。
Compute Engine のファイアウォールルールと異なり、App Engine のファイアウォールは受信トラフィック(上り/内向き)に対してのみ適用されます。
対象となる IP アドレス範囲ごとに許可/拒否のルールを作成し、ルールには優先度(1 ~ 2147483647)を設定します。デフォルトでは、すべての IP アドレスからのアクセスが許可する優先度最低(2147483647)のルールのみ登録されています。
モニタリング・ロギング
App Engine は Cloud Monitoring と統合されており、コンピューティングリソースの使用率やレスポンスのレイテンシ、実行中のインスタンス数などのメトリクスがデフォルトで提供されます。
また Cloud Logging では、App Engine のログとして以下の2種類のログを収集できます。
ログの種類 | 説明 |
---|---|
リクエストログ | App Engine アプリに送信されるリクエストのログ。自動で収集される。 |
アプリログ | アプリケーションのログ。アプリで使用する言語ごとに用意された方法でログエントリを作成する必要がある。 |
アプリログついては、stdout
または stderr
にテキスト文字列を送信するだけで Cloud Logging のログエントリを作成することができます。しかし、重要度でログをフィルタリングする必要がある場合などはログを構造化データとしてフォーマットする必要があります。
- 参考 : ログの書き込みと表示
デプロイと実行環境
アプリケーションのデプロイ
App Engine では、app.yaml
という設定ファイルに実行環境やランタイム、コンピューティングリソースなどの構成(それぞれ後述)を記述し、コードと一緒にデプロイすることでアプリケーションを実行することができます。
以下は Python を使用する App Engine アプリの app.yaml ファイルの例です。使用ランタイムやインスタンスクラス、リクエストの URL パターンごとの処理方法などが記述されています。
runtime: python312 instance_class: F2 env_variables: BUCKET_NAME: "example-gcs-bucket" handlers: # Matches requests to /images/... to files in static/images/... - url: /images static_dir: static/images - url: /.* secure: always redirect_http_response_code: 301 script: auto
設定ファイルの記述内容は実行環境により異なります。詳しくは以下のドキュメントを参照してください。
2つの実行環境
App Engine でアプリケーションを実行する場合、スタンダード環境とフレキシブル環境のどちらかを選択します。
スタンダード環境ではサポートされる言語の種類とバージョンに制限がある代わりに、Cloud Functions や Cloud Run のようなサーバーレスの実行基盤が利用できます。アプリケーションは gvisor ベースのコンテナインスタンスで実行され、高速なスケーリングとゼロスケーリング(インスタンス数を0にスケールインする)によるコスト削減が大きなメリットとなります。
フレキシブル環境では、マネージドな Compute Engine 仮想マシン上で Docker コンテナとしてアプリケーションが実行されます。スケーリングの単位が仮想マシンのため、スタンダード環境のようなスケーリングのメリットはありませんが、サポートされる言語の制限がなく構成の自由度の高さがメリットとなります。
実行基盤がサーバーレスか、Compute Engine 仮想マシンかの違いにより、実行環境ごとの機能に違いがあります。
以下の表は実行環境ごとの違いを一部抜粋したものです。
機能 | スタンダード環境 | フレキシブル環境 |
---|---|---|
インスタンスの起動時間 | 秒単位 | 分単位 |
リクエストの最大タイムアウト | ランタイムとスケーリングタイプ(後述)によって異なる。(参考) 自動スケーリングの場合は基本的に10分 |
60 分 |
バックグラウンドプロセス | × | ○ |
SSH 接続 | × | ○ |
ゼロスケーリング | ○ | × |
ローカルディスクへの書き込み | Python 2.7、PHP 5.5 以外のランタイムで /tmp ディレクトリが利用可能 | VM のエフェメラルディスクを利用可能 |
ランタイムの変更 | × | ○ |
デプロイ時間 | 秒単位 | 分単位 |
Websocket | × | ○ |
料金 | インスタンス時間 | vCPU、メモリ、永続ディスクの使用量 |
実行環境(スタンダード/フレキシブル)はサービスごとに選択することができ、1つのアプリケーションに異なる実行環境のサービスを混在させることができます。これにより、各サービスの役割に応じて適切な実行環境を選択することができます。
スタンダード環境
ランタイム
ランタイム環境の世代について
スタンダード環境ではフレキシブル環境と比較して、ランタイム環境としてサポートされている言語や API、ファイルシステムへのアクセス可否などの制限があります。
ランタイム環境には第1世代と第2世代があります。これから App Engine を利用する場合は、機能が大幅に改善されている第2世代を使用することになるでしょう。
スタンダード環境の世代間比較については以下のドキュメントを参照してください。当記事では特に指定のない限り、「スタンダード環境」と記載がある場合は第2世代を指しています。
第1世代ランタイム(レガシーランタイム)
第1世代は App Engine リリース当初から存在し、レガシーランタイム と呼ばれます。
以下のように、ランタイムとしてサポートされている言語のバージョンが古く、それぞれの言語のコミュニティで既に管理されていないバージョンが含まれています。
- Python 2.7
- Java 8
- PHP 5.5
- Go 1.11
これらのランタイムは2024年1月31日のサポート終了がアナウンスされています。公式ドキュメントでは第 2世代ランタイムへの 移行ガイド が提供されています。
第2世代ランタイム
第2世代ランタイムでは以下の言語がサポートされており、ベースとなる OS はすべて Ubuntu となっております。
サポートされている言語のバージョンについては、以下のページから最新の情報を確認できます。
- 参考 : ランタイム サポート スケジュール
ランタイムのライフサイクル
ランタイムは プレビュー
→ 一般提供(GA)
→ サポート終了
→ 非推奨
→ 廃止
のライフサイクルを辿ります。このうち一般提供(GA)の期間において、セキュリティやバグの修正などの定期的なアップデート、仕様変更の通知(リリースノート)、テクニカルサポートの提供が行われます。
サポート終了期間に入る90日前に、Google Cloud からの通知を受け取ることになります。ランタイムのサポート終了日になってもアプリケーションは引き続き実行されますが、Google Cloud によるセキュリティのアップデートが行われず、テクニカルサポートの対象外となってします。また、サポートが終了したランタイムを使用するアプリケーションは作成、更新ができなくなります。
したがって、ランタイムのアップグレードは定期的に行うことが強く推奨されています。
非推奨の期間に入って以降も基本的にはアプリケーションをそのまま実行できますが、重大なセキュリティ脆弱性が発覚した場合など、事前の通知なしに無効化される可能性があります。
- 参考 : ランタイム ライフサイクル
スケーリングタイプ
スケーリングタイプとは
スタンダード環境では3種類のスケーリングタイプが提供されており、後述のインスタンスクラスによって使用できるスケーリングタイプが異なります。
以下のように、スケーリングタイプによってリクエストのタイムアウトやスケーリング方式などが異なります。動的スケーリングについては後述します。
- | 自動スケーリング | 基本スケーリング | 手動スケーリング |
---|---|---|---|
リクエストのタイムアウト | 10分 | 24時間 | 24時間 |
スケーリング | 動的スケーリング | 動的スケーリング | 構成ファイルでインスタンス数を指定 |
スケーリングタイプごとの詳細な比較については以下のドキュメントを参照してください。
- 参考 : インスタンスの管理方法
動的スケーリング
基本スケーリングもしくは自動スケーリングを使用する場合、受信リクエストの量に応じたインスタンス数のスケーリングを自動で行うことができます。
なお、動的スケーリングの仕様は基本スケーリングと自動スケーリングで異なります。
基本スケーリングでは、受信したリクエストを処理できるインスタンスがない場合にのみ新しいインスタンスが起動します。したがって、新しいインスタンスが立ち上がるまでの間、受信したリクエストを処理できない場合があります。
自動スケーリングでは、スケーリングのトリガーとして以下の3つが使用できます。
トリガー | 説明 |
---|---|
CPU 使用率 | CPU 使用率の閾値を事前に設定し、それを超えたときに新しいインスタンスを起動する。 |
スループット | スループットの閾値を事前に設定し、それを超えたときに新しいインスタンスを起動する。 |
同時リクエスト数 | インスタンスが処理できる最大同時リクエスト数を事前に設定し、それを超えたときに新しいインスタンスを起動する。 |
自動スケーリングでは基本スケーリングと異なり、CPU 使用率やスループットを基準としてスケーリングをトリガーすることで、既存のインスタンスがリクエストを処理する余地を残したまま新しいインスタンスを用意することができます。
コールドスタート
App Engine では、以下のような状況でリクエストに対するレイテンシが発生する可能性があります。
- スケーリングによって新たなインスタンスを起動するとき
- サービスの別のバージョンをデプロイしたとき
- 基盤となるインフラストラクチャのメンテナンスが行われるとき
これは、新たに起動されたインスタンスがリクエストを処理するために、アプリケーションのコードやライブラリを事前に読み込む必要があるためです。
ウォームアップリクエスト
スケーリングタイプが自動スケーリングの場合のみ、ウォームアップリクエストを有効化することで、App Engine がスケールアウトのタイミングを事前に検知し、インスタンスが実際に必要になる前にコードの読み込みを行うことができます。
ウォームアップリクエストを有効化するには、設定ファイル(app.yaml)への追記と、コードにウォームアップリクエストを処理するハンドラを実装しておく必要があります。詳細については以下のドキュメントを参照してください。
なお、ウォームアップリクエストは常に実行されることが保証されているわけではありません。インスタンス数が0から1になるときや、リクエスト数のスパイクがあった場合などはコールドスタートが発生してしまいます。ただし、ウォームアップリクエストが有効化されている場合は、すでに実行されているインスタンスに対してリクエストを優先的にルーティングし、コールドスタートの影響をできる限り少なくするような仕様になっています。
インスタンスクラス
スタンダード環境の App Engine では、アプリケーションを実行するインスタンスのコンピューティングリソースを App Engine 独自のインスタンスクラスで指定します。
選択できるインスタンスクラスは以下の通りで、クラスによって使用可能なスケーリングタイプが異なります。
インスタンスクラス | メモリ | CPU | サポートされているスケーリングタイプ |
---|---|---|---|
F1(デフォルト) | 384 MB | 600 MHz | 自動 |
F2 | 768 MB | 1.2 GHz | 自動 |
F4 | 1,536 MB | 2.4 GHz | 自動 |
F4_1G | 3,072 MB | 2.4 GHz | 自動 |
B1 | 384 MB | 600 MHz | 手動、基本 |
B2(デフォルト) | 768 MB | 1.2 GHz | 手動、基本 |
B4 | 1,536 MB | 2.4 GHz | 手動、基本 |
B4_1G | 3,072 MB | 2.4 GHz | 手動、基本 |
B8 | 3,072 MB | 4.8 GHz | 手動、基本 |
VPC ネットワークへの接続
Cloud Run や Cloud Functions と同様に、スタンダード環境のインスタンスは VPC の外側にあり、Cloud SQL、Memorystore、Cloud NAT などの VPC リソースに対するプライベート IP を用いた接続にはサーバーレス VPC アクセスの設定が必要になります。
以下の図は、VPC リソースである Cloud SQL のインスタンスに接続する場合の構成です。ユーザー VPC に作成したコネクタインスタンスを経由してプライベート IP を用いた接続を行っています。
コネクタインスタンスは常時起動となっており、起動時間ぶんのコストが常に発生してしまいます。したがって VPC に接続する必要があるケースでは、VPC 内に App Engine インスタンスを起動することができるフレキシブル環境の利用も検討する必要があるでしょう。
- 参考 : VPC ネットワークへの接続
フレキシブル環境
ランタイム
フレキシブル環境では以下のランタイムがサポートされています。ベースとなる OS はスタンダード環境同様に Ubuntu ですが、設定ファイル(app.yaml)でバージョンを指定することができます。
スタンダード環境よりも使用可能ランタイムの種類が多いほか、カスタムランタイムとしてユーザが用意した Docker イメージを使用することができます。
- 参考 : App Engine フレキシブル環境
スケーリングタイプ
フレキシブル環境では自動スケーリングと手動スケーリングの2種類のスケーリングタイプを使用することができます。
スタンダード環境と異なる点として、スケーリングのたびに Compute Engine 仮想マシンが新規に起動されるためスケーリング速度が遅く、また最低1つのインスタンスを常時起動している必要があります(ゼロスケールできない)。
マシンタイプ
フレキシブル環境にはスタンダード環境のようなインスタンスクラスは存在せず、設定ファイル(app.yaml)で指定した CPU とメモリの量に基づいて Compute Engine のマシンタイプが割り当てられます。
したがって、スタンダード環境よりもコンピューティングリソースの量を細かく調整することができます。
VPC ネットワークへの接続
フレキシブル環境のインスタンスは Compute Engine 仮想マシンであり、ユーザーが作成した VPC 内で起動します。したがって スタンダード環境のようにサーバーレス VPC アクセスを設定することなく VPC リソースにプライベート IP アドレスで接続することができます。
その他の Computing プロダクトとの比較
以下の記事で、Google Cloud の Computing プロダクトの比較解説を行っています。
サーバーレスな Web アプリケーション実行基盤としては、Cloud Run と比較することが多いと思われます。
比較的新しいプロダクトであり積極的にアップデートが行われている Cloud Run と比較すると、リリースから15年以上の実績をもつ App Engine はいわゆる枯れたプロダクトであると言えます。したがって、App Engine のほうがユーザーによるナレッジの蓄積が多く、アップデートによる仕様変更に振り回されにくいプロダクトであるといえるでしょう。
また、Cloud Run はコンテナの利用が必須となるため、より手軽にアプリケーションをデプロイしたい場合の選択肢となります。
佐々木 駿太 (記事一覧)
G-gen最北端、北海道在住のクラウドソリューション部エンジニア
2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2024に選出。好きなGoogle CloudプロダクトはCloud Run。
趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。
Follow @sasashun0805