KubernetesのYAMLを環境毎のに分ける時にkubectlに標準で入っているkustomizeを使ってるのですが、サンプルなどに書かれている patchesStrategicMerge
では以下のようなYAML内の値に変数を埋め込めないな。と考えていました。
kustomizeのリポジトリを見ていたら vars
という設定を見つけたので、これをを上手く使えないか考えた方法を書いていきます。
利用ケース
例えば以下のCronJobのようなManifestがあった場合に $(ENV)
などの変数を埋め込みたい場合に利用できます。
apiVersion: batch/v1beta1 kind: CronJob metadata: name: test-cron-job spec: schedule: "*/1 * * * *" concurrencyPolicy: Allow failedJobsHistoryLimit: 5 successfulJobsHistoryLimit: 5 startingDeadlineSeconds: 5 suspend: false jobTemplate: spec: template: spec: restartPolicy: Never containers: - name: test-job image: $(ENV)acr.azurecr.io/test-job-$(ENV) env: - name: ENV value: $(ENV) - name: PROJECT value: $(PROJECT) - name: LOCATION value: $(LOCATION)
Varsの設定の読み方
これを実現するためにはkustomizeのvarsという設定を利用します。
具体的にはkustomization.ymlに以下のようにvarsの設定を書いていきます。
この読み方が最初わからなかったのですが、
name=test-cron-job
が設定された batch/v1beta1.CronJob
に対して、 metadata.labels.env
の値を参照して、変数 ENV
として設定する設定と理解しています。
日本語わかりにくいですね。実際にやってみます。
vars: - name: ENV objref: kind: CronJob name: test-cron-job apiVersion: batch/v1beta1 fieldref: fieldpath: metadata.labels.env
ファイル構造
以下のkustomizeのサンプルなどに近い構造を作ってみます。
test-job/ ├── base │ ├── cronjob.yml │ ├── kustomization.yml │ └── varreference.yml └── overlays ├── dev │ ├── cronjob_meta.yml │ └── kustomization.yml └── prod ├── cronjob_meta.yml └── kustomization.yml
ファイルの中身(overlays側)
この方式を採ると、環境毎に必用なoverlays側がシンプルになるのがメリットかと思っています。
overlays/${ENV}/cronjob_meta.yml
環境毎の設定はこのファイルに入れます。
labels
の下に変数の設定をKeyValueで入れる方法にしました。かなりシンプルに設定書けます。
kind
と metadata.name
はbase側の定義との紐付けに利用します。
apiVersion: batch/v1beta1 kind: CronJob metadata: name: test-cron-job labels: env: dev location: japan project: A
overlays/${ENV}/kustomization.yml
kustomizationはbase側を指定しているだけです。
もっと言えば、今回の設定ではbase側にLabelsを付与しているだけになります。
bases: - ../../base patchesStrategicMerge: - cronjob_meta.yml
ファイルの中身(base側)
base側は共通の定義を作成します。
base/cronjob.yml
base/cronjob.yml
にはは変数を $(VARIABLE)
という形式で埋め込みます。
apiVersion: batch/v1beta1 kind: CronJob metadata: name: test-cron-job spec: schedule: "*/1 * * * *" concurrencyPolicy: Allow failedJobsHistoryLimit: 5 successfulJobsHistoryLimit: 5 startingDeadlineSeconds: 5 suspend: false jobTemplate: spec: template: spec: restartPolicy: Never containers: - name: test-job image: $(ENV)acr.azurecr.io/test-job-$(ENV) env: - name: ENV value: $(ENV) - name: PROJECT value: $(PROJECT) - name: LOCATION value: $(LOCATION)
base/kustomization.yml
base/kustomize
は vars
と configurations
が設定されています。
namespace: otomo-test resources: - cronjob.yml configurations: - varreference.yml vars: - name: ENV objref: kind: CronJob name: test-cron-job apiVersion: batch/v1beta1 fieldref: fieldpath: metadata.labels.env - name: LOCATION objref: kind: CronJob name: test-cron-job apiVersion: batch/v1beta1 fieldref: fieldpath: metadata.labels.location - name: PROJECT objref: kind: CronJob name: test-cron-job apiVersion: batch/v1beta1 fieldref: fieldpath: metadata.labels.project
繰り返しになりますが、 vars
の以下の設定は metadata.labels.location
の値を、 $(LOCATION)
に設定する意味になります。
- name: LOCATION objref: kind: CronJob name: test-cron-job apiVersion: batch/v1beta1 fieldref: fieldpath: metadata.labels.location
base/varreference.yml
最後に configurations
で設定されていた varreference.yml
についてです。
中身は以下になります。
varReference: - path: spec/jobTemplate/spec/template/spec/containers/image kind: CronJob
varsで設定した変数はどこにでも埋め込めるわけではなくて、以下のファイルに指定された要素にだけ埋め込みが可能です。
varReference
を定義することでこれを拡張することができます。
kustomize/varreference.go at master · kubernetes-sigs/kustomize · GitHub
ちなみにvarreferenceの設定無しでkustomizeを実行すると、以下のように対応していないimageの要素だけが $(ENV)
を埋められずに残ってしまいます。
containers: name: test-job image: $(ENV)acr.azurecr.io/test-job-$(ENV) - env: - name: ENV value: prod - name: PROJECT value: Z - name: LOCATION value: us
実行結果
こちらのバージョンで実行してみます。
$ kubectl version --short Client Version: v1.17.3 Server Version: v1.16.7
dev環境
まずはここまで書いてきたdev環境の実行結果です。ちゃんと設定が反映されています。
$ kubectl kustomize ./test-job/overlays/dev/ apiVersion: batch/v1beta1 kind: CronJob metadata: labels: env: dev location: japan project: A name: test-cron-job namespace: otomo-test spec: concurrencyPolicy: Allow failedJobsHistoryLimit: 5 jobTemplate: spec: template: spec: containers: - env: - name: ENV value: dev - name: PROJECT value: A - name: LOCATION value: japan image: devacr.azurecr.io/test-job-dev name: test-job restartPolicy: Never schedule: '*/1 * * * *' startingDeadlineSeconds: 5 successfulJobsHistoryLimit: 5 suspend: false
prod環境
prod環境は overlays/prod/cronjob_meta.yml
だけを修正します。
apiVersion: batch/v1beta1 kind: CronJob metadata: name: test-cron-job labels: env: prod location: us project: Z
ちゃんとprod側の変数が反映されています。
$ kubectl kustomize ./test-job/overlays/prod/ apiVersion: batch/v1beta1 kind: CronJob metadata: labels: env: prod location: us project: Z name: test-cron-job # --省略 containers: - env: - name: ENV value: prod - name: PROJECT value: Z - name: LOCATION value: us image: prodacr.azurecr.io/test-job-prod name: test-job # --省略