[Kubernetes]CronJobの動作を確認する 3

#はじめに
今回はCronJobのヒストリーを保存する数を指定するパラメータの動作を確認したいと思います。
指定するパラメータは以下の2つです。

|パラメータ|概要|デフォルト値
|:---|:---|:---
|successfulJobsHistoryLimit|成功したJobを保存する数|3
|failedJobsHistoryLimit|失敗したJobを保存する数|3

#successfulJobsHistoryLimit
まずは成功したJobを保存する動作から確認します。
作成したマニフェストは以下になります。

```sampleCronJob3.yaml
$ cat sampleCronJob3.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: sample-cronjob
spec:
  schedule: "*/1 * * * *"
  concurrencyPolicy: Allow
  successfulJobsHistoryLimit: 2
  failedJobsHistoryLimit: 2
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: sample-cronjob
            image: centos:latest
            command:
            - sh
            - -c
            args:
            - echo "start job"; sleep 30; echo "end job"
          restartPolicy: Never
```
このマニフェストをapplyして、Pod（Job）の状態を別ターミナルで確認します。

```
$ kubectl get pod -w
NAME                              READY   STATUS    RESTARTS   AGE
sample-cronjob-1585485720-zw945   0/1     Pending   0          0s
sample-cronjob-1585485720-zw945   0/1     Pending   0          0s
sample-cronjob-1585485720-zw945   0/1     ContainerCreating   0          0s
sample-cronjob-1585485720-zw945   0/1     ContainerCreating   0          1s
sample-cronjob-1585485720-zw945   1/1     Running             0          7s
sample-cronjob-1585485720-zw945   0/1     Completed           0          37s
sample-cronjob-1585485780-sjf2s   0/1     Pending             0          0s
sample-cronjob-1585485780-sjf2s   0/1     Pending             0          0s
sample-cronjob-1585485780-sjf2s   0/1     ContainerCreating   0          0s
sample-cronjob-1585485780-sjf2s   0/1     ContainerCreating   0          1s
sample-cronjob-1585485780-sjf2s   1/1     Running             0          6s
sample-cronjob-1585485780-sjf2s   0/1     Completed           0          36s
sample-cronjob-1585485840-f56m5   0/1     Pending             0          0s
sample-cronjob-1585485840-f56m5   0/1     Pending             0          0s
sample-cronjob-1585485840-f56m5   0/1     ContainerCreating   0          0s
sample-cronjob-1585485840-f56m5   0/1     ContainerCreating   0          1s
sample-cronjob-1585485840-f56m5   1/1     Running             0          6s <--⓵
sample-cronjob-1585485840-f56m5   0/1     Completed           0          37s
sample-cronjob-1585485720-zw945   0/1     Terminating         0          2m40s
sample-cronjob-1585485720-zw945   0/1     Terminating         0          2m40s <--⓶
```
successfulJobsHistoryLimitの値は「2」にしています。
3つ目のPod（Job）がデプロイされたタイミングではなく、3つ目のPod（Job）が完了した後に、最初のJobが削除されていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/b7326cb6-c864-3248-de9e-0acc2d566ca2.png)

kubectl describeコマンドでもこの状態遷移が確認できます。

```
$ kubectl describe cronjob sample-cronjob
Name:                          sample-cronjob
・・・
Events:
  Type    Reason            Age    From                Message
  ----    ------            ----   ----                -------
  Normal  SuccessfulCreate  3m41s  cronjob-controller  Created job sample-cronjob-1585485720
  Normal  SawCompletedJob   3m1s   cronjob-controller  Saw completed job: sample-cronjob-1585485720, status: Complete
  Normal  SuccessfulCreate  2m41s  cronjob-controller  Created job sample-cronjob-1585485780
  Normal  SawCompletedJob   2m1s   cronjob-controller  Saw completed job: sample-cronjob-1585485780, status: Complete
  Normal  SuccessfulCreate  101s   cronjob-controller  Created job sample-cronjob-1585485840
  Normal  SawCompletedJob   61s    cronjob-controller  Saw completed job: sample-cronjob-1585485840, status: Complete
  Normal  SuccessfulDelete  61s    cronjob-controller  Deleted job sample-cronjob-1585485720
```

