KubernetesマニフェストでDRYを守るためのkustomizeの使い方
Kubernetesマニフェストはyamlファイルなので、ファイルの数が多くなるにしたがって記述の重複も多くなって困ります。
kustomizeを利用すると、重複をなくすDRYな状態を保てます。
その他にもKubernetesマニフェストを記述する際に便利な機能があります。
本投稿では、kustomizeの使い方について紹介します。
github.com
目次
インストール方法
$ brew install kustomize
kubectlでもkubectl kustomize
というサブコマンドでkustomizeを利用できます。
ただkustomizeのバージョンが古いので個別にkustomizeをインストールすることをオススメします。
重複をなくす
kustomizeには、overlayという仕組みがあります。
開発環境や本番環境毎に差分のkubernetesマニフェストを用意して、差分の箇所だけ変更できます。
例を以下に示します。
baseについて
まずはフォルダ構成を以下のようにします。
staging環境とproduction環境で一部の差異があることを想定したディレクトリ構成です。
~/app ├── base │ ├── kustomization.yaml │ └── pod.yaml └── overlays ├── production │ ├── kustomization.yaml │ └── pod.yaml └── staging ├── kustomization.yaml └── pod.yaml
base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization commonLabels: app: example resources: - pod.yaml
kustomization.yaml
はkustomizeの設定用のリソースファイルです。kustomizeを利用するにはこのファイルが必要です。
resources
では、kustomizeの処理に含まれるyamlファイルを指定します。
commonLabels
でkustomizeで処理するファイル全体に共通のlabel指定を行うことができます。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: selector: matchLabels: app: example template: spec: containers: - name: nginx image: nginx:1 ports: - containerPort: 80
kubernetesのyamlを書きます。
commonLabels
で指定しているので、labelの記述は不要です。
stagingについて
staging環境における構成です。
overlays/staging/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../../base patches: - path: pod.yaml images: - name: nginx newTag: "1.18"
resouces
でbaseのディレクトリを指定します。
patches
で差分のyamlファイルを指定します。
images
ではイメージタグの差分を個別に指定することができます。
下記のようにコマンドでkustomization.yaml
のimages
を変更することが可能です。
$ kustomize edit set image nginx:1.19
overlays/staging/pod.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 2
replicas
を差分として追加します。
apiVersion
などの記述は変更箇所を特定するために必要です。
kubectl apply
をするには以下のようにします。
$ kustomize build overlays/staging | kubectl apply -f -
kustomize build
でkustomizeの処理を適用したKubernetesマニフェストが出力されます。
productionについて
production環境における構成です。
overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../../base patches: - path: pod.yaml images: - name: nginx newTag: "1.19"
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 4
ConfigMapの変更を反映する
kustomizeのconfigMapGeneratorを使用すると、ConfigMapを変更してもそれを参照しているPodにConfigMapの変更が反映されないという事象に対応できます。
これはconfigMapGeneratorを使うことでconfigMapの変更をトリガーにして、kubernetesリソースのローリングアップデートを機能させることができるためです。
例を以下に示します。
baseの構成は先ほどと変わらず、overlaysを修正します。
overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../../base configMapGenerator: - envs: - config.env name: config secretGenerator: - envs: - secret.env name: secret type: Opaque patches: - path: pod.yaml images: - name: nginx newTag: "1.19"
configMapGenerator
で環境変数ファイルを指定します。
secretGenerator
もありますが、configMapGenerator
と使い方はほぼ変わりません。
overlays/production/pod.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 4 template: spec: containers: - name: nginx envFrom: - configMapRef: name: config - secretRef: name: secret
envFrom
では、各Generatorのnameを指定します。
overlays/production/config.env
ENV=production
overlays/production/secret.env
USER=production PASSWORD=production
secretの暗号化はsecretGenerator
で実施してくれます。
Secretリソースを作る時のように暗号化した値の指定は不要です。
kustomize build
すると以下の出力になります.
apiVersion: v1 data: ENV: production kind: ConfigMap metadata: name: config-fctgtgtt22 --- apiVersion: v1 data: PASSWORD: cHJvZHVjdGlvbg== USER: cHJvZHVjdGlvbg== kind: Secret metadata: name: secret-52d6mkchk6 type: Opaque --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: example name: nginx spec: replicas: 4 selector: matchLabels: app: example template: metadata: labels: app: example spec: containers: - envFrom: - configMapRef: name: config-fctgtgtt22 - secretRef: name: secret-52d6mkchk6 image: nginx:1.19 name: nginx ports: - containerPort: 80
configMapのname
のsuffixに識別子が付与されています。
configの内容が変更される毎にこの識別子が変更されるので、kubectl apply
をするとローリングアップデートが行われます。
また、secretの値が暗号化されています。
まとめ
kustomizeを使えばKubernetesマニフェストの記述が楽になります。
kustomizeには今回紹介したこと以外にも機能があるので公式のドキュメントを見てみると良いと思います。