入門!Cloud Runのススメ

記事タイトルとURLをコピーする

G-gen の佐々木です。当記事では、Google Cloud のサーバーレス コンテナコンピューティング サービスである Cloud Run で簡単なサービスを作成する方法を解説します。また、サービスの基本的な設定項目や、よく使用される機能や構成についても解説していきます。

Cloud Run について

Cloud Run は Google Cloud のマネージドなコンテナ実行環境でアプリケーションを実行することができる、サーバレス コンテナコンピューティング サービスです。

Cloud Run には Cloud Run servicesCloud Run jobsCloud Run functions(旧称 : Cloud Functions)、Cloud Run worker pools の4種類がありますが、当記事ではウェブアプリケーションの実行環境として主に利用される Cloud Run services の使い方を解説していきます。

当記事では以降、「Cloud Run」という記述は Cloud Run services を指します。

また、当記事の内容は、Cloud Run の基本的な使い方(始め方)に重点を置いた解説となるため、サービスの仕様に関する解説については以下の記事をご一読ください。

blog.g-gen.co.jp

なお当記事は2025年3月に執筆したものであり、設定項目の名称やコンソールの画面構成は、現在のものと異なる場合があります。

gcloud CLI の準備

当記事は Cloud Run の入門記事ということで、GUI で可能な操作は Google Cloud コンソールを使用して解説を行います。

一部の操作については gcloud コマンドを使用するため、以下のドキュメントを参考に gcloud コマンドのインストールを行ってください。

インストール後、以下のコマンドで、gcloud コマンドを実行する Google アカウントの認証を行ってください。

# gcloud コマンドのユーザー認証を行う
$ gcloud auth login

また、コマンド実行時に使用される、デフォルトのプロジェクトを設定しておきます。

# デフォルトのプロジェクトを設定する
$ gcloud config set project {プロジェクトID}

Artifact Registry の準備

まず、Google Cloud コンソールを使用して、Artifact Registry のリポジトリを作成します。

Artifact Registry は、コンテナイメージ等のビルドアーティファクトを管理するためのリポジトリを提供するサービスです。Cloud Run にデプロイするコンテナイメージは、Artifact Registry のリポジトリで管理されているものである必要があります。

Artifact Registry のコンソールで「リポジトリの作成」を押下します。

Artifact Registry コンソールからリポジトリを作成する

作成画面で任意の名前とリージョンを指定して、画面最下部の「作成」を押下します。当記事では myrepo という名前で asia-northeast1 リージョンにリポジトリを作成します。

リポジトリの作成画面

使用するコード(Python)

記事執筆時の環境について

当記事のサンプルコードは以下の環境を使用して動作を確認しています。

# OS
$ head --l 1 /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
  
# Python のバージョン
$ python -V
Python 3.12.0
  
# Google Cloud CLI のバージョン
$ gcloud version | head --l 1
Google Cloud SDK 513.0.0

なお、当記事の内容は Python がインストールされていない環境でも実施することが可能です。

サンプルコードの構成

当記事では、公式ドキュメントのサンプルコードを元にしたウェブアプリケーションを Cloud Run にデプロイしていきます。

サンプルコードとして、以下の3つのファイルを用意します。

.
├── Dockerfile
├── main.py
└── requirements.txt

main.py

サンプルコードは Flask によるシンプルなウェブアプリケーションとなっています。

このアプリケーションに対して HTTP リクエストがあると、Hello {環境変数 NAMEの値}! が返ります。環境変数が設定されていない場合は Hello World! が返るようになっています。

import os
  
from flask import Flask
  
app = Flask(__name__)
  
  
@app.route("/")
def hello_world():
    """Example Hello World route."""
    name = os.environ.get("NAME", "World")
    return f"Hello {name}!"
  
  
if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

requirements.txt

requirements.txt は以下のように記述します。

Flask==3.1.0
gunicorn==23.0.0
Werkzeug==3.1.3

Dockerfile

