Amazon EKS で Kubernetes CronJob を運用していると「ジョブが走らない」「失敗して止まった」などのトラブルに遭遇しがちです。
本記事では Kubernetes CronJob 失敗 対処法 を軸に、EKS ユーザーが押さえるべき原因分析と最新ベストプラクティスをまとめます。
CronJob が失敗・動かない主な4パターン
同時実行ポリシーでジョブがスキップされる
concurrencyPolicy: Forbid
を指定すると前回ジョブ完了まで次のジョブをスキップします。これは仕様であり失敗ではないものの、実行漏れと誤認しやすいので注意しましょう (出典: https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/)。
-
処理時間が読めない場合は
Replace
を検討 -
リソース不足が原因なら Pod の CPU / メモリを増強
正直、最初は「なぜ動かないのか分からない」と戸惑いましたが、ログを追えばスキップ理由が分かり安心しました。
一時停止と “100 回ルール”
.spec.suspend: true
で CronJob を停止し、数日後に再開したら動かない…。これは 100 回連続で実行機会を逃すと CronJob が停止 する安全装置によるものです (出典: https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/cronjob/)。毎分ジョブなら約1.5時間で上限到達。
-
長期停止前にスケジュールを毎時へ変更し失敗カウントを抑制
-
再開後に
startingDeadlineSeconds
を適切に設定しておく
わたしも週末メンテで suspend しっぱなしにしてしまい、月曜朝に慌てて再デプロイした苦い体験があります。
startingDeadlineSeconds
未設定
未設定だと「遅れてでも全部実行する」挙動になり、逃しカウントが増えて 100 回停止に直結します。
-
目安は ジョブ間隔 × 100 より少し小さい秒数
-
10 秒未満は CronJob 自体がスケジューリングされなくなる (出典: https://cloud.google.com/kubernetes-engine/docs/concepts/cronjob)
毎時バッチなら 360000 秒(約100時間)以内に収めると安心です。
Cron 式とタイムゾーンの誤り
Kubernetes 1.27 以降は .spec.timeZone
が Stable になり、timeZone: "Asia/Tokyo"
で日本時間指定が可能です (出典: https://github.com/kubernetes/kubernetes/pull/113845)。以前の UTC ずれ問題を根本解消できます。
-
cron 式はオンライン validator で確認
-
EKS クラスタバージョンが 1.27 以上かチェック
失敗を防ぐ設定ベストプラクティス
ConcurrencyPolicy 設計
-
Allow : 重複許可、簡単だが二重処理に要注意
-
Forbid : 重複禁止、処理ロック的に使える
-
Replace : 長時間ジョブを中断し最新ジョブへ置換
ジョブ実行時間が読めない場合は Replace が安全でした。実際にわたしのバックアップ処理は Replace で安定稼働しています。
startingDeadlineSeconds
の設定ガイド
実行間隔 | 推奨値の目安 |
---|---|
毎分 | 600–900 秒 |
5 分ごと | 3 000–4 000 秒 |
毎時 | 7 200–10 800 秒 |
Job 再試行 (backoffLimit
) と履歴
-
失敗時に再試行不要なら
backoffLimit: 0
-
ttlSecondsAfterFinished
で完了後に Job を自動削除し、メトリクスをクリーンに保つ -
successfulJobsHistoryLimit
/failedJobsHistoryLimit
で履歴を絞りクラスターを軽量化
監視とアラート設計
-
CloudWatch Container Insights で異常終了 Pod を可視化
-
Prometheus + Alertmanager で
kube_job_failed
をトリガに通知 -
EventBridge → SNS でメール・Slack 連携
CronJob 失敗 監視 EKS をキーワードに検索すると、実装例が多数見つかります。アラートは「早朝の定期バッチが止まった」瞬間に気付ける一番の保険です。
Amazon EKS ならではの運用Tips
ノードオートスケーリング
CronJob が作成されても Pod が Pending のままなら、ノードグループに該当インスタンスタイプが無い可能性があります。Cluster Autoscaler を有効化し、必要な taint / label を設定しましょう。
CloudWatch ログの活用
CronJob Pod 標準出力を CloudWatch Logs に送れば、フィルタで error
や panic
を検知可能。わたしは Logs Insights で「status=error
AND cronjob=my-batch
」クエリを実行し、失敗パターンを洗い出しています。
GitOps で Manifest を管理
手動 kubectl apply
はヒューマンエラーの温床。Argo CD や Flux で Git リポジトリと同期し、PR レビューで startingDeadlineSeconds
や concurrencyPolicy
の差分を可視化すると運用が楽になります。
よくある Q&A
-
Q. suspend せずに安全に止めたい
→ スケジュールを未来日時に変更し、停止後に元へ戻す方法がおすすめ。 -
Q. 100 回制限を無効化できる?
→ できません。設計段階でstartingDeadlineSeconds
やスケジュール変更で回避しましょう。 -
Q. UTC ずれ以外で実行時刻がおかしい
→ コントロールプレーンの時計とノードの NTP 同期を確認。EKS は自動同期ですが独自 AMI では要チェック。
まとめ
-
Kubernetes CronJob 失敗 対処法 の核心は ConcurrencyPolicy と
startingDeadlineSeconds
。 -
suspend × 長期停止は “100 回ルール” で停止するため要注意。
-
EKS 環境では CloudWatch・Prometheus 監視と GitOps を組み合わせ、止まらない定期バッチを実現しよう。