問題
Kubernetes の CronJob は schedule
を1つしか設定できません。
そのため同じコンテナ定義で schedule
と command
, 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 # 最終的に出力をまとめる用
各ファイルの中身はこんな感じです。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./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.
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
- op: replace
path: /spec/schedule
value: "0 9 * * *"
- op: replace
path: /spec/jobTemplate/spec/template/spec/containers/0/args/0
value: "Good morning."
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ./schedules/0-9-any-any-any
- ./schedules/0-0-any-any-any
schedules/.../kustomization.yaml
の nameSuffix
がミソです。
Kustomize は通常ひとつのベースリソースからひとつの派生リソースしか作れないのですが、nameSuffix
か namePrefix
を使うと同一のベースリソースから複数の派生リソースを作成することができます。
今回の場合はこれがないと次のようなエラーが出てしまいます。
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 * * *