サーバーの起動・停止を気にせずバッチ処理を実行したい。Cloud Run jobsは、コンテナを使い捨て感覚で走らせ、処理が終われば自動で課金が止まるGoogle Cloudのサーバーレス実行基盤です。
Cloud Run jobsは2023年5月にGA(一般提供)となった、非同期タスク向けの実行サービスです。HTTPリクエストを受けて応答するCloud Run servicesとは異なり、Cloud Run jobsはコンテナを起動して処理を完了させたら終了する「実行して終わり」のモデルを採用しています。データベースのバックアップ、レポート生成、データ変換パイプラインなど、定期的に実行したいバッチ処理に適しています。
Cloud Run servicesとjobsの根本的な違い
Cloud Runには「services」と「jobs」の2つの実行モデルがあります。名前が似ているため混同しやすいですが、設計思想が異なります。
| 観点 | Cloud Run services | Cloud Run jobs |
|---|---|---|
| 実行トリガー | HTTPリクエスト | 手動・スケジュール・API |
| ライフサイクル | リクエストがある限り起動し続ける | 処理完了で自動終了 |
| スケーリング | リクエスト数に応じて0〜Nにオートスケール | タスク数を事前に指定(最大10,000) |
| 最大実行時間 | リクエストタイムアウト最大60分 | タスクタイムアウト最大168時間(7日間) |
| HTTPサーバー | 必須(ポートをリッスンする必要あり) | 不要 |
| ユースケース | Web API、Webhook受信 | バッチ処理、データ変換、定期ジョブ |
判断基準はシンプルです。外部からのHTTPリクエストに応答する必要があるならservices、処理を実行して終了するだけならjobsを選びます。
ジョブ・Execution・タスクの3層構造
Cloud Run jobsには3つの階層があります。それぞれの役割を把握しておくと、並列処理やリトライの設計がスムーズになります。
Job – 設定を保持するルートリソース
Jobはコンテナイメージ、CPU・メモリ割り当て、環境変数、タスク数などの設定をまとめたテンプレートです。Jobそのものは実行されず、「このコンテナをこの設定で動かす」という定義だけを保持します。1プロジェクト・1リージョンあたり最大1,000個のJobを作成できます。
Execution – 1回の実行サイクル
JobをトリガーするとExecutionが作成されます。Executionは「いつ実行されたか」「成功したか失敗したか」を追跡する実行履歴の単位です。1つのJobに対して最大1,000件の完了済みExecutionが保持されます。
Task – コンテナインスタンスと1対1で動く最小単位
Execution内で実際にコンテナが起動する単位がTaskです。1つのExecutionに最大10,000個のTaskを含められます。各Taskは独立したコンテナインスタンスで実行されるため、Task間でメモリやファイルシステムは共有されません。
並列処理を設計する際は、環境変数 CLOUD_RUN_TASK_INDEX(0から始まる連番)と CLOUD_RUN_TASK_COUNT(総タスク数)を使って各Taskにワークを分配します。たとえば10,000件のレコードを10個のTaskで処理する場合、各Taskは自分のインデックスをもとに1,000件ずつ担当する設計にします。
import os
task_index = int(os.environ.get("CLOUD_RUN_TASK_INDEX", 0))
task_count = int(os.environ.get("CLOUD_RUN_TASK_COUNT", 1))
# 処理対象のレコードを分割
all_records = fetch_all_records()
chunk_size = len(all_records) // task_count
start = task_index * chunk_size
end = start + chunk_size if task_index < task_count - 1 else len(all_records)
for record in all_records[start:end]:
process(record)
ジョブの作成とデプロイ手順
gcloud CLIによるデプロイ
最もシンプルなデプロイ方法は gcloud run jobs deploy コマンドです。コンテナイメージをArtifact Registryにプッシュ済みであれば、1コマンドでジョブを作成できます。
# Artifact Registryにイメージをプッシュ
docker build -t asia-northeast1-docker.pkg.dev/PROJECT_ID/REPO/my-job:latest .
docker push asia-northeast1-docker.pkg.dev/PROJECT_ID/REPO/my-job:latest
# ジョブの作成
gcloud run jobs deploy my-batch-job \
--image asia-northeast1-docker.pkg.dev/PROJECT_ID/REPO/my-job:latest \
--region asia-northeast1 \
--tasks 10 \
--max-retries 3 \
--task-timeout 3600 \
--memory 1Gi \
--cpu 1
# ジョブの実行
gcloud run jobs execute my-batch-job --region asia-northeast1
主なオプションを整理します。
| オプション | 説明 | デフォルト値 |
|---|---|---|
--tasks | 実行するタスク数 | 1 |
--max-retries | タスク失敗時の最大再試行回数(0〜10) | 3 |
--task-timeout | タスクのタイムアウト(秒) | 600(10分) |
--parallelism | 同時実行するタスクの最大数 | 0(可能な限り並列) |
--memory | メモリ割り当て | 512Mi |
--cpu | CPU割り当て | 1 |
--set-env-vars | 環境変数の設定 | なし |
YAML定義によるジョブ管理
ジョブの設定をバージョン管理したい場合は、YAML定義ファイルを使います。
apiVersion: run.googleapis.com/v1
kind: Job
metadata:
name: my-batch-job
annotations:
run.googleapis.com/launch-stage: GA
spec:
template:
spec:
taskCount: 10
parallelism: 5
template:
spec:
containers:
- image: asia-northeast1-docker.pkg.dev/PROJECT_ID/REPO/my-job:latest
resources:
limits:
cpu: "1"
memory: "1Gi"
env:
- name: DB_HOST
value: "10.0.0.1"
maxRetries: 3
timeoutSeconds: 3600
# YAMLからジョブを作成・更新
gcloud run jobs replace job.yaml --region asia-northeast1
Terraformでインフラコード化する
本番環境ではTerraformによるIaC管理が有効です。ジョブの設定変更を差分管理でき、レビューを経てデプロイできます。
resource "google_cloud_run_v2_job" "batch_job" {
name = "my-batch-job"
location = "asia-northeast1"
template {
task_count = 10
parallelism = 5
template {
max_retries = 3
timeout = "3600s"
containers {
image = "asia-northeast1-docker.pkg.dev/${var.project_id}/repo/my-job:latest"
resources {
limits = {
cpu = "1"
memory = "1Gi"
}
}
env {
name = "DB_HOST"
value = "10.0.0.1"
}
}
}
}
}
Cloud Schedulerを使った定期実行の設定
Cloud Run jobsを定期的に実行するには、Cloud Schedulerと組み合わせます。Cloud Schedulerはフルマネージドのcronサービスであり、指定した時刻にCloud Run jobsのExecutionを自動作成します。
設定手順
# サービスアカウントの作成
gcloud iam service-accounts create job-invoker \
--display-name "Cloud Run Job Invoker"
# Cloud Run Invokerロールの付与
gcloud run jobs add-iam-policy-binding my-batch-job \
--member serviceAccount:job-invoker@PROJECT_ID.iam.gserviceaccount.com \
--role roles/run.invoker \
--region asia-northeast1
# Cloud Schedulerジョブの作成(毎日午前3時に実行)
gcloud scheduler jobs create http daily-batch \
--location asia-northeast1 \
--schedule "0 3 * * *" \
--uri "https://asia-northeast1-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/PROJECT_ID/jobs/my-batch-job:run" \
--http-method POST \
--oauth-service-account-email job-invoker@PROJECT_ID.iam.gserviceaccount.com
cron式の 0 3 * * * は「毎日午前3時」を意味します。Cloud Schedulerの料金は、ジョブ3個まで無料、4個目以降は1ジョブあたり月額$0.10です。
Schedulerのタイムアウトに注意
Cloud Schedulerには独自のタイムアウト設定(デフォルト3分)があります。Cloud Run jobsの実行はSchedulerのHTTPリクエストに対するレスポンスとは独立して動作するため、Scheduler側のタイムアウトはジョブの実行時間に影響しません。SchedulerはJobの「起動リクエスト」を送信するだけで、ジョブの完了を待ちません。
実行時パラメータのオーバーライド
同じJobの設定をベースにしつつ、実行ごとに一部の設定を変更したいケースがあります。gcloud run jobs execute の --update-env-vars や --tasks オプションを使うと、Job定義を変更せずにExecutionごとのパラメータを上書きできます。
# 環境変数を変更して実行
gcloud run jobs execute my-batch-job \
--region asia-northeast1 \
--update-env-vars TARGET_DATE=2026-02-25
# タスク数を変更して実行
gcloud run jobs execute my-batch-job \
--region asia-northeast1 \
--tasks 50
この仕組みを活用すると、Workflows等のオーケストレーションサービスから日付パラメータを渡してジョブを呼び出すパイプラインを構築できます。
制限値の一覧
Cloud Run jobsの主な制限値を表にまとめます。
| 項目 | 制限値 |
|---|---|
| 1プロジェクト・リージョンあたりのジョブ数 | 1,000 |
| 1ジョブあたりのタスク数 | 最大10,000 |
| タスクの並列実行数 | リージョン・CPU・メモリ構成に依存(多くのリージョンでデフォルト100程度) |
| タスクタイムアウト | 最大168時間(7日間)、GPU利用時は最大1時間 |
| デフォルトタイムアウト | 10分 |
| 最大再試行回数 | 10回(デフォルト3回) |
| CPU | 最大8 vCPU |
| メモリ | 最大32 GiB |
| 環境変数の数 | 最大1,000 |
| コマンド引数の数 | 最大1,000 |
| 完了済みExecutionの保持数 | 1,000件 / Job |
料金体系と無料枠
Cloud Run jobsの料金はservicesと同じ体系で、CPUとメモリの使用量に対して100ミリ秒単位で課金されます。
無料枠(毎月リセット)
| リソース | 無料枠 |
|---|---|
| CPU | 180,000 vCPU秒 / 月 |
| メモリ | 360,000 GiB秒 / 月 |
| リクエスト | 200万リクエスト / 月 |
180,000 vCPU秒は、1 vCPUのタスクを50時間分に相当します。軽量なバッチ処理であれば無料枠の範囲内で運用可能です。
従量課金(無料枠超過分)
| リソース | Tier 1(米国・欧州) | Tier 2(東京を含むアジア) |
|---|---|---|
| CPU | $0.00002400 / vCPU秒 | $0.00003360 / vCPU秒 |
| メモリ | $0.00000250 / GiB秒 | $0.00000350 / GiB秒 |
東京リージョン(asia-northeast1)はTier 2に分類されます。
料金の計算例
1 vCPU・1 GiBメモリのタスクを1日1回、10分間実行する場合の月額コスト(30日間・無料枠消費後)を試算します。
- CPU: 600秒 × 30日 × $0.00003360 = $0.6048 / 月
- メモリ: 600秒 × 30日 × $0.00000350 = $0.0630 / 月
- 合計: 約 $0.67 / 月(約100円)
無料枠を使い切っていない場合は、この程度の利用量であれば無料で運用できます。
Cloud Functions・Cloud Batchとの使い分け
Google Cloudにはバッチ処理やイベント駆動処理のサービスが複数あります。用途に応じた選定が重要です。
| 観点 | Cloud Run jobs | Cloud Functions (2nd gen) | Cloud Batch |
|---|---|---|---|
| 実行モデル | コンテナベース | 関数ベース | コンテナ/スクリプト |
| 最大実行時間 | 168時間(7日間) | 60分(HTTPトリガー時) | 制限なし(VM存続中) |
| 並列処理 | タスク分割(最大10,000) | イベント単位でオートスケール | タスクグループ |
| GPU対応 | あり(L4、タイムアウト1時間) | なし | あり(A100, V100等) |
| インフラ管理 | 不要(サーバーレス) | 不要(サーバーレス) | VM管理が一部必要 |
| 課金単位 | vCPU秒 + GiB秒 | vCPU秒 + GiB秒 | vCPU秒 + GiB秒 + VM |
| 向いている処理 | 中〜長時間バッチ | 短時間イベント処理 | HPC・大規模計算 |
Cloud Run jobsを選ぶべきケース:
- 処理時間が数分〜数時間のバッチ処理
- Dockerコンテナで環境を統一したい
- サーバーレスでインフラ管理を省きたい
- Cloud Schedulerとの定期実行連携が必要
Cloud Functionsが適するケース:
- Pub/SubやCloud Storageのイベントをトリガーに軽量な処理を実行する
- 実行時間が数秒〜数分で完結する
Cloud Batchが適するケース:
- GPUを数時間以上使い続ける機械学習やHPC
- VMのスペック(CPU数・メモリ・ディスク)を細かく制御したい
- 数万タスク規模の大規模並列計算
Cloud Tasksとの違い
米国の技術コミュニティではCloud Run jobsとCloud Tasksの比較が頻繁に議論されます。Cloud Tasksは「HTTPエンドポイントへのリクエストをキューイングして非同期に配信するサービス」です。Cloud Run jobs(バッチ実行基盤)とは役割が異なります。
- Cloud Tasks: 個々のHTTPリクエストを非同期キューで管理する。リトライや遅延配信の制御が得意
- Cloud Run jobs: まとまった処理をコンテナで実行する。タスク分割と並列処理が得意
Webhookの非同期処理やAPIコールのリトライ制御にはCloud Tasks、データ加工やファイル生成などのバッチ処理にはCloud Run jobsが適しています。
GCPサービスとの連携パターン
BigQueryのデータ抽出をジョブで自動化
BigQueryからデータを抽出してCSVに変換し、Cloud Storageにアップロードする処理はCloud Run jobsの典型的なユースケースです。
from google.cloud import bigquery, storage
def main():
bq_client = bigquery.Client()
query = "SELECT * FROM `project.dataset.table` WHERE date = CURRENT_DATE()"
df = bq_client.query(query).to_dataframe()
# CSVに変換してGCSにアップロード
storage_client = storage.Client()
bucket = storage_client.bucket("my-export-bucket")
blob = bucket.blob(f"exports/{df.iloc[0]['date']}.csv")
blob.upload_from_string(df.to_csv(index=False), content_type="text/csv")
if __name__ == "__main__":
main()
Pub/Subメッセージをトリガーにジョブを起動
Cloud Run jobsを直接Pub/Subサブスクリプションのエンドポイントにはできませんが、EventarcやWorkflowsを経由して連携できます。Eventarcを使うと、Pub/Subメッセージの受信をトリガーにCloud Run jobsのExecutionを自動作成する仕組みを構築できます。
米国のCloud Run実務者の間では、Pub/SubメッセージをPullモードで処理するバッチジョブのパターンも活用されています。ジョブ内でPub/Subクライアントを使ってメッセージを取得し、一括処理してからAckを返す設計です。リアルタイム性よりもスループットを優先する場面で有効です。
Workflowsとの組み合わせ
Google Cloud Workflowsを使うと、複数のCloud Run jobsを順番に実行したり、ジョブの結果に応じて分岐処理を組んだりするパイプラインを構築できます。ジョブの実行パラメータをWorkflows側から動的に渡すこともできるため、日付パラメータ付きのETLパイプラインなどに向いています。
serviceからjobsへの移行で押さえるポイント
既存のCloud Run servicesでバッチ処理を動かしている場合、jobsへの移行を検討する価値があります。iret.mediaの事例では、openrestyベースのHTTPトリガーで起動していたバッチ処理をjobsに移行し、HTTPサーバーの管理コストを削減しています。
移行時の主な変更点
- HTTPサーバーの削除: servicesではコンテナがHTTPリクエストを受け付ける必要がありますが、jobsではHTTPサーバーは不要です。
main()関数を直接実行するエントリポイントに変更します - ヘルスチェックの除去: servicesにはスタートアップチェックやヘルスチェックのエンドポイントが必要ですが、jobsにはありません
- 終了コードの設計: jobsではコンテナの終了コード0が成功、非0が失敗と判定されます。例外をキャッチしてsys.exit(1)で失敗を明示する設計にします
- 並列数の初期値確認: コンソールから作成する場合、タスク数と並列数のデフォルト値が意図と異なることがあるため確認が必要です
ジョブの更新とバージョン管理
コンテナイメージ更新時の再デプロイ
コンテナイメージを更新した場合、ジョブも再デプロイする必要があります。latest タグを使っていても、Cloud Run jobsは作成時のイメージダイジェストを記録するため、自動的に最新イメージに切り替わりません。
# イメージを更新してジョブを再デプロイ
gcloud run jobs update my-batch-job \
--image asia-northeast1-docker.pkg.dev/PROJECT_ID/REPO/my-job:v2 \
--region asia-northeast1
米国のCloud Run利用者の間では、タグ付きイメージ(:v1, :v2)を使ってバージョンを管理し、問題が発生した場合に前のバージョンのイメージを指定して再デプロイするプラクティスが一般的です。CI/CDパイプラインでGitのコミットハッシュをイメージタグに含める方法も広く使われています。
実行のキャンセルと削除
実行中のExecutionをキャンセルするには以下のコマンドを使います。
# 実行中のExecutionを一覧表示
gcloud run jobs executions list --job my-batch-job --region asia-northeast1
# Executionをキャンセル
gcloud run jobs executions cancel EXECUTION_NAME --region asia-northeast1
# Executionを削除
gcloud run jobs executions delete EXECUTION_NAME --region asia-northeast1
GPU対応ワークロード
Cloud Run jobsはGPU(NVIDIA L4)をサポートしています。機械学習の推論バッチ処理や画像処理など、GPUが必要なワークロードにも対応可能です。ただし、GPU利用時はタスクタイムアウトの上限が1時間に制限されます。
GPUを使った長時間の学習ジョブには、タイムアウト制限のないCloud Batchが適しています。Cloud Run jobsのGPU対応は、短時間で完了する推論バッチや画像変換処理に向いています。
まとめ
Cloud Run jobsは、コンテナベースのバッチ処理をサーバーレスで実行するための実用的なサービスです。HTTPサーバーを用意する必要がなく、処理が完了すれば自動的に課金が止まる点が最大のメリットです。
ジョブ・Execution・タスクの3層構造を理解し、CLOUD_RUN_TASK_INDEX による並列処理の分割パターンを押さえておけば、多くのバッチ処理に対応できます。Cloud Schedulerとの定期実行連携、Terraformによるインフラコード管理、Workflowsを使ったパイプライン構築など、Google Cloudの各サービスと組み合わせることで運用の自動化も実現できます。
無料枠(毎月180,000 vCPU秒)の範囲内であれば費用をかけずに運用できるため、まずは小規模なバッチ処理から試すのがよいスタートです。
