VPC Service Controls の境界内で Cloud Run ジョブをスケジュールする方法

1. はじめに

概要

GCP プロジェクトが VPC SC 境界内にある場合は、スケジュール設定されたジョブを設定するために追加の手順を行う必要があります。Cloud Scheduler は VPC SC 境界内でジョブを直接トリガーできないため、別のコンポーネントを介してリクエストをプロキシする必要があります。このプロキシとして Cloud Run サービスを使用することをおすすめします。

アーキテクチャは次のようになります。

Cloud Scheduler が Cloud Run ジョブを実行する Cloud Run サービスをトリガーする図

学習内容

  • VPC SC 境界内でスケジュールに従って Cloud Run ジョブを実行する方法
  • Cloud Run クライアント ライブラリを使用して Cloud Run ジョブをトリガーする Cloud Run サービスを作成する方法
  • スケジュールに従って Cloud Run サービスを呼び出すように Cloud Scheduler を構成する方法

2. 始める前に

まず、VPC Service Controls 用に Cloud Run をセットアップする手順を完了していることを確認します。

次に、この Codelab 全体で使用する環境変数を設定します。

PROJECT_ID=<YOUR_PROJECT_ID>
REGION=<YOUR_REGION>
AR_REPO=sample-job-repo
CLOUD_RUN_SERVICE=job-runner-service
CLOUD_RUN_JOB=sample-job
CLOUD_SCHEDULER=job-scheduler
SERVICE_ACCOUNT="cloud-run-invoker-sa"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
NETWORK=default
SUBNET=default

3. Cloud Run ジョブを作成する

この Codelab では、サンプルの Cloud Run ジョブ コンテナを使用します。

まず、Cloud Run ジョブコンテナ用の Artifact Registry リポジトリを作成します。

gcloud artifacts repositories create $AR_REPO --repository-format=docker --location=$REGION --description="codelab for Cloud Run jobs on schedule within VPC SC"

次に、VPC SC が構成されたプロジェクト内の Artifact Registry にサンプルの Cloud Run ジョブ コンテナをコピーします。これを行うには、gcrane ツールを使用します。インストール手順に沿って操作してください。gcrane の詳細については、リポジトリ間でイメージをコピーするドキュメントをご覧ください。

gcrane cp us-docker.pkg.dev/cloudrun/container/job:latest $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$CLOUD_RUN_JOB:latest

次に、VPC Service Controls に準拠した Cloud Run ジョブをデプロイします。

gcloud run jobs create $CLOUD_RUN_JOB --region $REGION \
 --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$CLOUD_RUN_JOB:latest \
 --network=$NETWORK \
 --subnet=$SUBNET \
 --vpc-egress=all-traffic

Jobs の作成の詳細については、Cloud Run ジョブのドキュメントの手順をご覧ください。

4. サービス アカウントを作成する

このサービス アカウントは、Cloud Run が Cloud Run ジョブを呼び出すために使用されます。

まず、次のコマンドを実行してサービス アカウントを作成します。

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run to run a Cloud Run job"

次に、サービス アカウントに Cloud Run 起動元ロールと Cloud Run 閲覧者ロールを付与します。

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/run.invoker

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/run.viewer

5. Cloud Run サービスを作成する

このステップでは、プロキシとして機能する Cloud Run サービスをデプロイします。

mkdir job-runner-service && cd $_

次のコードを使用して、main.py という名前のファイルを作成します。

import os
from flask import Flask
app = Flask(__name__)

# pip install google-cloud-run
from google.cloud import run_v2

@app.route('/')
def hello():

    client = run_v2.JobsClient()

    # UPDATE TO YOUR JOB NAME, REGION, AND PROJECT ID
    job_name = 'projects/YOUR_PROJECT_ID/locations/YOUR_JOB_REGION/jobs/YOUR_JOB_NAME' 

    print("Triggering job...")
    request = run_v2.RunJobRequest(name=job_name)
    operation = client.run_job(request=request)
    response = operation.result()

    print(response)
    return "Done!"

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

次のコードを使用して、requirements.txt という名前のファイルを作成します。

google-cloud-run
flask

最後に、Dockerfile を作成します。

FROM python:3.9-slim-buster
# for logging purposes
ENV PYTHONUNBUFFERED=True

WORKDIR /app

COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

COPY . .

CMD ["python3", "main.py"]

次に、次の Docker コマンドを使用してコンテナをビルドします。ソースベースのデプロイは、VPC SC 環境で設定するのが難しい場合があります。既存のビルド デプロイ パイプラインがある場合は、そのパイプラインを使用してソースコードをコンテナにビルドし、コンテナを Cloud Run サービスとしてデプロイします。

docker build -t $CLOUD_RUN_SERVICE .

docker tag $CLOUD_RUN_SERVICE $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$CLOUD_RUN_SERVICE

docker push $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$CLOUD_RUN_SERVICE

次に、VPC Service Controls に準拠した Cloud Run サービスをデプロイします。

gcloud run deploy $CLOUD_RUN_SERVICE --region $REGION \
 --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$CLOUD_RUN_SERVICE \
 --service-account $SERVICE_ACCOUNT_ADDRESS \
 --network=$NETWORK \
 --subnet=$SUBNET \
 --vpc-egress=all-traffic \
 --no-allow-unauthenticated \
 --ingress internal

次のコマンドを実行して、サービス エンドポイント URL を保存します。

SERVICE_URL=$(gcloud run services describe $CLOUD_RUN_SERVICE --region $REGION --format 'value(status.url)')

6. サービスをトリガーする Cloud Scheduler ジョブを作成する

# create the Cloud Scheduler job
gcloud scheduler jobs create http $CLOUD_SCHEDULER \
  --location=$REGION \
  --schedule="0 0 1 * *" \
  --uri=$SERVICE_URL \
  --http-method=GET \
  --oidc-service-account-email=$SERVICE_ACCOUNT_ADDRESS

Cloud Scheduler ジョブが作成されたら、次のコマンドを実行して、テスト目的で Cloud Scheduler ジョブをすぐに実行できます。

gcloud scheduler jobs run $CLOUD_SCHEDULER --location=$REGION

注:

ジョブの実行が完了するまで数分かかることがあります。ステータスは Cloud Run Scheduler ページで確認できます。

次のコマンドを実行して、Cloud Run ジョブが正常に実行されたことを確認します。

EXECUTION_NAME=$(gcloud run jobs describe $CLOUD_RUN_JOB --region $REGION --format 'value(status.latestCreatedExecution.name)')

gcloud run jobs executions describe $EXECUTION_NAME --region $REGION

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

✔ Execution sample-job-w6hrj in region us-central1
1 task completed successfully
Elapsed time: 28 seconds

7. 完了

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

学習した内容

  • VPC SC 境界内でスケジュールに従って Cloud Run ジョブを実行する方法
  • Cloud Run クライアント ライブラリを使用して Cloud Run ジョブをトリガーする Cloud Run サービスを作成する方法
  • スケジュールに従って Cloud Run サービスを呼び出すように Cloud Scheduler を構成する方法

8. クリーンアップ

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

Cloud Run サービスと Cloud Run ジョブを削除するには、Cloud Run Cloud コンソール(https://console.cloud.google.com/run)に移動して、サービスを削除します。

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