Cloud Run にはアプリケーションのコンテナイメージをデプロイする必要があるため、ビルド用の Dockerfile を用意します。

FROM python:3.12-slim
  
ENV PYTHONUNBUFFERED True
  
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
  
RUN pip install --no-cache-dir -r requirements.txt
  
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

なお、Cloud Run では Dockerfile を使用せず、ソースコードのみを使用してデプロイすることもできます。

この場合、裏側では Google Cloud のサーバーレス CI/CD プラットフォームである Cloud Build によってコンテナイメージのビルドが自動で行われています。

ビルドの際、ベースイメージは Google 管理の安全なものが使用されるため、ビルドの内容を細かくカスタマイズする必要がない場合は、こちらの方法を検討してみてもよいでしょう。

ソースコードからのデプロイの詳細については、以下のドキュメントをご一読ください。

コンテナイメージの準備

コンテナイメージの要件

ここからは、Cloud Run にデプロイするアプリケーションのコンテナイメージを作成していきます。

Cloud Run で使用できるコンテナイメージは、以下のような要件を満たしている必要があります。

  • コンテナイメージ内の実行可能ファイルは、Linux 64 ビット用(Linux ABI x86_64)にコンパイルする必要がある。
  • リクエストの送信先ポート(デフォルトのポートは 8080 )で 0.0.0.0 のリクエストをリッスンする必要がある。
  • リクエストを受信してから Cloud Run のタイムアウト設定で指定された時間内に、レスポンスを返す必要がある。

その他、コンテナイメージの詳細な要件は以下のドキュメントをご一読ください。

ビルド環境について

Cloud Run にデプロイできるコンテナイメージは x86_64 アーキテクチャに対応しているため、Mac 等の arm64 アーキテクチャ環境でコンテナイメージをビルドする場合、コンテナイメージのビルド時に注意が必要です。

このような環境で docker build コマンドでイメージをビルドする場合は、x86_64 アーキテクチャを使用するように指定する必要があります。

# x86_64 アーキテクチャを明示的に指定する
$ docker build --platform linux/amd64 -t {イメージタグ} .

コンテナイメージのビルドに Cloud Build を使用する場合、Google Cloud のサーバーレス環境でビルドが行われます。デフォルトで x86_64 アーキテクチャが使用されるため、上記のビルド時の考慮は必要ありません。

当記事では、Cloud Build を使用する方法でビルドを行っていきます。

コンテナイメージのビルド

イメージ名について

Cloud Build を使用してコンテナイメージをビルドし、はじめに作成した Artifact Registry のリポジトリにプッシュします。Cloud Build を使用する場合、ビルドとプッシュは1つのコマンドで実行可能です。

コンテナイメージ名は以下のような形式にする必要があります(docker コマンドを使用する場合も同様)。

{リポジトリのリージョン}-docker.pkg.dev/{プロジェクトID}/{リポジトリ名}/{任意のイメージ名}:{タグ(省略可)}

このうち、{リポジトリのリージョン}-docker.pkg.dev/{プロジェクトID}/{リポジトリ名} の部分は、Artifact Registry のコンソールから文字列としてコピーすることができます。

イメージ名に使用するリポジトリのパスをコピーする

ビルドとプッシュ

Dockerfile があるディレクトリ上で、gcloud builds submit コマンドを実行します。これにより、用意したファイルが Cloud Build に送信され、Google Cloud のサーバーレス環境上でコンテナイメージのビルドと、Artifact Registry へのプッシュが行われます。

# Cloud Build でビルドとプッシュを行う
$ gcloud builds submit --tag {リポジトリのリージョン}-docker.pkg.dev/{プロジェクトID}/{リポジトリ名}/{任意のイメージ名}:{タグ(省略可)}

当記事ではイメージ名を hello、タグを v1.0 としてイメージをビルドします。 Artifact Registry のリポジトリ myrepoasia-northeast1 リージョンにあるため、実行するコマンドは以下のようになります(プロジェクトは仮に myproject とします)。