なお、successfulJobsHistoryLimitの値を「0」にすると、Job完了後にJobが削除される動作になります。

```
$ kubectl get pod -w
NAME                              READY   STATUS    RESTARTS   AGE
sample-cronjob-1585487700-bcz5h   0/1     Pending   0          0s
sample-cronjob-1585487700-bcz5h   0/1     Pending   0          0s
sample-cronjob-1585487700-bcz5h   0/1     ContainerCreating   0          0s
sample-cronjob-1585487700-bcz5h   0/1     ContainerCreating   0          1s
sample-cronjob-1585487700-bcz5h   1/1     Running             0          6s
sample-cronjob-1585487700-bcz5h   0/1     Completed           0          35s
sample-cronjob-1585487700-bcz5h   0/1     Terminating         0          40s <-- Job完了後に削除
sample-cronjob-1585487700-bcz5h   0/1     Terminating         0          40s
sample-cronjob-1585487760-xrrn2   0/1     Pending             0          0s
sample-cronjob-1585487760-xrrn2   0/1     Pending             0          0s
sample-cronjob-1585487760-xrrn2   0/1     ContainerCreating   0          0s
sample-cronjob-1585487760-xrrn2   0/1     ContainerCreating   0          2s
sample-cronjob-1585487760-xrrn2   1/1     Running             0          9s
```

#failedJobsHistoryLimit
次は失敗したJobを保存する動作を確認します。
作成したマニフェストはこちらになります。

