サーバーの起動・停止を気にせずバッチ処理を実行したい。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 servicesCloud 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
--cpuCPU割り当て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ミリ秒単位で課金されます。

無料枠(毎月リセット)

リソース無料枠
CPU180,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 jobsCloud 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サーバーの管理コストを削減しています。

移行時の主な変更点

  1. HTTPサーバーの削除: servicesではコンテナがHTTPリクエストを受け付ける必要がありますが、jobsではHTTPサーバーは不要です。main() 関数を直接実行するエントリポイントに変更します
  2. ヘルスチェックの除去: servicesにはスタートアップチェックやヘルスチェックのエンドポイントが必要ですが、jobsにはありません
  3. 終了コードの設計: jobsではコンテナの終了コード0が成功、非0が失敗と判定されます。例外をキャッチしてsys.exit(1)で失敗を明示する設計にします
  4. 並列数の初期値確認: コンソールから作成する場合、タスク数と並列数のデフォルト値が意図と異なることがあるため確認が必要です

ジョブの更新とバージョン管理

コンテナイメージ更新時の再デプロイ

コンテナイメージを更新した場合、ジョブも再デプロイする必要があります。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秒)の範囲内であれば費用をかけずに運用できるため、まずは小規模なバッチ処理から試すのがよいスタートです。