# コマンド実行例
$ gcloud builds submit --tag asia-northeast1-docker.pkg.dev/myproject/myrepo/hello:v1.0

ビルド完了後、Artifact Registry のリポジトリにコンテナイメージがプッシュされていることを確認します。

Artifact Registry にコンテナイメージがプッシュされている

Cloud Run サービスのデプロイ

最小限の設定でデプロイ

Google Cloud のコンソールから、最小限の設定のみを行ってデプロイを行います。

GUI を仕様した Cloud Run のデプロイは、Cloud Run のコンソールや、Artifact Registry に格納されたコンテナイメージから行うことができます。

Cloud Run のコンソールからデプロイする場合

Artifact Registry のコンソールからデプロイする場合

「コンテナイメージの URL」項目で Artifact Registry にプッシュしたコンテナイメージを指定します。デフォルトでは、コンテナイメージの名前がデプロイする Cloud Run サービスの名前になります(変更可能)。

デプロイしたコンテナイメージを選択する

「リージョン」は初期状態の us-central1 でもよいですが、asia-northeast1 に変更しておきます。

また「認証」項目で 未認証の呼び出しを許可 を選択します。

リージョンと認証を設定後、「作成」を押下してサービスを作成する

コンソール画面最下部の「作成」を押下し、サービスをデプロイします。

動作確認

少し待つとサービスのリビジョン(デプロイごとに作成される、サービスのバージョン)が作成されます。

Cloud Run はこのリビジョンの単位でサービスのバージョン管理を行うことができ、新しくデプロイしたリビジョンに問題があるような場合に、すぐに前のリビジョンにロールバックすることが可能です。

サービスの詳細画面でサービス用に生成された HTTPS エンドポイントが表示されているので、ブラウザからアクセスしてみます。

HTTPS エンドポイントからサービスにアクセスする

コンテナインスタンスが起動し、Hello World! が返ってきます。

Cloud Run にデプロイしたウェブアプリケーションのレスポンス

デプロイ時のよくあるエラー

Cloud Run のデプロイ時、以下のエラーが発生してデプロイが失敗することがあります。

デプロイ時のよくあるエラー

The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable within the allocated timeout. This can happen when the container port is misconfigured or if the timeout is too short. The health check timeout can be extended. Logs for this revision might contain more information. Logs URL: {Cloud Logging の URL} For more troubleshooting guidance, see https://cloud.google.com/run/docs/troubleshooting#container-failed-to-start

このエラーは Cloud Run の設定ではなく、コンテナイメージ側の問題でアプリケーションが正常に実行できていない可能性が非常に高いです。  

トラブルシューティングとして、まずは Cloud Logging に出力されているエラーログや Dockerfile の記述内容を確認したり、開発環境の Docker 上でコンテナが正常に実行できるか確認したりするとよいでしょう。

デプロイ時の基本的な設定項目について

ここでは、Cloud Run のデプロイ時に設定できる基本的な項目について解説します。

認証

「構成」の「認証」項目では、Cloud Run 上のサービスへのアクセス時に IAM 認証を必要とするかどうかを設定します。

サービス作成画面の「認証」項目

一般公開するサービスであれば 未認証の呼び出しを許可 を設定しますが、Cloud Run にデプロイしたアプリケーションが他のサービスのバックエンドとして使用される場合や、特定のユーザーのみにサービスを公開したい場合(後述の「サービスに対するアクセスの制御」を参照)に 認証が必要 に設定することがあります。

なお、ここで 認証が必要 に設定した場合は、ブラウザからサービスのエンドポイントを使用して直接アクセスすることができなくなります。詳細は以下の記事をご一読ください。

また、認証の設定は、サービスの編集画面から設定し直すことができません。サービス一覧画面で対象のサービスを選択し、「権限」から設定を行います。

未認証の呼び出しを許可 から 認証が必要 にしたい場合、「Cloud Run 起動元」ロールが付与されている「allUsers」を削除します。

