Kuberneteを使っていると、環境ごとに別々のyamlファイルを作ると思います。
ただ、環境ごとファイルを作っても一部が違うだけでほぼほぼ同じファイルになちゃったりしますよね。。。
そんな状況をKustomizeを使うことで改善できます!
この記事ではkustomizeの使い方について逆引きで解説していきます。
導入
kubernetesユーザであれば、普段kubectlコマンドで操作をしているのではないでしょうか?
kustomizeはkubectlに内包されているため、kubectlを利用している場合は特に手順はありません。
一方、ローカルではkubectlが実行できない(CICD上でしか実行できない)場合には、kustomize単体をインストールすることもできます。
Macの場合はhomebrewでインストールできます!
$ brew install kustomize※インストール手順の公式ドキュメントはこちらです
使ってみる
まずは使ってみて、できることや使い方を大雑把に把握してみましょう!
最終的にはこのような構成になります。
├── base
│ ├── deployment.yaml
│ └── kustomization.yaml
└── overlays
└── prod
├── deployment-patch.yaml
└── kustomization.yamlディレクトリ作成
まずはディレクトリを作成します。
kustomizeには決まったディレクトリ構成はないのですが、これまでみてきた中で一番しっくりきてシンプルな構成を紹介します。
| ディレクトリ | 役割 |
|---|---|
| base | ・マニフェストのベースファイルを配置する |
| overlays/<環境> | ・マニフェストのパッチファイルを配置する ・環境に依存する定義をここに |
kustomize実行
まずはkustomizeを使うだけ使ってみましょう。
baseディレクトリ配下に2つのファイルを作成します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yamlkustomizeを使ってkubernetesへの反映は kubectl apply -k <ディレクトリ>で実行するのですが、動作確認でいちいちapplyはしていられないのでこの記事ではkustomize実行時にどのようなマニフェストファイルになるのか表示して確認してみます。
# CLIの場合はこちら(以後省略)
#$ kustomize build base
$ kubectl kustomize baseapiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.14.2
name: nginx
ports:
- containerPort: 80そのまま表示されるだけなのでまだ旨味はないですねw
差分をoverlays配下に定義
次に環境ごとの差分をoverlays/prodに置いて動かしてみます。
replicasを変えてみましょう。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 5・apiVersion
・kind
・metadata.name
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# baseディレクトのパスを指定(このファイルからの相対パス)
bases:
- ../../base
# パッチファイルを指定(このファイルからの相対パス)
patchesStrategicMerge:
- ./deployment-patch.yamlここまで準備ができたら、kustomizeを実行してみましょう!
# 作成したい環境のoverlaysディレクトリを指定する
$ kubectl kustomize overlays/prodapiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-deployment
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.14.2
name: nginx
ports:
- containerPort: 80replicasが上書きできました!!!
Kustomizeでできること
ここからはkustomizeでできることを逆引きで解説していきます。
マニフェストに設定を追加する
サイドカーを多く利用する場合deploymentファイルが大きくなりがちで、どの設定がどのコンテナと関係があるのかわかりにくくなりますよね。。。
なので、サイドカーの設定をpatchファイルに移動しちゃいましょう!
ここではnginxを2層にしたくなったと仮定します(そんなことにはなかなかならないとお思いますがw)
※サイドカーは環境ごと中身が変わらないと仮定
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
template:
spec:
containers:
- name: nginx-sidecar
image: nginx:1.14.2
ports:
- containerPort: 8080apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
# patchファイルを追加
patchesStrategicMerge:
- deployment-patch-nginx.yamlファイルの準備ができたら実行してみましょう!
$ kubectl kustomize baseapiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.14.2
name: nginx-sidecar
ports:
- containerPort: 8080
- image: nginx:1.14.2
name: nginx
ports:
- containerPort: 80・kind
・apiVersion
・metadata.name
プロジェクト間共通の設定をgithubから読み込む
resourcesやpatchesStrategicMergeにはgithubのraw URLを指定することもできます!
共通的なマニフェストをどこか1箇所のリポジトリにまとめておけば、複数のプロジェクトで共有できるのでとても管理が楽になります!
raw URLを指定したkustomization.yamlはこんな感じです!
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://raw.githubusercontent.com/rhirabay/my-projects/main/kubernetes/kustomize/trial/base/deployment.yaml
patchesStrategicMerge:
- https://raw.githubusercontent.com/rhirabay/my-projects/main/kubernetes/kustomize/trial/base/deployment-patch-nginx.yamlファイルからconfigMapを生成する(ファイル編)
kubectl create configmap <configmap名> --from-file <ファイル名> と同様のことがkustomizeでもできます。
まずはconfigMapで反映したい設定ファイルを作成します。(お試しなので内容は適当)
key1=value1
key2=value2kustmization.yamlではconfigMapGeneratorを使用します。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
configMapGenerator:
- name: application-config
files:
- application.propertiesまた、baseのdeployment.yamlもここで作成したconfigMapを読み込むように設定を追加しておきます。
envFrom:
- configMapRef:
name: application-configこれで実行してみましょう!
apiVersion: v1
data:
application.properties: |-
key1=value1
key2=value2
kind: ConfigMap
metadata:
name: application-config-2hhtc6gcdk
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- envFrom:
- configMapRef:
name: application-config-2hhtc6gcdk
image: nginx:1.14.2
name: nginx
ports:
- containerPort: 80
・deployment側のconfigmapのnameも付与されたsuffixに対応してくれます
もし自動で付与されるsuffixが嫌な場合は、generatorOptionsを設定しましょう
configMapGenerator:
- name: application-config
files:
- application.properties
# suffixを付与したくない場合
generatorOptions:
disableNameSuffixHash: trueファイルからconfigMapを生成する(data編)
ファイル編で、ファイルをそのままconfigmapに登録することをしましたが、
data形式で環境変数としてコンテナに配布することも可能です!
ファイル編のfilesをenvsに変えるだけです!
configMapGenerator:
- name: application-config
# 環境変数で配布したい場合は「envs」
envs:
- application.propertiesapiVersion: v1
data:
key1: value1
key2: value2
kind: ConfigMap
metadata:
name: application-configSecretをbase64せず生成する
Secretは環境変数の値をbase64する必要がありますが、secretGenerator を使うとbase64前の文字列で管理ができます!
secretGenerator:
- name: sample-secret
literals:
- username=admin
- password=p@ssw0rdapiVersion: v1
data:
password: cEBzc3cwcmQ=
username: YWRtaW4=
kind: Secret
metadata:
name: sample-secret-8752d75k47
type: Opaque・configmapと同じく
envsやfilesも使えます。マニフェストの一部を変更する
pachesを使うとマニフェストの一部を変更することができます。
例えば以下のようなkustomization.yamlを用意すると
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
patches:
- target:
kind: Deployment
patch: |-
- op: replace
path: /metadata/name
value: replacedNameこんな感じになります!
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: replacedNamepatchesStrategicMergeでは「kind」「apiVersion」「metadata.name」を合致させる縛りがありましたが、patchesではtargetで指定できるのでより自由度が高くなっています!
(うまく使えばテンプレートからアプリケーション固有のマニフェストファイルを生成なんてことができそうな…!)

