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


はじめに

今回はJobの同時実行を制御するパラメータ「concurrencyPolicy」の動作を確認したいと思います。
設定できる値は以下の3つがあります。

設定値 概要
Allow(デフォルト) 同時実行を許可する(特に制御しない)
Forbid 同時実行しない(前のJobが終了していない場合は次のJobを実行しない)
Replace 前のJobが終了していない場合、そのJobをキャンセルして次のJobを実行する

Allow

まずはデフォルトのAllowの動作を確認します。
作成したyamlファイルはこちらです。

sampleCronJob2.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: sample-cronjob
spec:
  schedule: "*/1 * * * *"
  concurrencyPolicy: Allow
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: sample-cronjob
            image: centos:latest
            command:
            - sh
            - -c
            args:
            - echo "start job"; sleep 90; echo "end job"
          restartPolicy: Never

1分間隔でJobを実行しますが、Jobの実行中に90秒スリープしますので、前後のJobが重なります。

このマニフェストをapplyします。

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

別ターミナルでPodの状態を確認します。

$ kubectl get pod -w
NAME                              READY   STATUS    RESTARTS   AGE
sample-cronjob-1585397160-psxdm   0/1     Pending   0          0s
sample-cronjob-1585397160-psxdm   0/1     Pending   0          0s
sample-cronjob-1585397160-psxdm   0/1     ContainerCreating   0          0s
sample-cronjob-1585397160-psxdm   0/1     ContainerCreating   0          2s
sample-cronjob-1585397160-psxdm   1/1     Running             0          8s
sample-cronjob-1585397220-tb4bb   0/1     Pending             0          0s
sample-cronjob-1585397220-tb4bb   0/1     Pending             0          0s
sample-cronjob-1585397220-tb4bb   0/1     ContainerCreating   0          0s <--1つ目のPod実行中に2つ目のPodをデプロイ
sample-cronjob-1585397220-tb4bb   0/1     ContainerCreating   0          0s
sample-cronjob-1585397220-tb4bb   1/1     Running             0          6s
sample-cronjob-1585397160-psxdm   0/1     Completed           0          98s <--1つ目のPod終了
sample-cronjob-1585397280-wls7r   0/1     Pending             0          0s
sample-cronjob-1585397280-wls7r   0/1     Pending             0          0s
sample-cronjob-1585397280-wls7r   0/1     ContainerCreating   0          0s
sample-cronjob-1585397280-wls7r   0/1     ContainerCreating   0          1s
sample-cronjob-1585397280-wls7r   1/1     Running             0          6s
sample-cronjob-1585397220-tb4bb   0/1     Completed           0          95s
sample-cronjob-1585397280-wls7r   0/1     Completed           0          96s

複数のJob(Pod)が同時に実行していることが確認できます。

Forbid

次にForbidの動作を確認します。
作成したyamlファイルは、Allowを「Forbid」に変えただけです。

sampleCronJob2.yaml
・・・
  concurrencyPolicy: Forbid
・・・

同様にapplyして、別ターミナルでPodの動作を確認します。

$ kubectl get pod -w
NAME                              READY   STATUS    RESTARTS   AGE
sample-cronjob-1585398660-7r52w   0/1     Pending   0          0s
sample-cronjob-1585398660-7r52w   0/1     Pending   0          0s
sample-cronjob-1585398660-7r52w   0/1     ContainerCreating   0          0s
sample-cronjob-1585398660-7r52w   0/1     ContainerCreating   0          2s
sample-cronjob-1585398660-7r52w   1/1     Running             0          6s
sample-cronjob-1585398660-7r52w   0/1     Completed           0          97s
sample-cronjob-1585398720-4fbrs   0/1     Pending             0          0s <--1つ目のPodが終了してから2つ目のPodをデプロイ
sample-cronjob-1585398720-4fbrs   0/1     Pending             0          0s
sample-cronjob-1585398720-4fbrs   0/1     ContainerCreating   0          0s
sample-cronjob-1585398720-4fbrs   0/1     ContainerCreating   0          1s
sample-cronjob-1585398720-4fbrs   1/1     Running             0          6s
sample-cronjob-1585398720-4fbrs   0/1     Completed           0          96s
sample-cronjob-1585398840-smvlz   0/1     Pending             0          0s
sample-cronjob-1585398840-smvlz   0/1     Pending             0          0s
sample-cronjob-1585398840-smvlz   0/1     ContainerCreating   0          0s
sample-cronjob-1585398840-smvlz   0/1     ContainerCreating   0          1s
sample-cronjob-1585398840-smvlz   1/1     Running             0          6s
sample-cronjob-1585398840-smvlz   0/1     Completed           0          96s

Allowとは違って、1つ目のPodが終了してから2つ目のPodがデプロイされていることが確認できます。

1つ目と2つ目のJobの起動時間を確認します。

