0時に寝て6時に起きた。寝不足を解消して体調が戻ってきた。

k8s の cronjob

バッチ処理を Kubernetes: CronJob で作る。一通り設定して minikube で検証して eks 上でも動くようになった。

apiVersion: batch/v1
kind: CronJob
metadata:
  name: my-app-hourly-job
spec:
  schedule: "5 */1 * * *"
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 600
  jobTemplate:
    spec:
      backoffLimit: 0
      template:
        metadata:
          labels:
            app: my-app-hourly
          annotations:
            dapr.io/enabled: "true"
            dapr.io/app-id: "my-app-hourly"
        spec:
          containers:
          - name: my-app-hourly-job
            image: my-app-image
            imagePullPolicy: Always
            env:
            - name: BATCH_ENV
              value: "dev"
            command:
            - "/bin/sh"
            - "/app/scripts/my-app.sh"
            - "param1"
            - "param2"
          restartPolicy: Never

command の設定がわかりにくい。さらに k8s のドキュメントのサンプル設定も誤解を招くような例になっている。どうも実行できるのは1つの cli だけで、複数コマンドを指定できるわけではない。シェルスクリプトを docker イメージに含めて、そこで任意のスクリプトを実装した方がよいだろう。

  • “/bin/sh”
  • “/app/scripts/my-app.sh”
  • “param1”
  • “param2”

この設定は次の cli として実行される。

/bin/sh /app/scripts/my-app.sh param1 param2

How to ensure kubernetes cronjob does not restart on failure によると、バッチ処理が失敗したときに再実行したくないときは次の3つの設定をする。

  • concurrencyPolicy: Forbid
  • backoffLimit: 0
  • restartPolicy: Never

restartPolicy が Never 以外だと、エラーが発生すると永遠に再実行されてしまうので障害時に2次被害を増やしてしまう懸念があったような気がする。

あと、うちの環境は dapr 経由で他の pod サービスと通信しているので dapr を有効にしないと pod 間通信ができない。dapr はデーモンでずっと起動しているからバッチ処理の終了時に daprd も shutdown してやらないといけない。Running Dapr with a Kubernetes Job にその方法が書いてある。daprd を shutdown しないと、pod のステータスが NotReady のままで Completed にならない。

まだまだよくわかってないので Jobs のドキュメントに一通り目を通そうと思っている。