```sampleCronJob4.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: sample-cronjob
spec:
  schedule: "*/1 * * * *"
  concurrencyPolicy: Allow
  successfulJobsHistoryLimit: 2
  failedJobsHistoryLimit: 2
  jobTemplate:
    spec:
      backoffLimit: 1
      template:
        spec:
          containers:
          - name: sample-cronjob
            image: centos:latest
            command:
            - sh
            - -c
            args:
            - echo "start job"; sleep 5; echo "end job"; exit 1
          restartPolicy: Never
```
failedJobsHistoryLimitは「2」にしています。また、Jobのパラメータの「backoffLimit」を「1」にしています。
backoffLimitの動作については、[こちら](https://qiita.com/dingtianhongjie/items/e4f8cbdf914725d40c84)をご確認ください。

このマニフェストをapplyして、Pod（Job）の動作を別ターミナルで確認します。

```
$ kubectl get pod -w
NAME                              READY   STATUS    RESTARTS   AGE
sample-cronjob-1585576380-j9gwt   0/1     Pending   0          0s
sample-cronjob-1585576380-j9gwt   0/1     Pending   0          0s
sample-cronjob-1585576380-j9gwt   0/1     ContainerCreating   0          0s
sample-cronjob-1585576380-j9gwt   0/1     ContainerCreating   0          1s
sample-cronjob-1585576380-j9gwt   1/1     Running             0          6s
sample-cronjob-1585576380-j9gwt   0/1     Error               0          11s
sample-cronjob-1585576380-bdj87   0/1     Pending             0          0s
sample-cronjob-1585576380-bdj87   0/1     Pending             0          0s
sample-cronjob-1585576380-bdj87   0/1     ContainerCreating   0          0s
sample-cronjob-1585576380-bdj87   0/1     ContainerCreating   0          1s
sample-cronjob-1585576380-bdj87   1/1     Running             0          6s
sample-cronjob-1585576380-bdj87   0/1     Error               0          11s <--➂
sample-cronjob-1585576440-rpfkp   0/1     Pending             0          0s
sample-cronjob-1585576440-rpfkp   0/1     Pending             0          0s
sample-cronjob-1585576440-rpfkp   0/1     ContainerCreating   0          0s
sample-cronjob-1585576440-rpfkp   0/1     ContainerCreating   0          1s
sample-cronjob-1585576440-rpfkp   1/1     Running             0          6s
sample-cronjob-1585576440-rpfkp   0/1     Error               0          11s
sample-cronjob-1585576440-xgsvp   0/1     Pending             0          0s
sample-cronjob-1585576440-xgsvp   0/1     Pending             0          0s
sample-cronjob-1585576440-xgsvp   0/1     ContainerCreating   0          0s
sample-cronjob-1585576440-xgsvp   0/1     ContainerCreating   0          1s
sample-cronjob-1585576440-xgsvp   1/1     Running             0          5s
sample-cronjob-1585576440-xgsvp   0/1     Error               0          11s <--⓸
sample-cronjob-1585576500-2kzbc   0/1     Pending             0          0s
sample-cronjob-1585576500-2kzbc   0/1     Pending             0          0s
sample-cronjob-1585576500-2kzbc   0/1     ContainerCreating   0          0s
sample-cronjob-1585576500-2kzbc   0/1     ContainerCreating   0          1s
sample-cronjob-1585576500-2kzbc   1/1     Running             0          6s
sample-cronjob-1585576500-2kzbc   0/1     Error               0          10s
sample-cronjob-1585576500-gqtwt   0/1     Pending             0          0s
sample-cronjob-1585576500-gqtwt   0/1     Pending             0          0s
sample-cronjob-1585576500-gqtwt   0/1     ContainerCreating   0          0s
sample-cronjob-1585576500-gqtwt   0/1     ContainerCreating   0          1s
sample-cronjob-1585576500-gqtwt   1/1     Running             0          7s <--⓹
sample-cronjob-1585576500-gqtwt   0/1     Error               0          11s
sample-cronjob-1585576380-j9gwt   0/1     Terminating         0          2m40s
sample-cronjob-1585576380-bdj87   0/1     Terminating         0          2m29s
sample-cronjob-1585576380-bdj87   0/1     Terminating         0          2m29s
sample-cronjob-1585576380-j9gwt   0/1     Terminating         0          2m40s <--⓺
```
ログが長いので分かりにくいですが、以下に各ポイントとなる地点を図にしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/b83941e2-9c29-112d-590b-e8fe2c73963d.png)

今回は「failedJobsHistoryLimit」だけでなく、「backoffLimit」の動作も絡んできます。
③④の状態は、backoffLimitの値に達したため、各Jobが終了となっています。
⑥はfailedJobsHistoryLimitの条件に達したため、一番最初のJobとPodが削除されています。

#補足（JobのClean Up）
Jobの動作を確認しているときに、実行が終わったJobが自動で削除されればいいのになーと思って調べていました。

マニュアルを見てみると、ttlSecondsAfterFinishedというパラメータを設定すると、設定した時間のあとに削除してくれるようです。
[kubernetes.io](https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#clean-up-finished-jobs-automatically)

ただ、このパラメータを有効にするには、[TTL Controller](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/)を有効にしないといけないのですが、現時点ではまだα版となっています。
なので、Jobを自動で削除するには、CronJobを使う方がよさそうです。

#まとめ
今回はCronJobのヒストリーについて確認しました。
Jobを定期的に実行していると、実行したJobがどんどん溜まっていきますので、ヒストリーを適切に設定して定期的に削除するようにしておきたいですね。
ただ、実行が終わったJobを残しておくと、kubectl logsコマンドでログを確認することができますので、ある程度は残しておきたいですね。

大きなシステムになると、EFKなどでログ管理基盤を構築すると思いますので、システムの規模とかポリシーなどで変わってくるのかなと思います。

ここまでJobとCronJobの動作を確認してきましたが、多くのパラメータを組み合わせて使用することができますので、色々な動作を指定することができます。ユースケースも追々まとめていけたらなと思います。