入門Kubernetes Jobs・CronJob
概要
KubernetesのWorkloadリソースであるJobsとCronJobの公式ドキュメントの内容について、個人の備忘録としてまとめていきます。
Jobs
Jobは一つ以上のPodを作成することである特定数のPodが正常終了するまでリトライしながら処理を実行するKubernetesのWorkloadリソースです。
Jobの利用シーンとして、1つのJobを正常通りに処理するために1つのJobオブジェクトを作成するケースがあります。Podの実行が失敗したり削除された場合はJobは新たにPodを起動します。
Jobは平行に複数のPodを起動することもできます。
ex)
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
jobを実行
kubectl applyjob.yaml
Job spec
apiVersion
とkind
、metada
、そして .spec
セクションを指定します。
Pod Template
.spec
フィールドにおいて唯一必須の項目が.spec.template
です。
spec.template
は基本的に pod templateと同一の内容になります。
Podのspecと共通ですが、フィールドの指定に関して注意点があります。
Kubernetesのcommand
はDockerでのEntryPoint
に該当し、
DockerのCMD
に対応するものはKubernetesではcommand
ではなくargs
で指定するようにします。(ex: サブコマンドを指定した場合はcommand
ではなくargs
の方に指定するようにします)
Jobでは、Pod templateで必須のフィールドに加えて、適切なラベル( https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-selector )と適切な起動ポリシーの指定が必須です。
RestartPolicy
はNever
又はOnFailure
のみ指定可能です。
Jobの平行実行
Jobの実行において主に3つのシチュエーションが考えられます
- 単一のJob
- Podが失敗しない限り通常は1つのPodのみが起動します
- Podが正常終了したタイミングでJobが完了します
- Podの実行完了数が固定された平行実行
-
.spec.completions
に正の数が指定される場合 - Jobは全体のタスクを表し、指定の
.spec.completions
数のPodの実行が完了したタイミングでJobが完了します -
.spec.completionMode="Indexed"
が指定されている場合は、0から.spec.completions=1
の範囲でPodは異なるインデックスを取得します
-
- work queueを利用した平行実行
-
.spec.completions
は指定しません - それぞれのPodがどの処理を実行するかを決めるために、Pod間又は外部サービス間で調整する必要があります
- 個々のPodはJob全体が完了しかたかどうかを個別に判断できます
- JobのPodが正常終了又停止された場合、新しいPodが作成されます
- Podが正常終了してその他全てのPodも終了している場合、Jobが正常に終了します
- いずれかのPodが正常終了した場合、その他のPodはその作業を処理したり出力したりすることはできません
-
CronJob
CronJobはJobをcronのように定期実行するためのKubernetesのWorkloadリソースです。
スケジュールは Cron形式で指定します。
例
ex)
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "* * * * *"
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
Cronスケジュール構文
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
# │ │ │ │ │ 7 is also Sunday on some systems)
# │ │ │ │ │ 又は sun, mon, tue, wed, thu, fri, sat
# │ │ │ │ │
# * * * * *
ex)
0 0 13 * 5
上の例では、毎月13日の金曜日の00:00に定期実行する
CronJobの制限
スケジュール毎に"およそ"1つのJobオブジェクトを生成します。
たまに2つのjobや1つのjobが生成されない場合もありえます。
そのため、CronJobは冪等的に実装される必要があります。
CronJob毎に、CronJobコントローラーは最後の実行から現在に至るまでどれくらいの数のスケジュールがスキップされたかをチェックしています。
もし100回以上のスケジュールがスキップされている場合は、それ以上のjobを実行したりログを出力したりエラーを出力したりしません。
Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew.
startingDeadlineSeconds
フィールドがセットされている場合、
startingDeadlineSeconds
から現在に至るまでどれくらいのJobがスキップされたかをCronJobコントローラーはカウントします。
startingDeadlineSeconds
でスケジュールされた時間にCronJobが生成できないと失敗したとみなされます。例えば、concurrencyPolicy
がForbid
に設定されている場合、前回のスケジュールがまだ実行中にCronJobをスケジュールしようとするとCronJobは生成されません。
CronJobはスケジュールに一致するJobの作成のみを管理し、そのJobがPodの管理を行います。
Discussion