Cloud Run でのリビジョンの使用(トラフィック分割、段階的なロールアウト、ロールバック)

1. はじめに

概要

Cloud Run リビジョンを使用すると、トラフィックを受信するリビジョンと、各リビジョンに送信するトラフィックの割合を指定できます。リビジョンを使用すると、以前のリビジョンにロールバックしたり、リビジョンを段階的にロールアウトしたり、複数のリビジョン間でトラフィックを分割したりできます。

この Codelab では、リビジョンを使用して Cloud Run サービスへのトラフィックを管理する方法について説明します。リビジョンの詳細については、Cloud Run のドキュメントをご覧ください。

学習内容

  • Cloud Run サービスの 2 つ以上のリビジョン間でトラフィックを分割する方法
  • 新しいリビジョンを段階的にロールアウトする方法
  • 以前のリビジョンにロールバックする方法

2. 設定と要件

前提条件

  • Cloud コンソールにログインしていること。
  • 以前に Cloud Run サービスをデプロイしている。たとえば、Cloud Run サービスのデプロイの手順に沿って開始できます。

環境変数の設定

この Codelab 全体で使用する環境変数を設定できます。

PROJECT_ID=YOUR-PROJECT-ID
REGION=YOUR_REGION

BG_COLOR=darkseagreen
SERVICE_NAME=traffic-revisions-color
AR_REPO=traffic-revisions-color-repo

Service の Artifact Registry リポジトリを作成する

gcloud artifacts repositories create $AR_REPO \
    --repository-format=docker \
    --location=$REGION \
    --description="codelab for finetuning using CR jobs" \
    --project=$PROJECT_ID

3. トラフィック分割

このサンプルでは、色の環境変数を読み取り、その背景色を使用してリビジョン名を返す Cloud Run サービスを作成する方法を示します。

この Codelab では Python を使用しますが、任意のランタイムを使用できます。

環境変数の設定

この Codelab 全体で使用する環境変数を設定できます。

REGION=<YOUR_REGION>
PROJECT_ID=<YOUR-PROJECT-ID>
BG_COLOR=darkseagreen
SERVICE_NAME=traffic-revisions-color
AR_REPO=traffic-revisions-color-repo

サービスを作成する

まず、ソースコードのディレクトリを作成し、そのディレクトリに移動します。

mkdir traffic-revisions-codelab && cd $_

次に、次の内容の main.py ファイルを作成します。

import os
from flask import Flask, render_template_string

app = Flask(__name__)

TEMPLATE = """
<!doctype html>
<html lang="en">
<head>
    <title>Cloud Run Traffic Revisions</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 50vh;
            background-color: {{ bg_color }}; /* Set by environment variable */
            font-family: sans-serif;
        }
        .content {
            background-color: rgba(255, 255, 255, 0.8); /* Semi-transparent white background */
            padding: 2em;
            border-radius: 8px;
            text-align: center;
            box-shadow: 0 4px 8px rgba(0,0,0,0.1);
        }
    </style>
</head>
<body>
    <div class="content">
        <p>background color: <strong>{{ color_name }}</strong></p>
    </div>
</body>
</html>
"""

@app.route('/')
def main():
    """Serves the main page with a background color from the ENV."""
    # Get the color from the 'BG_COLOR' environment variable.
    # Default to 'white' if the variable is not set.
    color = os.environ.get('BG_COLOR', 'white').lower()

    return render_template_string(TEMPLATE, bg_color=color, color_name=color)

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

次に、次の内容の requirements.txt ファイルを作成します。

Flask>=2.0.0
gunicorn>=20.0.0

最後に Dockerfile を作成します。

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8080

ENV PYTHONPATH /app

CMD ["gunicorn", "--bind", "0.0.0.0:8080", "main:app"]

Cloud Build を使用して Buildpack を使用して Artifact Registry にイメージを作成します。

gcloud builds submit \
   --tag $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME

最初のリビジョンを darkseagreen 色で Cloud Run にデプロイします。