「認証が必要」に設定する場合

認証が必要 から 未認証の呼び出しを許可 にしたい場合、「プリンシパルを追加」を押下し、「allUsers」に対して「Cloud Run 起動元」ロールを付与します。

「プリンシパルを追加」からサービスに対するアクセス権を設定する

「未認証の呼び出しを許可」に設定する場合

Ingress

Ingress の設定はサービスに対してどこからアクセスできるかを大まかに設定できます。

サービス作成画面の「Ingress」項目

以下の3パターンがあるため、ユースケースに応じて設定します。

設定値 説明
すべて インターネットからサービスにアクセスする場合に設定する。
内部(外部アプリケーション ロードバランサからのトラフィックを許可する) カスタムドメインを設定する場合など、インターネットからロードバランサ経由でサービスにアクセスする場合に設定する。
内部 Google Cloud の他のサービス(例:Pub/Sub、他の Cloud Run など)からサービスにアクセスする場合に設定する。

CPU・メモリ・最大同時リクエスト数

CPU、メモリ、最大同時リクエスト数の設定は、Cloud Run のスケーリングにかかわる非常に重要な項目です。

サービス作成画面の「リソース」項目(CPU・メモリ)

サービス作成画面の「リクエスト」項目(インスタンスあたりの最大同時リクエスト数)

これらの設定値は、Cloud Run のコンテナインスタンス1つあたりが使用するコンピューティングリソースと、同時に処理できる最大リクエスト数を定義します。

Cloud Run では、1分間の平均 CPU 使用率と同時リクエスト数を元に、起動するコンテナインスタンスの数を制御しています。

CPU 使用率とスケーリングの関係は以下のようになっています。

  • 各コンテナインスタンスの平均 CPU 使用率が 60% に維持されるようにインスタンス数が調整される。

これに加えて、同時リクエスト数の上限を超える場合にインスタンス数の調整が行われます。そのため、同時リクエスト数の上限値が低い場合、CPU 使用率にまだ余裕があるにもかかわらず、コンテナインスタンスのスケールアウトが行われてしまう可能性があります。

Cloud Run は基本的に「コンピューティングリソースの設定値 × コンテナインスタンスの実行時間」で料金が発生するため、CPU が 20% しか使用されていないのにスケールアウトが起こってしまうと、40% ぶんの無駄が料金が発生してしまいます(スケールアウト基準値の 60% - 20%)。

したがって、設定する値は、平均 CPU 使用率が 50~60% になるちょうどよい値が理想となります。これは、サービスの初回デプロイ時に決定するのは非常に難しいため、サービス運用開始後に継続してモニタリングを行い、それぞれ調整していく必要があります。

最小インスタンス数

Cloud Run の大きな特徴として、サービスの最小インスタンスを 0 にできる点があります。この特徴は一般に「ゼロスケール」と呼ばれます。

ゼロスケールは、サービスに対するリクエストがないときはインスタンスが起動していないため、料金が発生しないことが大きなメリットとなります。

その反面、ゼロスケールのデメリットとして、最初のリクエストの処理にコンテナインスタンスの起動時間ぶんのレイテンシが発生してしまうコールドスタートがあります。

コールドスタートによるレイテンシが許容できない場合は、最小インスタンス数を 1 以上にすることで、コンテナインスタンスを常に起動した状態にします。この場合、当然ながらゼロスケールの料金メリットは享受できなくなります。

サービス作成画面の「サービスのスケーリング」項目(インスタンスの最小数)

また Cloud Run には、コンテナインスタンスの起動時のみインスタンスに割り当てられる CPU を一時的に増やす「起動時の CPU のブースト」という機能があります。最小インスタンス数を増やす前に、まずはこの機能でレイテンシが緩和されるか確認するとよいでしょう(デフォルトで有効になっている)。

「起動時の CPU ブースト」を設定する

コールドスタートの詳細については、以下の記事をご一読ください。

