kubernetesのCronjob設定

CronJobは定時実行プログラムのcronと同様の機能を提供するJobです。
k8s標準機能であるため、マニフェスト定義だけで利用でき手軽です。

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: webhook
spec:
  # Exec at 23:30JST
  schedule: "30 14 * * *"
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 120
  suspend: false
  successfulJobsHistoryLimit: 2
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: tekton-trigger
            image: curlimages/curl:latest
            command: ["bash"]
            args: ["-c", "curl -XPOST -H 'X-Tekton-Type:container-build' -H 'application/json' -d '{ \"name\": \"production\" }' http://el-tekton.default.svc.cluster.local:8080"]
          restartPolicy: Never

Deploymentなどのマニフェストとほぼ同様で、一部CronJob用の特徴があります。

  • apiVersionはk8s v1.21からbatch/v1、v1.20以前の環境ではbatch/v1beta1
  • spec.scheduleにcron書式のジョブスケジュールを指定
    • 時刻帯はk8sマスターに従う。GKEなど多くの環境でUTC(グリニッジ標準時)
    • JST(日本標準時)とは9時間差の時刻を指定する。世界時計のアプリでグリニッジ(GST+0)を参照すると間違いにくい
  • spec.jobTemplate.spec.template.spec.containersの定義は、Deploymentなどと同様
    • imageは必要なツールを同梱した任意のイメージを指定できる
    • 実行するコマンド類は、commandargsで指定する方法が柔軟

なお、タイムゾーンについては、v1.22でCRON_TZをサポートする計画があるようです。cronのタイムゾーンは昔からあるトピックと言えます。
UTCで定義しておくとグローバル共通設定となり実行環境を選ばないため、現行方式にもメリットがあります。
上の例のようにYAMLのコメントを利用することで足りるケースもあるでしょう。

YAMLのヒアドキュメント

Jobの実行内容は、ワンライナーに収まらないものがあります。
YAMLのヒアドキュメントを利用すると、複数行のスクリプトも書けます。また、クオートを減らせるため、エスケープのトラブルも減らせます。

先ほどの例を書きかえると以下のような記述が可能です。

            command: ["bash"]
            args:
            - "-c"
            - |
              curl -XPOST -H 'X-Tekton-Type:container-build' -H 'application/json' -d '{ "name": "production" }' http://el-tekton.default.svc.cluster.local:8080

インデントは意味を持つので注意が必要です。
また、この例ではヒアドキュメントの行末は改行がつきますが、開始記号により挙動が異なります。

一般的なbashスクリプト同様、行末の改行を抑制するにはバックスラッシュでエスケープします。

CronJobの登録・確認

登録はDeploymentなどと同様、マニフェストのapplyで実行できます。
また、kubectl get cronjobでスケジュールを含むリストを表示できます。

$ kubectl apply -f webhook-job.yaml

# cronjobというリソースができる
$ kubectl get cronjob

NAME                   SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
webhook                30 14 * * *   False     0        13h             43h

手動実行で確認

create jobサブコマンドで即時実行できます。

$ kubetcl create job <temporal job name> --from=cj/<webhook>

登録済のCronJobリストから選択して任意のタイミングでジョブを実行する、 kubectl pick jobプラグインを開発し、オープンソースで提供しています。

Tekton Triggerの定時実行

kubernetesに特化したCIツール Tekton PipelinesはCronJobから TriggerのEventListenerを呼ぶことで定時実行できます。
上の例では、Tekton Triggersをコールする例を定義しています。

上述のとおり、一般的なwebhookと同じ要領でコールできます。

中馬崇尋
Chuma Takahiro