$ kubectl describe job sample-cronjob-1585398660
Name:           sample-cronjob-1585398660
・・・
Start Time:     Sat, 28 Mar 2020 21:31:06 +0900
・・・

$ kubectl describe job sample-cronjob-1585398720
Name:           sample-cronjob-1585398720
・・・
Start Time:     Sat, 28 Mar 2020 21:32:46 +0900
・・・

約100秒後に2つ目のJobが起動してますね。
CronJobの実行間隔は1分(60秒)にしています。Jobが終了していない場合、次のJobをスキップ(120秒後)するのではなく、保留していて、前のJobが終了したら次のJobを実行する動作であることがわかります。

Replace

最後にReplaceの動作を確認します。
作成したyamlファイルは、同様にspec.concurrencyPolicyを「Replace」に変えただけです。

applyして、同様にPodの状態を確認します。

$ kubectl get pod -w
NAME                              READY   STATUS    RESTARTS   AGE
sample-cronjob-1585400580-2p7ph   0/1     Pending   0          0s
sample-cronjob-1585400580-2p7ph   0/1     Pending   0          0s
sample-cronjob-1585400580-2p7ph   0/1     ContainerCreating   0          0s
sample-cronjob-1585400580-2p7ph   0/1     ContainerCreating   0          1s
sample-cronjob-1585400580-2p7ph   1/1     Running             0          6s
sample-cronjob-1585400640-svjxz   0/1     Pending             0          0s 
sample-cronjob-1585400640-svjxz   0/1     Pending             0          0s
sample-cronjob-1585400640-svjxz   0/1     ContainerCreating   0          0s <-- 2つ目のPodデプロイ
sample-cronjob-1585400580-2p7ph   1/1     Terminating         0          61s <-- 1つ目のPod削除
sample-cronjob-1585400640-svjxz   0/1     ContainerCreating   0          1s
sample-cronjob-1585400640-svjxz   1/1     Running             0          6s
sample-cronjob-1585400580-2p7ph   0/1     Terminating         0          93s
sample-cronjob-1585400580-2p7ph   0/1     Terminating         0          96s
sample-cronjob-1585400580-2p7ph   0/1     Terminating         0          96s
sample-cronjob-1585400700-jmhhc   0/1     Pending             0          0s
sample-cronjob-1585400700-jmhhc   0/1     Pending             0          0s
sample-cronjob-1585400700-jmhhc   0/1     ContainerCreating   0          0s <-- 3つ目のPodデプロイ
sample-cronjob-1585400640-svjxz   1/1     Terminating         0          61s <-- 2つ目のPod削除
sample-cronjob-1585400700-jmhhc   0/1     ContainerCreating   0          1s
sample-cronjob-1585400700-jmhhc   1/1     Running             0          6s
sample-cronjob-1585400640-svjxz   0/1     Terminating         0          92s
sample-cronjob-1585400640-svjxz   0/1     Terminating         0          93s
sample-cronjob-1585400640-svjxz   0/1     Terminating         0          93s
sample-cronjob-1585400700-jmhhc   0/1     Completed           0          97s

3番目のJob実行時に、CronJobをサスペンドにしましたので、3番目のPodのみCompletedになっていますが、最初の2つは途中で削除されています。
JobとPodの状態を確認します。

$ kubectl get job
NAME                        COMPLETIONS   DURATION   AGE
sample-cronjob-1585400700   1/1           97s        6m37s
$ kubectl get pod
NAME                              READY   STATUS      RESTARTS   AGE
sample-cronjob-1585400700-jmhhc   0/1     Completed   0          6m40s

残っているJob/Podは3番目のものだけです。

CronJobの詳細も確認します。

$ kubectl describe cronjobs.batch sample-cronjob
Name:                          sample-cronjob
・・・
Events:
  Type    Reason            Age    From                Message
  ----    ------            ----   ----                -------
  Normal  SuccessfulCreate  5m26s  cronjob-controller  Created job sample-cronjob-1585400580
  Normal  SuccessfulDelete  4m26s  cronjob-controller  Deleted job sample-cronjob-1585400580
  Normal  SuccessfulCreate  4m26s  cronjob-controller  Created job sample-cronjob-1585400640
  Normal  SuccessfulDelete  3m26s  cronjob-controller  Deleted job sample-cronjob-1585400640
  Normal  SuccessfulCreate  3m26s  cronjob-controller  Created job sample-cronjob-1585400700
  Normal  SawCompletedJob   105s   cronjob-controller  Saw completed job: sample-cronjob-1585400700, status: Complete

こちらでも2つのJobが削除されていることがわかりますね。

まとめ

今回はconcurrencyPolicyの動作を確認しました。マニュアルを読んで想定した動きとは少し違う動作でした。
やはり実際やってみないとわからないですね。