gcloud run deploy $SERVICE_NAME \
    --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME:latest \
    --region $REGION \
    --allow-unauthenticated \
    --set-env-vars BG_COLOR=darkseagreen

サービスをテストするには、ウェブブラウザでエンドポイントを直接開き、背景色が濃い海藻色であることを確認します。

次に、背景色がタン色の 2 つ目のリビジョンをデプロイします。

# update the env var
BG_COLOR=tan

gcloud run deploy $SERVICE_NAME \
    --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME:latest \
    --region $REGION \
    --set-env-vars BG_COLOR=tan

ウェブサイトを更新すると、茶色の背景色が表示されます。

トラフィックを 50% ずつ分割する

ディープシーグリーンとタンのリビジョン間でトラフィックを分割するには、基盤となる Cloud Run サービスのリビジョン ID を見つける必要があります。リビジョン ID を表示するには、次のコマンドを実行します。

gcloud run revisions list --service $SERVICE_NAME \
  --region $REGION --format 'value(REVISION)'

次のような結果が表示されます。

traffic-revisions-color-00003-qoq
traffic-revisions-color-00002-zag

リビジョンで次のコマンドを実行すると、トラフィックを 2 つのリビジョン間で 50/50 に分割できます。

gcloud run services update-traffic $SERVICE_NAME \
  --region $REGION \
  --to-revisions YOUR_REVISION_1=50,YOUR_REVISION_2=50

トラフィック分割をテストする

ブラウザでページを更新すると、サービスをテストできます。

