kubernetesのCronJob調べてみた

## 概要

k8sのCronJobはDeploymentをCron的に扱うのにいいがAPIフィールドが多いのでわけわからなくなる。ので整理した。
ついでにcronjobを起動させ、停止させるところまでやってみる。

ちなみに「DeploymentをCron的に扱う」というのは、

- CronJob が Deployment と対応し、
- Job が ReplicaSet と対応している

という解釈。どちらもPodsを直接扱うのではなく、Podsを *よしなに* 操作する「何か」を作成する。



## CronJobSpecのAPIフィールド

ちなみに [CronJob [batch/v1beta1]](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#cronjob-v1beta1-batch) です。

|フィールド|オプション|説明|
|-----------------|------------------|------------------|
| concurrencyPolicy<br>(string)| Allow(default), Forbid, Replace |Jobの同時実行を許可するかどうか。Allowは許可。Forbidは同時実行を禁止。以前のジョブが完了していなければ、今回の実行をスキップ。Replaceは現在実行中のジョブをキャンセルし、新しいジョブで置換。|
| failedJobsHistoryLimit<br>(iteger)|defaultは1|保持する失敗した終了ジョブの数。|
| jobTemplate|-| CronJobが実行された時に作成されるJobの詳細。|
| schedule<br>(string)|-|Cronフォーマットで記述するスケジュール|
| startingDeadlineSeconds<br>(iteger)|-|なんらかの理由でジョブがスケジュール通り実行できなかった時に許容できる時間。実行されなかったジョブは、失敗ジョブとみなされる。|
| successfulJobsHistoryLimit<br>(iteger)|defaultは3|保持する成功したジョブの数。|
| suspend<br>(boolean)|True,False(default) |後続の実行を一時停止するようにコントローラーに指示する。既に走っている実行には適用されない。|

concurrencyPolicyはちょっと分かりづらいので補足。
例えばあるJobが実行に2分かかるのに、cronが毎分実行される設定になっているとjobが同時に発生することになる。
Allowはそれを許可し、Forbidはそれを禁止し、Replaceは新しいJobを優先するようにするオプションである。

startingDeadlineSecondsも分かりづらいので補足。
例えばあるジョブが何かしらの理由で実行が遅れる/実行できなかったとする。その時ざっくりと「何秒待ってくれるか」という設定を設けられる。ここが0なら全くまたないし、30なら30秒は待ってくれる。その許容時間に実行開始されないと失敗ジョブとみなされる。

## CronJobStatusのAPIフィールド

|フィールド|オプション|説明|
|-----------------|------------------|------------------|
|active<br>(array)|-|同時に実行されているジョブのポインターのリスト。|
| lastScheduleTime<br>(Time) |-|最後にジョブが無事スケジュールされた時の情報。|


## 実行


```cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: sample-cronjob
  namespace: test
spec:
  schedule: "*/1 * * * *"
  failedJobsHistoryLimit: 1
  concurrencyPolicy: Allow
  startingDeadlineSeconds: 30
  successfulJobsHistoryLimit: 5
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: sleep-container
            image: nginx:1.11
            command: ["sleep"]
            args: ["5"]
          restartPolicy: Never
```

ファイルをコマンド実行。

```
$ kubectl apply -f cronjob.yaml
cronjob.batch/sample-cronjob created
```

cronjobが作成されていることがわかる。

```
$ kubectl get cronjob
NAME             SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
sample-cronjob   */1 * * * *   False     0        26s             10m
```

jobを見てみる。定期的に叩けばわかるが、成功した完了ジョブの保持数は5にしているので、5行より増えると古いものが消されていく。

```
$ kubectl get job
NAME                        COMPLETIONS   DURATION   AGE
sample-cronjob-1583660100   1/1           7s         4m39s
sample-cronjob-1583660160   1/1           6s         3m39s
sample-cronjob-1583660220   1/1           7s         2m39s
sample-cronjob-1583660280   1/1           8s         99s
sample-cronjob-1583660340   1/1           7s         38s
```

次にpodを見てみる。たまたま叩いた時にコンテナ実行中のpodが表示されたが、これもjobと同じで5行以上は保持されない。

```
$ kubectl get pods
NAME                              READY   STATUS      RESTARTS   AGE
sample-cronjob-1583660220-fd2mf   0/1     Completed   0          5m4s
sample-cronjob-1583660280-5p9g7   0/1     Completed   0          4m4s
sample-cronjob-1583660340-4sx5f   0/1     Completed   0          3m3s
sample-cronjob-1583660400-mw4zw   0/1     Completed   0          2m3s
sample-cronjob-1583660460-bxd7j   0/1     Completed   0          63s
sample-cronjob-1583660520-4nm2b   1/1     Running     0          3s
```

試しにしばらくして見てみると、5行になっている。

```
$ kubectl get pods
NAME                              READY   STATUS      RESTARTS   AGE
sample-cronjob-1583660280-5p9g7   0/1     Completed   0          4m18s
sample-cronjob-1583660340-4sx5f   0/1     Completed   0          3m17s
sample-cronjob-1583660400-mw4zw   0/1     Completed   0          2m17s
sample-cronjob-1583660460-bxd7j   0/1     Completed   0          77s
sample-cronjob-1583660520-4nm2b   0/1     Completed   0          17s
```

cronjobを止めてみる。下記のようにSUSPEND=TrueになればOK。

```
$ kubectl patch cronjob sample-cronjob -p '{"spec":{"suspend":true}}'
cronjob.batch/sample-cronjob patched

$ kubectl get cronjob
NAME             SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
sample-cronjob   */1 * * * *   True      0        16s             16m
```