リクエストのタイムアウト

「リクエストのタイムアウト」項目では、1つのリクエストの処理に使用できる時間を設定します。ここで設定した時間までにリクエストが完了しないと HTTP 504 エラーが返ります。タイムアウトは 1 ~ 3600(秒) で設定できます。

サービス作成画面の「リクエスト」項目(リクエストのタイムアウト)

Cloud Run 側のタイムアウト設定を長くしていても、アプリケーションのフレームワーク側でタイムアウトの設定値が Cloud Run よりも短くなっている場合があるため注意しましょう。

サービスアカウント

Cloud Run で実行しているアプリケーションから他の Google Cloud サービスを利用する場合、コンテナインスタンスに紐づけられたサービスアカウントを使用してサービスの認証が行われます。

デフォルトでは、「Default compute service account」というサービスアカウントが設定されています。これは Compute Engine のデフォルトのサービス アカウントと呼ばれるもので、Compute Engine や Cloud Run のようなコンピューティング サービスにおいて、デフォルト値として設定されているサービスアカウントです。

コンテナインスタンスに紐づけるサービスアカウントの設定

デフォルトのサービスアカウントは非常に強い権限を持っており、ほとんどのサービスにアクセスすることができてしまいます。そのため、最小権限の原則に従って、サービスに必要な権限のみを付与したサービスアカウントを作成することが推奨されます。

コンテナの環境変数

Cloud Run では環境変数を Key-Value 形式で設定することができ、コンテナの環境変数としてコードからアクセスできます。

当記事のサンプルコードは NAME 環境変数を利用するようになっているため、サービスの編集画面から NAME をキーとする環境変数を設定してみます。

コンテナの環境変数を設定する

リビジョンの再デプロイ後、ブラウザからサービスにアクセスします。環境変数が反映され、Hello, {環境変数の値}! が返ってきます。

設定した環境変数が反映されている

Cloud Run でよく使用される機能や構成

ここからは、Cloud Run でサービスを提供する際に、よく使用される機能や構成を紹介します。

カスタムドメインの使用

Cloud Run でサービスをデプロイすると、サービスにアクセスするための .run.app ドメインの HTTPS エンドポイントが2つ発行されます(参考)。

会社のドメイン等、任意のドメインを使用してサービスにアクセスできるようにするためには、Cloud Run の前段に外部アプリケーションロードバランサ(旧称 : 外部 HTTP(S) ロードバランサ)を配置し、ロードバランサに対してカスタムドメインを構成する方法が一般的です。

カスタムドメインで Cloud Run のサービスにアクセスできるようにする

具体的な設定方法については、以下の記事の「HTTPS Load Balancing の設定」を参照してください。

サービスに対するアクセスの制御

Identity-Aware Proxy(IAP) を使用することで、許可された Google アカウントのみがサービスにアクセスできるように構成することができます。

IAP を使用してアクセス制御を行う場合、Cloud Run で直接 IAP を有効化する方法か、Cloud Run の前段にあるロードバランサで IAP を有効化する方法のいずれかを選択します。

Cloud Run に対して直接 IAP を有効化するほうがシンプルな構成となりますが、前述の通り、ロードバランサを使用する場合はカスタムドメインを設定することができます。

また、ロードバランサではクラウド型 WAF である Cloud Armor を使用することで、サービスのアクセス元 IP アドレスを制限することも可能です。

ライトなユースケースでは Cloud Run で IAP を有効化し、正式なサービスとして展開する場合はロードバランサを使用するなど、ユースケースによって使い分けるとよいでしょう。

Google アカウントやアクセス元 IP アドレスでアクセス制限を行う

Workforce Identity 連携により、Microsoft Entra ID 等の外部 ID プロバイダを利用して IAP による認証を構成することもできます。

機密情報の使用(パスワード・API キーなど)

Cloud Run では、Secret Manager に格納したデータベースのパスワードや外部サービスの API キーなどの機密情報(シークレット)を、環境変数もしくはボリュームマウントの形式で利用することができます。

