kubernetes
kustomize

KubernetesのYAML管理ツールkustomizeを試してみた


kustomizeとは


  • kubernetes(以下、k8sと表記)のYAML設定ファイルをパッケージングするツール

  • 基盤となるbase構成から、カスタマイズを加えてパッケージングすることができる

  • 出力は単一のYAMLファイルになる

  • あくまでもパッケージングのためのツールなので、出来上がったYAMLをどのようにk8sに適用するかまでは面倒を見てくれない


  • Helmと競合しそうだが、以下の点で差別化できる模様


    • Helm: 設定値をテンプレートエンジンで変更可能にしておく必要がある


      • ==> カスタマイズされる元ファイル + カスタマイズのためのファイルについて学習が必要



    • kustomize: あくまでも入力・出力共にkubectl applyできるYAMLを扱う


      • ==> カスタマイズのためのファイル書式のみ学習すればOK






気に入ったところ


  • configmap名の末尾にハッシュ値を付与することにより、強制的な設定値の再読込が可能

  • とにかくひとつのYAMLで出力されること。シンプル!


好きじゃないところ


  • configmapの名前を自動で変更してしまうので、古い設定値が残り続ける(強制的な設定値の再読込とトレードオフだが。。。)


kustomizeを試してみる


インストール

公式のインストールガイドを参照してください

https://github.com/kubernetes-sigs/kustomize/blob/master/INSTALL.md


kustomization.yaml


kustomization.yaml

# すべてのリソースに設定するnamespace

namespace: my-namespace

# リソース名のprefix
namePrefix: alices-

# すべてのリソースに追加するlabelとselector
commonLabels:
someName: someValue
owner: alice
app: bingo

# すべてのリソースに追加するAnnotation
commonAnnotations:
oncallPager: 800-555-1212

# kustomizeでビルドする対象ファイル
resources:
- some-service.yaml
- ../some-dir/some-deployment.yaml

# ファイルからconfigmapを生成する設定
configMapGenerator:
- name: myJavaServerProps
files:
- application.properties
- more.properties

# コマンドからsecretを生成する設定
secretGenerator:
- name: app-tls
commands:
tls.crt: "cat secret/tls.cert"
tls.key: "cat secret/tls.key"
type: "kubernetes.io/tls"
- name: downloaded_secret
commands:
username: "curl -s https://path/to/secrets/username.yaml"
password: "curl -s https://path/to/secrets/password.yaml"
type: Opaque

# baseとなるkustomization.yamlを含むディレクトリ
bases:
- ../../base

# patchを当てるためのファイルを指定する
patches:
- service_port_8888.yaml
- deployment_increase_replicas.yaml
- deployment_increase_memory.yaml

# カスタムリソースの定義
crds:
- crds/typeA.yaml
- crds/typeB.yaml

# kustomize内で使用できるプレースホルダの設定。 $(HOGEHOGE)の形式で参照できる
vars:
- name: SOME_SECRET_NAME
objref:
kind: Secret
name: my-secret
apiVersion: v1
- name: MY_SERVICE_NAME
objref:
kind: Service
name: my-service
apiVersion: v1
fieldref:
fieldpath: metadata.name
- name: ANOTHER_DEPLOYMENTS_POD_RESTART_POLICY
objref:
kind: Deployment
name: my-deployment
apiVersion: apps/v1
fieldref:
fieldpath: spec.template.spec.restartPolicy


表にまとめると以下のとおりです。

Demo=-の部分は暇があれば追加するかもしれません。

項目
概要
Demo

namespace
すべてのリソースに設定するnamespace
-

namePrefix
リソース名のprefix
-

commonLabels
すべてのリソースに追加するlabelとselector
-

commonAnnotations
すべてのリソースに追加するAnnotation
-

resources
kustomizeでビルドする対象ファイル
Demo1

configMapGenerator
ファイルからconfigmapを生成する設定
-

secretGenerator
コマンドからsecretを生成する設定
-

bases
baseとなるkustomization.yamlを含むディレクトリ
Demo2

patches
patchを当てるためのファイルを指定する
Demo2

crds
カスタムリソースの定義
-

vars
kustomize内で使用できるプレースホルダの設定。$(HOGEHOGE)の形式で参照できる
-


Demo1(パッケージング)

configmapで出力を設定できるnginxを用意しました。

deployment, configmap, serviceで3つのYAMLファイルに分かれています。

