JobとCronJob
Kubernetesでは、Webサーバーのような常駐型のアプリケーションだけでなく、一度だけ実行して終了するタスクや、定期的に実行されるタスクを管理するためのリソースも提供されています。それが Job と CronJob です。
Job (ジョブ)
Jobは、1つ以上のPodを作成し、指定された数のPodが正常に終了(Succeeded)することを保証するリソースです。
主なユースケース
- データベースのマイグレーション
- バッチ処理(データ集計、レポート生成など)
- 一回限りの初期化スクリプト
マニフェスト例
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
重要なパラメータ
- restartPolicy: Jobの場合は
OnFailureまたはNeverを指定します(Alwaysは不可)。 - completions: 成功させるべき回数。
- parallelism: 同時に実行するPodの数。
- backoffLimit: 失敗時のリトライ回数(デフォルトは6)。
CronJob (クロンジョブ)
CronJobは、Linuxのcron形式のスケジュールに基づいてJobを定期的に作成するリソースです。
主なユースケース
- 定期的なバックアップ
- 定期的なメール配信
- 深夜のデータクレンジング
マニフェスト例
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox:1.28
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
重要なパラメータ
- schedule: Cron形式のスケジュール(例:
"0 0 * * *")。 - concurrencyPolicy:
Allow: 同時実行を許可(デフォルト)。Forbid: 前のジョブが終わっていなければスキップ。Replace: 前のジョブをキャンセルして新しいジョブを開始。
- successfulJobsHistoryLimit: 成功したJobの履歴保持数(デフォルト3)。
- failedJobsHistoryLimit: 失敗したJobの履歴保持数(デフォルト1)。
ベストプラクティス
1. タイムアウトとクリーンアップの設定
Jobが無限に実行され続けるのを防ぐため、また終了したPodがリソースを圧迫しないように設定します。
- activeDeadlineSeconds: Jobの実行時間の制限(秒)。これを超えるとJobは強制終了されます。
- ttlSecondsAfterFinished: Job終了後、指定秒数が経過するとJobリソース(および関連Pod)を自動削除します(TTL Controller)。
spec:
ttlSecondsAfterFinished: 100 # 終了後100秒で削除
activeDeadlineSeconds: 1800 # 30分でタイムアウト
2. 冪等性(Idempotency)の確保
KubernetesのJobは、ネットワーク障害やノード障害により、稀に同じ処理が複数回実行される可能性があります。アプリケーション側で冪等性を担保する(同じ処理を何度実行しても結果が変わらないようにする)ことが重要です。
3. リソース制限の設定
バッチ処理は高負荷になりがちです。他のアプリケーションへの影響を防ぐため、必ず resources.requests と resources.limits を設定しましょう。
4. 同時実行ポリシーの検討 (CronJob)
ジョブの実行時間がスケジュール間隔を超える可能性がある場合、concurrencyPolicy を慎重に選択してください。データの整合性が重要な場合は Forbid が推奨されます。
5. 失敗時のハンドリング
backoffLimit を適切に設定し、無限リトライを防ぎます。また、アプリケーションログを適切に出力し、失敗原因を調査できるようにしておきましょう。
6. startingDeadlineSeconds の設定(重要)
.spec.startingDeadlineSeconds は、予定時刻を過ぎてからJobの開始を許容する秒数ですが、これはCronJobの停止を防ぐためにも重要です。
Kubernetesの仕様上、CronJobは「直近100回連続でスケジューリングに失敗する」と、それ以降Jobを生成しなくなります。startingDeadlineSeconds を設定していない場合、長期間の suspend: true や障害による連続失敗が100回に達すると、CronJobが壊れて再作成が必要になります。
この値を設定することで、判定対象が「その時間枠内での失敗」に限定されるため、意図しないCronJobの停止を防ぐことができます。
7. タイムゾーンの指定
デフォルトではCronJobはUTC(協定世界時)で動作します。JST(日本標準時)で実行したい場合、Kubernetes 1.27以降(AKS 1.27以降)では .spec.timeZone フィールドを利用できます。
spec:
timeZone: "Asia/Tokyo"
schedule: "0 0 * * *" # JST 0:00に実行
8. Spot VM (Preemptible Node) の回避
長時間実行される重要なバッチ処理は、コスト削減のためにSpot VM (Spot Node Pool) を使用しているクラスタであっても、Spot VM上での実行を避けるべきです。nodeAffinity を使用して、通常の(オンデマンド)ノードで実行されるように制御します。
spec:
template:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.azure.com/scalesetpriority
operator: NotIn
values:
- spot