Cloud Run jobs を使ってみる
こんにちは、自分の勉強したことをまとめて、発信を行なっていこうと思います。
今回は備忘録的な内容になります。
この記事では、Cloud Run の 1 機能であるCloud Run jobs を terraformで構築して、pythonジョブを定期実行するまでをまとめています。
Cloud Run jobs とは
Cloud Run には Cloud Run services と Cloud Run jobs があります。
Cloud Run services はHTTPリクエストを受け付けることのできるので、Webサーバーなどによく使われます。
一方、Cloud Run jobs はある一回の実行で終了する作業(ジョブ)の動作環境に使用できます。
Cloud Run jobsの特徴
Cloud Run servicesに比べると Cloud Run jobs の特徴は以下のようなものだと思います。個人的には最大24時間までタイムアウトが延べせるのが使い所によっては使いやすいなと思っています。
1回限りの実行が可能
HTTPSで実行開始することはできるが、パラメータを渡すことはできない
ジョブの実行時に、環境変数をオーバーライドできる
ジョブのタイムアウトは最長24時間まで長くすることができる
Cloud Run services は最長60分まで
実際に使ってみる
コードはここに全てアップしています
https://github.com/M0T0-2020/GCP-memorandum/tree/master/cr-jobs-0714
コンテナイメージの用意
今回はダミージョブとして、このpythonスクリプトを実行していきます。
`MESSAGE` と `NUMBER` という環境変数を読み込んで、それらをパラメータとして処理を実行します。
# main.py
import os
import time
from joblib import Parallel, delayed
def process_something(id: int, message: str):
n = min(id, 10)
for k in range(n):
print(f"id{n}: {message} {k}th")
time.sleep(1)
return message
def do_job(message: str, number: int):
results = Parallel(n_jobs=-1)(
delayed(process_something)(id, message) for id in range(number)
)
return list(results)
if __name__ == "__main__":
message = os.getenv("MESSAGE")
number = int(os.getenv("NUMBER"))
messages = do_job(message, number)
Dockerfileを用意してArtifact Registry にpushしておきます。
タスクはインスタンス上で1度だけ実行されるので、Dockerfileもpython環境を構築して、.pyを実行するだけの構成になっています。
# Dockerfile
# Use Python 3.11 slim as the base image
FROM python:3.11-slim
# Set environment variables
ENV PYTHONUNBUFFERED=1
ENV JOBS_HOME=/jobs
# Set the working directory
WORKDIR $JOBS_HOME
# Copy requirements file and install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy the remaining application files
COPY . .
# Run the main Python script
CMD ["python", "main.py"]
# Artifact Registry にpushしておきます。
gcloud builds submit . -t us-central1-docker.pkg.dev/$PROJECT_ID/$REPOSITORY/$IMAGE_NAME
terraformで環境構築
ジョブのスクリプトの用意ができたので、次はCloud Run jobsの環境をterraformで構築したいと思います。
今回は、スケジュラーで毎日19時にジョブを定期実行するような構成で書いていきます。
ジョブのタイムアウトは3時間に設定してみました。
terraformコードの作成には、この辺の情報を参考にしています。
https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_v2_job
https://cloud.google.com/run/docs/execute/jobs-on-schedule?hl=ja#terraform
provider "google" {
project = var.project_id
region = var.region
}
data "google_project" "project" {
project_id = var.project_id
}
resource "google_service_account" "default" {
account_id = "cloud-run-jobs-test-sa"
display_name = "service account for cr-jobs-0714"
}
resource "google_project_service" "cloudscheduler_api" {
service = "cloudscheduler.googleapis.com"
}
resource "google_cloud_run_v2_job" "default" {
name = "cloud-run-job"
location = var.region
launch_stage = "BETA"
template {
template {
containers {
image = var.container_path
env {
name = "MESSAGE"
value = var.message
}
env {
name = "NUMBER"
value = var.number
}
}
# 3 hours
timeout = "10800s"
service_account = google_service_account.default.email
}
}
}
resource "google_cloud_run_v2_job_iam_binding" "binding" {
project = google_cloud_run_v2_job.default.project
name = google_cloud_run_v2_job.default.name
location = google_cloud_run_v2_job.default.location
role = "roles/run.invoker"
members = [
"serviceAccount:${google_service_account.default.email}"
]
}
resource "google_cloud_scheduler_job" "job" {
name = "schedule-job"
description = "test http job"
schedule = "0 10 * * *" # execute every day at 7pm(jst)
attempt_deadline = "320s"
region = var.region
project = var.project_id
retry_config {
retry_count = 3
}
http_target {
http_method = "POST"
uri = "https://${google_cloud_run_v2_job.default.location}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${data.google_project.project.number}/jobs/${google_cloud_run_v2_job.default.name}:run"
oauth_token {
service_account_email = google_service_account.default.email
}
}
depends_on = [
resource.google_project_service.cloudscheduler_api,
resource.google_cloud_run_v2_job.default,
resource.google_cloud_run_v2_job_iam_binding.binding
]
}
確認
コンソールを確認すると、スケジューラによって19時にジョブが実行されているのが確認できました。
詳細を見ると意図通りのログも見ることができました。
他には、コンソール環境変数の値を上書きして実行することもできます。
環境変数の上書き設定をして、httpリクエストによる実行も可能です。
まとめ
簡単にCloud Run Jobsを構築することができました。
Cloud FunctionsやCloudRunServiceは最大タイムアウト時間が1時間ですが、Cloud Run Jobsは24時間まで許容範囲なので、時間がかかるようなタスクを実行させるときに使えるかなと思いました。
最後まで読んでくれてありがとうございます。 🙏