具体的な仕様や設定方法については以下の記事を参照してください。

データベース サービスへの接続

Google Cloud にはいくつかのデータベース サービス(参考)がありますが、そのうち Cloud SQLAlloyDB for PostgreSQL(AlloyDB)は「パブリック IP による接続」か「VPC を経由したプライベート IP 接続」のどちらかを選択する必要があります。

パブリック IP による接続では、プロキシソフトウェアである Cloud SQL Auth Proxy および AlloyDB Auth Proxy を使用した接続が推奨されています。これらを使用することにより、TLS 1.3 を使用した安全なデータベース接続が保証されます。

Cloud SQL Auth Proxy および AlloyDB Auth Proxy を使用した接続については、以下の記事を参照してください。

VPC を経由したプライベート IP 接続では、Cloud Run から「Cloud SQL(もしくは AlloyDB)にプライベート接続できる VPC」を経由してデータベースにアクセスする必要があります。

Cloud Run から VPC に接続するためには、サーバーレス VPC アクセス もしくは Direct VPC Egress を使用する必要があります。それぞれの比較や利用方法については以下の記事を参照してください。

Cloud Run から Cloud SQL にプライベート IP アドレスで接続する場合の構成例

Spanner や Firestore 等、その他データベース サービスについては、Google Cloud APIs を介したアクセスとなります。

Cloud Run から Google Cloud APIs へのリクエストは Google の内部ネットワーク内にとどまることが保証されているため、VPC を経由したアクセスの設定は必要ありません(参考)。

Cloud Run が使用する外部 IP アドレスの固定

Cloud Run 上のアプリケーションから外部サービスの API を使用する場合、外部サービス側で接続元 IP アドレスが制限されるケースがあります。

デフォルトでは、Cloud Run サービスは、コンテナインスタンスごとに自動で割り当てられるパブリック IP アドレスを使用してインターネット接続を行います。この IP アドレスはコンテナインスタンスが起動するたびに変わってしまいます。

インターネット接続に使用される IP アドレスの固定には、Cloud NAT を使用する必要があります。Cloud NAT は VPC 内に存在するため、「データベース サービスへの接続」で紹介したサーバーレス VPC アクセスもしくは Direct VPC Egress を構成して Cloud NAT に接続できるようにします。

サーバーレス VPC アクセス を使用するパターン

Direct VPC Egress を使用するパターン

それぞれの具体的な設定方法については以下の記事を参照してください。

他の Cloud Run サービスへのプライベートアクセス

Cloud Run のサービスをフロントエンドとバックエンドで分離する場合など、サービスから他の Cloud Run サービスにアクセスする場合、かつバックエンド側(アクセスされる側)のサービスが外部に公開できない場合、バックエンド側サービスの Ingress の設定を内部に設定することが推奨されます。

内部からのサービスアクセスのみ許可する

しかし、フロントエンド側サービスからバックエンド側サービス エンドポイントへの直接アクセスは「内部」ではないため許可されません。これを「内部」からのアクセスにするためには、フロントエンド側サービスを VPC に接続し、限定公開の Google アクセス を使用してバックエンド側サービスにアクセスする必要があります。

Cloud Run から他の Cloud Run サービスへのプライベートアクセス

設定方法の詳細については以下の記事を参照してください。

Cloud Storage バケットのマウント

Cloud Run では、容量無制限のオブジェクトストレージ サービスである Cloud Storage のバケットをファイルシステムとしてマウントすることができます。

これにより、Cloud Run 上のアプリケーションで使用する静的アセットをコンテナイメージに含める必要がなくなり、静的アセットの編集が容易になります。

マウントの詳細な仕様や設定方法については以下の記事を参照してください。

佐々木 駿太 (記事一覧)

G-gen最北端、北海道在住のクラウドソリューション部エンジニア

2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2025 Fellowに選出。好きなGoogle CloudプロダクトはCloud Run。

趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。