モチベーション
今担当しているシステムではkube-jobを利用し、特定のPodからjobを起動しています。
実行するbatchのマニフェストは、configmapで管理しています。configmapをdeploymentでマウントして実行するイメージです。
configmapの中にkubernetesマニフェストであるbatchを記述するのですが、
- configmap内にマニフェストを書いているので可読性が損なわれる
- 記述ミスが増そう(予感
など、色々問題がありそうなので、このタイミングで直しました。
configmapGeneratorの記事はたくさんあるのですが、volumeの設定に関して少しハマったので、備忘録的に残しておきます。
対策する前はこんな感じです。マニフェストの中にマニフェストを書くのはちょっと辛い。
apiVersion: v1
kind: ConfigMap
metadata:
name: config
data:
task.yml: |+
apiVersion: batch/v1
kind: Job
metadata:
name: task
labels:
app: task
前提
- kustomize v4.4.0
- kubectl v1.22.2
ディレクトリ構成
今回は備忘録的に残しておくだけなので、きっちりディレクトリを構成しません。
$ tree
└── base
├── config
│ └── task.yaml # このファイルをConfigmapで扱いたい
├── deployment.yaml # 生成したConfigmapをmountしたい
└── kustomization.yaml
やり方
kustomization.yaml
configMapGenerator
を設定し、files
に実際に読み込みたいファイルを指定します。
files
の内容もkubernetes manifestですが、これはさまざまなユースケースに合わせて自由に記述できます。
resources:
- deployment.yaml
configMapGenerator:
- name: cm-in-task
files:
- ./config/task.yaml # 公式から拾ってきたCronJobのサンプルをコピペして持ってきた
deployment.yaml
volumes
にconfigMapGenerator
で記述したname
、作成するファイル名をitems配下に指定します。
最初envの読み込み方(configMapKeyRef)とごっちゃになりハマりました。普通にマニフェストの仕様通り読み込めばよかったです。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
# (本件と関係ない設定は諸々省略してます)
template:
spec:
# (本件と関係ない設定は諸々省略してます)
containers:
- name: nginx
image: nginx:1.14.2
volumeMounts:
- name: cm-in-task # mountしたいvolumeを指定
mountPath: /etc/config
ports:
- containerPort: 80
volumes:
- name: cm-in-task
configMap:
# どうやって読み込むかで結構ハマった
name: cm-in-task # configmapGeneratorで設定したnameを指定
items:
- key: task.yaml # 生成するファイル名
path: task.yaml # 生成するファイル名
kustomize build
の結果
# configmapが生成されている
apiVersion: v1
data:
task.yaml: |
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
kind: ConfigMap
metadata:
name: cm-in-task-fmtgff4cb2 # hashつきのnameを自動生成
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.14.2
name: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /etc/config
name: cm-in-task
volumes:
- configMap:
items:
- key: task.yaml
path: task.yaml
name: cm-in-task-fmtgff4cb2 # hashつきnameが自動で適用
name: cm-in-task
podの中を確認
実際にpodに入りconfigmapの内容が参照できるか確認します。
$ head etc/config/task.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
終わりに
いかがでしたか?
configmapに複雑な設定を記述したい場合に、外部のファイルに切り出せるのはメリットがありますね。
特に、configmapで生成するマニフェスト自体もkubeval等でチェックできるのが最高です。
今後は、configmapで生成するマニフェストもkustomizeでbase, overlaysで共通化できないかを調べてみたいと考えています。
参考
今回検証するために以下を参考にさせていただきました。