さらにこれらをkustomizeでひとまとめにするための設定をkustomization.yamlに記述しました。


ファイル一覧

└── demo1

├── configmap.yaml
├── deployment.yaml
├── kustomization.yaml #kustomize用の設定ファイル
└── service.yaml


kustomization.yaml

resources: #今回は取り上げていませんが、resourcesの設定に`path/to/yamls/*` などとワイルドカード指定が使えます

- deployment.yaml
- configmap.yaml
- service.yaml


deployment.yaml

apiVersion: apps/v1

kind: Deployment
metadata:
name: nginx-test
spec:
replicas: 1
selector:
matchLabels:
app: nginx-test
template:
metadata:
labels:
app: nginx-test
spec:
containers:
- name: nginx-test
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: config
mountPath: /usr/share/nginx/html
volumes:
- name: config
configMap:
name: nginx-test


configmap.yaml

apiVersion: v1

kind: ConfigMap
metadata:
name: nginx-test
data:
index.html: hello kustomize


service.yaml

apiVersion: v1

kind: Service
metadata:
name: nginx-test
spec:
type: NodePort
selector:
app: nginx-test
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 8080

これをkustomizeでパッケージングしてみます


コマンド

kustomize build demo1


結果は標準出力に表示されます。

configmapの名前がnginx-test-tkhfbfb9ffに変わっていることに注目してください。

末尾にハッシュ値が追加され。参照している側のdeploymentでも自動的に設定されています。

configmapのみの変更をk8sにデプロイしたら、Podがホットリロードに対応しておらず設定変更されない!ということがありましたが、

kustomizeならばdeploymentの設定値が変更されることにより、Podが自動的に再作成されて設定値が読み込まれます。


出力

apiVersion: v1

data:
index.html: hello kustomize
kind: ConfigMap
metadata:
name: nginx-test-tkhfbfb9ff # configmapの名前が自動的に変更されている
---
apiVersion: v1
kind: Service
metadata:
name: nginx-test
spec:
ports:
- name: http
nodePort: 8080
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx-test
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-test
spec:
replicas: 1
selector:
matchLabels:
app: nginx-test
template:
metadata:
labels:
app: nginx-test
spec:
containers:
- image: nginx:alpine
name: nginx-test
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: config
volumes:
- configMap:
name: nginx-test-tkhfbfb9ff # 参照側も変わる
name: config

一気にデプロイまでしたい場合は、以下のようなコマンドを実行するとよいでしょう。

kustomize build demo1 | kubectl apply -f -

きちんとデプロイされた場合、以下のようになるはずです

hello-kustomize-demo1


Demo2(設定値の上書き)

Demo1で実施した内容を、部分的に書き換えてみます。(configmapの内容を変更し、レプリカ数を2に変更します)

変えたい部分だけのYAMLを作成し、ほかはdemo1を参照させます。

patch用のYAMLは、最低限apiVersion, kind, metadata.nameがあれば動くようです。

ここでは取り上げていませんが、baseは複数あっても動作します。


ファイル一覧

├── demo1

〜〜〜〜〜〜
└── demo2
├── configmap.yaml
├── deployment.yaml
└── kustomization.yaml


kustomization.yaml

bases:

- ../demo1
patches:
- deployment.yaml
- configmap.yaml


deployment.yaml

apiVersion: apps/v1

kind: Deployment
metadata:
name: nginx-test
spec:
replicas: 2


configmap.yaml

apiVersion: v1

kind: ConfigMap
metadata:
name: nginx-test
data:
index.html: hello kustomize demo2


コマンド

kustomize build demo2



出力

apiVersion: v1

data:
index.html: hello kustomize demo2
kind: ConfigMap
metadata:
name: nginx-test-9gb64hc8d7
---
apiVersion: v1
kind: Service
metadata:
name: nginx-test
spec:
ports:
- name: http
nodePort: 8080
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx-test
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-test
spec:
replicas: 2
selector:
matchLabels:
app: nginx-test
template:
metadata:
labels:
app: nginx-test
spec:
containers:
- image: nginx:alpine
name: nginx-test
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: config
volumes:
- configMap:
name: nginx-test-9gb64hc8d7
name: config

デプロイするともちろん内容が変わります

hello-kustomize-demo2


その他


検証環境


  • k8s: v1.11.0

  • kubectl: v1.11.0

  • kustomize: v1.0.3


参考