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: 80
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
kustomizeを使ってkubernetesへの反映は kubectl apply -k <ディレクトリ>
で実行するのですが、動作確認でいちいちapplyはしていられないのでこの記事ではkustomize実行時にどのようなマニフェストファイルになるのか表示して確認してみます。
# CLIの場合はこちら(以後省略)
#$ kustomize build base
$ kubectl kustomize base
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:
- 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/prod
apiVersion: 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: 80
replicasが上書きできました!!!
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: 8080
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
# patchファイルを追加
patchesStrategicMerge:
- deployment-patch-nginx.yaml
ファイルの準備ができたら実行してみましょう!
$ kubectl kustomize base
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:
- 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=value2
kustmization.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.properties
apiVersion: v1
data:
key1: value1
key2: value2
kind: ConfigMap
metadata:
name: application-config
Secretをbase64せず生成する
Secretは環境変数の値をbase64する必要がありますが、secretGenerator
を使うとbase64前の文字列で管理ができます!
secretGenerator:
- name: sample-secret
literals:
- username=admin
- password=p@ssw0rd
apiVersion: 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: replacedName
patchesStrategicMerge
では「kind」「apiVersion」「metadata.name」を合致させる縛りがありましたが、patches
ではtargetで指定できるのでより自由度が高くなっています!
(うまく使えばテンプレートからアプリケーション固有のマニフェストファイルを生成なんてことができそうな…!)