半分は濃い海藻色のリビジョンが表示され、残りの半分はタン色のリビジョンが表示されます。また、出力にリビジョン名が表示されます(例:

<html><body style="background-color:tan;"><div><p>Hello traffic-revisions-color-00003-qoq</p></div></body></html>

4. 段階的なロールアウト

このセクションでは、新しい Cloud Service リビジョンに変更を段階的にロールアウトする方法について説明します。段階的なロールアウトの詳細については、ドキュメントをご覧ください。

前のセクションと同じコードを使用しますが、新しい Cloud Run サービスとしてデプロイします。

まず、背景色を beige に設定し、gradual-rollouts-colors という名前の関数をデプロイします。

Cloud Run 関数を Cloud Run に直接デプロイするには、次のコマンドを実行します。

# update the env var
BG_COLOR=beige

gcloud beta run deploy gradual-rollouts-colors \
      --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME:latest \
      --region $REGION \
      --allow-unauthenticated \
      --update-env-vars BG_COLOR=$BG_COLOR

背景色をラベンダーにした新しいリビジョンを段階的にロールアウトするとします。

まず、現在のリビジョン(ベージュ)に 100% のトラフィックを受信するように設定します。これにより、今後の改訂版にトラフィックが送信されなくなります。デフォルトでは、Cloud Run は latest フラグを使用してリビジョンに 100% のトラフィックを設定します。この現在のリビジョン beige がすべてのトラフィックを受信するように手動で指定すると、latest フラグを持つリビジョンは 100% のトラフィックを受信しなくなります。ドキュメントをご覧ください。

# get the revision name

BEIGE_REVISION=$(gcloud run revisions list --service gradual-rollouts-colors \
  --region $REGION --format 'value(REVISION)')

# now set 100% traffic to that revision

gcloud run services update-traffic gradual-rollouts-colors \
  --to-revisions=$BEIGE_REVISION=100 \
  --region $REGION

Traffic: 100% radual-rollouts-colors-00001-yox のような出力が表示されます。

これで、トラフィックを受信しない新しいリビジョンをデプロイできます。コードを変更する代わりに、このリビジョンの BG_COLOR 環境変数を更新できます。

Cloud Run 関数を Cloud Run に直接デプロイするには、次のコマンドを実行します。

# update color

BG_COLOR=lavender

# deploy the function that will not receive any traffic
gcloud beta run deploy gradual-rollouts-colors \
      --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME:latest \
      --region $REGION \
      --allow-unauthenticated \
      --update-env-vars BG_COLOR=$BG_COLOR

ブラウザでウェブサイトにアクセスすると、ラベンダーが最後にデプロイされたリビジョンであるにもかかわらず、ベージュ色が表示されます。

トラフィックを 0% で配信するリビジョンをテストする

リビジョンが正常にデプロイされ、トラフィックを 0% 処理していることを確認したとします。ヘルスチェックに合格したとしても、このリビジョンでラベンダーの背景色が使用されていることを確認する必要があります。

lavender リビジョンをテストするには、そのリビジョンにタグを適用します。タグを使用すると、トラフィックを処理することなく、特定の URL で新しいリビジョンを直接テストできます。

まず、最新リビジョン(ラベンダー)の画像 URL を取得します。

IMAGE_URL_LAVENDER=$(gcloud run services describe gradual-rollouts-colors --region $REGION --format 'value(IMAGE)')

次に、その画像に関連する色のタグを設定します。

gcloud run deploy gradual-rollouts-colors --image $IMAGE_URL_LAVENDER --no-traffic --tag $BG_COLOR --region $REGION

出力は次のようになります。

The revision can be reached directly at https://lavender---gradual-rollouts-colors-<hash>-<region>.a.run.app

これで、その特定のリビジョンの URL にアクセスすると、ラベンダー色が表示されます。

トラフィックが徐々に増加している

これで、lavender リビジョンへのトラフィックの送信を開始できます。次の例は、トラフィックの 1% を lavender に送信する方法を示しています。

gcloud run services update-traffic gradual-rollouts-colors --region $REGION --to-tags lavender=1

トラフィックの 50% を lavender に送信するには、同じコマンドを使用しますが、代わりに 50% を指定します。

gcloud run services update-traffic gradual-rollouts-colors --region $REGION --to-tags lavender=50

各リビジョンが受信しているトラフィックの量のリストが表示されます。

Traffic:
  50% gradual-rollouts-colors-00001-hos
  50% gradual-rollouts-colors-00004-mum
        lavender: https://lavender---gradual-rollouts-colors-<hash>-<region>.a.run.app

ラベンダーを完全にロールアウトする準備ができたら、ラベンダーを 100% に設定してベージュに置き換えることができます。

gcloud run services update-traffic gradual-rollouts-colors --region $REGION --to-tags lavender=100

ウェブサイトにアクセスすると、ラベンダーのみが表示されます。

5. ロールバック

早期の UX フィードバックが届き、ユーザーがラベンダーよりもベージュを好んでいることが判明し、ベージュにロールバックする必要がある場合を考えてみましょう。

次のコマンドを実行すると、以前のリビジョン(ベージュ)にロールバックできます。

gcloud run services update-traffic gradual-rollouts-colors --region $REGION --to-revisions $BEIGE_REVISION=100

これで、ウェブサイトにアクセスすると、背景色がベージュになります。

ロールバックの詳細については、ドキュメントをご覧ください。

6. 完了

以上で、この Codelab は完了です。

ロールアウト、ロールバック、トラフィックの移行に関するドキュメントを確認することをおすすめします。

学習した内容

  • Cloud Run サービスの 2 つ以上のリビジョン間でトラフィックを分割する方法
  • 新しいリビジョンを段階的にロールアウトする方法
  • 以前のリビジョンにロールバックする方法

7. クリーンアップ

誤って課金されないようにするには(たとえば、この Cloud Run 関数が 無料 tier の Cloud Run 呼び出しの月間割り当てを超える回数誤って呼び出された場合など)、Cloud Run サービスを削除するか、手順 2 で作成したプロジェクトを削除します。

Cloud Run サービスを削除するには、Cloud コンソールの Cloud Run(https://console.cloud.google.com/run/)に移動し、この Codelab で作成した関数を削除します。

プロジェクト全体を削除する場合は、https://console.cloud.google.com/cloud-resource-manager に移動し、ステップ 2 で作成したプロジェクトを選択して、[削除] を選択します。プロジェクトを削除する場合は、Cloud SDK でプロジェクトを変更する必要があります。gcloud projects list を実行すると、使用可能なすべてのプロジェクトのリストが表示されます。