Edited at

Kustomize で CronJob を同一テンプレートからスケジュール毎に生成する


問題

Kubernetes の CronJob は schedule を1つしか設定できません。

そのため同じコンテナ定義で schedulecommand , args だけを変えたスケジュールを設定したくても、その数の分だけ CronJob を作成する必要があります。

# 1個目

apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: greeting-morning
spec:
schedule: 0 9 * * *
jobTemplate:
spec:
template:
spec:
containers:
- image: alpine:latest
name: main
command:
- echo
args:
- Good morning.
---
# 2個目
# 違いは name, schedule, args のみ
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: greeting-midnight
spec:
schedule: 0 0 * * *
jobTemplate:
spec:
template:
spec:
containers:
- image: alpine:latest
name: main
command:
- echo
args:
- It's midnight.


解決策

Kustomize を使ってひとつのテンプレートから複数の CronJob を生成し、さらにそれらを最後にひとつにまとめます。

デモ: https://github.com/yubessy/example-kustomize-cronjob-multiple-schedule

ディレクトリ構成は次のようにします。

.

├── template
│ ├── kustomization.yaml # テンプレート用
│ └── cronjob.yaml # テンプレートとなる CronJob
├── schedules
│   ├── 0-9-any-any-any
│   │   ├── kustomization.yaml # 1個目の CronJob 用
│   │   └── patch.yaml # schedule, args の patch
│   └── 0-0-any-any-any
│   ├── kustomization.yaml # 2個目の CronJob 用
│   └── patch.yaml # schedule, args の patch
└── kustomization.yaml # 最終的に出力をまとめる用

各ファイルの中身はこんな感じです。


template/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1

kind: Kustomization
resources:
- ./cronjob.yaml


template/cronjob.yaml

apiVersion: batch/v1beta1

kind: CronJob
metadata:
name: greeting
spec:
schedule: ""
jobTemplate:
spec:
template:
spec:
containers:
- name: main
image: alpine:latest
command:
- echo
args:
- This is template.


schedules/.../kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1

kind: Kustomization
bases:
- ../../template
# これがないと怒られる
nameSuffix: -midnight
patchesJson6902:
- target:
group: batch
version: v1beta1
kind: CronJob
name: greeting
path: ./patch.yaml


schedules/.../patch.yaml

- op: replace

path: /spec/schedule
value: "0 9 * * *"
- op: replace
path: /spec/jobTemplate/spec/template/spec/containers/0/args/0
value: "Good morning."


kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1

kind: Kustomization
bases:
- ./schedules/0-9-any-any-any
- ./schedules/0-0-any-any-any

schedules/.../kustomization.yamlnameSuffix がミソです。

Kustomize は通常ひとつのベースリソースからひとつの派生リソースしか作れないのですが、nameSuffixnamePrefix を使うと同一のベースリソースから複数の派生リソースを作成することができます。

今回の場合はこれがないと次のようなエラーが出てしまいます。

Error: ./schedules/0-0-any-any-any: id '"batch_v1beta1_CronJob|~X|~P|template|~S"' already used

このディレクトリ構成のトップで kustomize build すれば次のように複数の CronJob がまとめて出力されます。

$ kustomize build

apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: greeting-morning
spec:
jobTemplate:
spec:
template:
spec:
containers:
- args:
- Good morning.
command:
- echo
image: alpine:latest
name: main
schedule: 0 9 * * *
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: greeting-midnight
spec:
jobTemplate:
spec:
template:
spec:
containers:
- args:
- It's midnight.
command:
- echo
image: alpine:latest
name: main
schedule: 0 0 * * *


参考