目次
Kubernetes 1.14 以降にGAになったkustomize 機能について実践ベースで紹介します。
こんにちは。ペットのゴールデンハムスターのキンクマを眺めながらWork From Homeしている高田です。 ゴールデンと言えば最近無料配信中のゴールデンカムイを最新話まで勢いで読み切りました。勢いも情報量も凄まじかったですが、面白かったです。
さて今回は、というよりは今回もKubernetesのKustomizeについての話となります。
Kubernetes 1.14 より Kustomize 機能がGAとなっています(https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/)
前回の私の記事で Kusutomize 機能のセットアップから使い方までを紹介しました。 Kubernetes 1.14以降のバージョンへアップグレードすることで、前回のようなセットアップは不要で、Kustomize機能をサブコマンドのように扱えるようになったようです。 ということで今回は Kubernetes 1.14以降のバージョンにて、実際に新しい方法で動作を確認していきたいと思います。
Kustomize機能とそのセットアップ方法については前回の記事を参照してみてください。
今回試した際のKubernetesバージョンはこちらです
Server Version: v1.18.20-gke.501
ディレクトリ構成は以下となります
$ tree .
.
└── base
├── deployment.yaml
├── kustomization.yaml
└── service.yaml
└── overlays
└── dev
├── deployment.yaml
├── kustomization.yaml
└── service.yaml
baseディレクトリの準備
まずは構築場所の定義ということで、以下のような構成をとります
.
└── base
├── deployment.yaml
├── kustomization.yaml
└── service.yaml
上記のコマンド結果はbase配下のディレクトリ構成を示しています。 各yamlファイル内は以下の様にします。
base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
base/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
base/kustomization.yaml
resources:
- deployment.yaml
- service.yaml
確認
kubectl kustomize <kustomization_directory>
を実行できるとのこと kustomization.yamlファイルを定義したディレクトリへ移動しkubectl kustomize .
を実行すると、デプロイされるmanifestsを出力することができました。
$ cd ../base
$ kubectl kustomize .
apiVersion: v1
kind: Service
metadata:
labels:
run: my-nginx
name: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 2
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: nginx
name: my-nginx
ovarlaysの準備
続いて拡張機能側をセットアップしていきます。
.
└── overlays
└── dev
├── deployment.yaml
├── kustomization.yaml
└── service.yaml
各yamlファイルの設定内容です
overlays/dev/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
拡張設定用のkustomize.yamlは公式ドキュメントの通りにpod名にprefixを追加するだけのシンプルなものとします。
overlays/dev/kustomization.yaml
bases:
- ../../base
namePrefix: dev-
確認
base同様にkustomize.yamlファイルの定義したディレクトリ先で実行可能です。
apiVersion: v1
kind: Service
metadata:
labels:
run: my-nginx
name: dev-my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dev-my-nginx
spec:
replicas: 2
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: nginx
name: my-nginx
ディレクトリを間違えてたり、kustomization.yamlで定義したファイル名が間違っていると以下の様にエラーになります。 以下は、ディレクトリを謝って確認コマンドを実行したときの実行例です。
# "overlays/dev/" ディレクトリではなく、"overlays/" ディレクトリで実行すると:
$ cd overlays
$ kubectl kustomize .
Error: unable to find one of 'kustomization.yaml', 'kustomization.yml' or 'Kustomization' in directory '/home/takadamio/polaris-dev-etc/manifest/overlays'
Examples:
# Use the current working directory
kubectl kustomize .
# Use some shared configuration directory
kubectl kustomize /home/configuration/production
# Use a URL
kubectl kustomize github.com/kubernetes-sigs/kustomize.git/examples/helloWorld?ref=v1.0.6
Usage:
kubectl kustomize <dir> [flags] [options]
Use "kubectl options" for a list of global command-line options (applies to all commands).
# kustomization.yamlファイルが見つからずエラーとなってしまった
デプロイ
公式ドキュメントの通りkubectl apply -k <kustomization directory>
とありますので oveylays/dev/ ディレクトリへ移動して以下のコマンドでデプロイしてみます。
$ cd overlays/dev/
$ kubectl apply -k ./
service/dev-my-nginx created
deployment.apps/dev-my-nginx created
kubectl get pod
を実行すると、overlaysされたpodがデプロイされていることが確認できました。
$ kubectl get pod
dev-my-nginx-54cc7d6865-j2gl9 1/1 Running 0 82s
dev-my-nginx-54cc7d6865-ms9r4 1/1 Running 0 82s
既存設定を変更して差分確認する&その時に気をつけたいこと
一度デプロイが完了したpodをそのまま使い続けるというよりは、パラメータを変更しながら運用するケースの方が多いかと思います。 既にデプロイ済みのyamlファイルとの差分を確認する方法として 以下のようにパイプしてコマンドを組み合わせて、デプロイされた既存のmanifestと更新差分を出力確認することが出来ます。
kubectl diff -k .
では先ほどデプロイしたoverlays/dev/kustomization.yamlを変更してやってみましょう。
overlays/dev/kustomization.yaml
を以下の様に変更します。pod名にsuffixを追加しました。
bases:
- ../../base
namePrefix: grasys-
nameSuffix: "-grasys01"
既存のpodとの差分を確認してみます
$ cd overlays/dev/
$ kubectl diff -k .
diff -u -N /tmp/LIVE-979226958/apps.v1.Deployment.default.dev-my-nginx-grasys01 /tmp/MERGED-087402581/apps.v1.Deployment.default.dev-my-nginx-grasys01
--- /tmp/LIVE-979226958/apps.v1.Deployment.default.dev-my-nginx-grasys01 2021-08-16 07:34:48.450766595 +0000
+++ /tmp/MERGED-087402581/apps.v1.Deployment.default.dev-my-nginx-grasys01 2021-08-16 07:34:48.601766503 +0000
@@ -0,0 +1,81 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ creationTimestamp: "2021-08-16T07:34:48Z"
+ generation: 1
+ managedFields:
+ - apiVersion: apps/v1
+ fieldsType: FieldsV1
+ fieldsV1:
+ f:spec:
+ f:progressDeadlineSeconds: {}
+ f:replicas: {}
+ f:revisionHistoryLimit: {}
+ f:selector:
+ f:matchLabels:
+ .: {}
+ f:run: {}
+ f:strategy:
+ f:rollingUpdate:
+ .: {}
+ f:maxSurge: {}
+ f:maxUnavailable: {}
+ f:type: {}
+ f:template:
+ f:metadata:
+ f:labels:
+ .: {}
+ f:run: {}
+ f:spec:
+ f:containers:
+ k:{"name":"my-nginx"}:
+ .: {}
+ f:image: {}
+ f:imagePullPolicy: {}
+ f:name: {}
+ f:resources: {}
+ f:terminationMessagePath: {}
+ f:terminationMessagePolicy: {}
+ f:dnsPolicy: {}
+ f:restartPolicy: {}
+ f:schedulerName: {}
+ f:securityContext: {}
+ f:terminationGracePeriodSeconds: {}
+ manager: kubectl
+ operation: Update
+ time: "2021-08-16T07:34:48Z"
+ name: dev-my-nginx-grasys01
+ namespace: default
+ selfLink: /apis/apps/v1/namespaces/default/deployments/dev-my-nginx-grasys01
+ uid: 903e78c4-d381-43fb-96c7-b9816d677d6c
+spec:
+ progressDeadlineSeconds: 600
+ replicas: 2
+ revisionHistoryLimit: 10
+ selector:
+ matchLabels:
+ run: my-nginx
+ strategy:
+ rollingUpdate:
+ maxSurge: 25%
+ maxUnavailable: 25%
+ type: RollingUpdate
+ template:
+ metadata:
+ creationTimestamp: null
+ labels:
+ run: my-nginx
+ spec:
+ containers:
+ - image: nginx
+ imagePullPolicy: Always
+ name: my-nginx
+ resources: {}
+ terminationMessagePath: /dev/termination-log
+ terminationMessagePolicy: File
+ dnsPolicy: ClusterFirst
+ restartPolicy: Always
+ schedulerName: default-scheduler
+ securityContext: {}
+ terminationGracePeriodSeconds: 30
+status: {}
diff -u -N /tmp/LIVE-979226958/v1.Service.default.dev-my-nginx-grasys01 /tmp/MERGED-087402581/v1.Service.default.dev-my-nginx-grasys01
--- /tmp/LIVE-979226958/v1.Service.default.dev-my-nginx-grasys01 2021-08-16 07:34:47.927766912 +0000
+++ /tmp/MERGED-087402581/v1.Service.default.dev-my-nginx-grasys01 2021-08-16 07:34:48.081766820 +0000
@@ -0,0 +1,45 @@
+apiVersion: v1
+kind: Service
+metadata:
+ creationTimestamp: "2021-08-16T07:34:48Z"
+ labels:
+ run: my-nginx
+ managedFields:
+ - apiVersion: v1
+ fieldsType: FieldsV1
+ fieldsV1:
+ f:metadata:
+ f:labels:
+ .: {}
+ f:run: {}
+ f:spec:
+ f:ports:
+ .: {}
+ k:{"port":80,"protocol":"TCP"}:
+ .: {}
+ f:port: {}
+ f:protocol: {}
+ f:targetPort: {}
+ f:selector:
+ .: {}
+ f:run: {}
+ f:sessionAffinity: {}
+ f:type: {}
+ manager: kubectl
+ operation: Update
+ time: "2021-08-16T07:34:48Z"
+ name: dev-my-nginx-grasys01
+ namespace: default
+ selfLink: /api/v1/namespaces/default/services/dev-my-nginx-grasys01
+ uid: 28472b6c-6472-4eda-91ed-380a4dea7583
+spec:
+ ports:
+ - port: 80
+ protocol: TCP
+ targetPort: 80
+ selector:
+ run: my-nginx
+ sessionAffinity: None
+ type: ClusterIP
+status:
+ loadBalancer: {}
exit status 1
行頭の”+“から始まる部分が、これからデプロイされる際に新規追加となる差分情報です。 このままデプロイをしてみます。
$ kubectl apply -k .
service/dev-my-nginx-grasys01 created
deployment.apps/dev-my-nginx-grasys01 created
get podしてみると、既存環境はRunningのまま、suffix定義したdev-my-nginx-grasys01-
の名前を含むpodが新たに2つ追加してデプロイされました。
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
dev-my-nginx-54cc7d6865-j2gl9 1/1 Running 0 23m
dev-my-nginx-54cc7d6865-ms9r4 1/1 Running 0 23m
dev-my-nginx-grasys01-54cc7d6865-29k7g 1/1 Running 0 12s
dev-my-nginx-grasys01-54cc7d6865-2dk9v 1/1 Running 0 12s
既存環境2つだけを消す手順ですが まずは追加したkustomization.yamlファイルのnameSuffixをコメントアウトして保存、、、としがちですが、これでは削除されません。(理由は後ほど)
# kustomization.yamlで追加した部分をコメントアウトしても、既存のpodを消せない例:
$ cat kustomization.yaml
bases:
- ../../base
namePrefix: dev-
#nameSuffix: "-grasys01"
$ kubectl diff -k .
$
$ kubectl apply -k .
service/dev-my-nginx unchanged
deployment.apps/dev-my-nginx unchanged
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
dev-my-nginx-54cc7d6865-j2gl9 1/1 Running 0 30m
dev-my-nginx-54cc7d6865-ms9r4 1/1 Running 0 30m
dev-my-nginx-grasys01-54cc7d6865-29k7g 1/1 Running 0 7m28s
dev-my-nginx-grasys01-54cc7d6865-2dk9v 1/1 Running 0 7m28s
kustomization.yamlで追加した内容をコメントアウトしてdiff確認して削除、の流れで、既存のpod環境が削除出来なかった理由はこちらです。 https://github.com/kubernetes-sigs/kustomize/blob/master/examples/transformerconfigs/README.md
Kustomize creates new resources by applying a series of transformations to an original set of resources. Kustomize provides the following default transformers:
- annotations
- images
- labels
- name reference
- namespace
- prefix/suffix
- variable reference
プレフィックス/サフィックストランスフォーマーは、metadata/nameすべてのリソースのフィールドにプレフィックス/サフィックスを追加します。
上記の内容から、この様な流れで情報が読み込まれたこととなります。
- 最初のデプロイで
dev-my-nginx
というpod名のmanifestがデプロイされた - kustomization.yamlに
dev-my-nginx-grasys01
というpod名のmanifestが新規でデプロイされた - kustomization.yamlで追加した内容をコメントアウトしてdiff確認しても、それは 最初にデプロイした
dev-my-nginx
というpod名のmanifestの設定でdiff対象に認識された(このためkubectl diff -k .
しても何も差分は表示されなかった)
今回のケースでは既存環境はdeploymentを削除することで対応できます。
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
dev-my-nginx 2/2 2 2 30m
dev-my-nginx-grasys01 2/2 2 2 7m41s
$ kubectl delete deployment dev-my-nginx
deployment.apps "dev-my-nginx" deleted
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
dev-my-nginx-54cc7d6865-ms9r4 0/1 Terminating 0 36m
dev-my-nginx-grasys01-54cc7d6865-29k7g 1/1 Running 0 13m
dev-my-nginx-grasys01-54cc7d6865-2dk9v 1/1 Running 0 13m
バージョンアップしてkustomize機能をサブコマンドライクに使えて便利に扱える一方で、問題や予期せぬ動作などが起きるすると、対処が難しくなってきます。 どこまでがパラメータの更新でどこまでがkustomize機能となるのかは注意が必要したいところです。
それでは今回はこの辺で。
株式会社grasys(グラシス)は、技術が好きで一緒に夢中になれる仲間を募集しています。
grasysは、大規模・高負荷・高集積・高密度なシステムを多く扱っているITインフラの会社です。Google Cloud (GCP)、Amazon Web Services (AWS)、Microsoft Azureの最先端技術を活用してクラウドインフラやデータ分析基盤など、ITシステムの重要な基盤を設計・構築し、改善を続けながら運用しています。
お客様の課題解決をしながら技術を広げたい方、攻めのインフラ技術を習得したい方、とことん技術を追求したい方にとって素晴らしい環境が、grasysにはあります。
お気軽にご連絡ください。