TL;DR
- GKEのmanifestをkustomizeで管理する際のサンプルです
- 例としてdevとprod環境を分けてプロビジョニングします
概要
kustomizeとは
kustomizeとはKubernetesのマニフェスト(yamlベースのIaC)を管理するために使用されるツールです。
素のmanifestファイルとの相違点として、主に環境毎に設定を変更できる点です。
また、他の管理ツールと比較して直感的な使いやすさとkubectlコマンドに組み込まれていることも強みです。
e.g.
$ kubectl apply -k base/
$ kubectl kustomize base/
Version
- kubectl
- 1.27.4
- GKE-autopilot
- 1.27.3-gke.100
Code
How to
kustomizeで環境差分を表現するサンプルになります。
構築するものはnginxを立ち上げるDeploymentとServiceの2つのみで、kustomizeに重点を置いて書いています。
GKEクラスターの作成と接続
kustomize-exampleという名前のクラスターを東京リージョンに作成します。
$ gcloud container clusters create-auto "kustomize-example" \ --region "asia-east1" \ --release-channel "regular"
作成したクラスターに接続します。
$ gcloud container clusters get-credentials kustomize-example
接続の確認を行います。
$ kubectl get all NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 34.118.224.1 <none> 443/TCP 165m
kustomize
devとprod環境が欲しいため、今回は以下のようなディレクトリ構成で行います。
$ tree -d . ├── base └── overlays ├── development └── production
- baseディレクトリ
- この配下にテンプレートとなるマニフェストファイルを記載します。
- overlaysディレクトリ
- この配下には構築したい環境分ディレクトリを切ります
- その各ディレクトリにbaseディレクトリのテンプレートとの環境差分を定義したマニフェストファイルを記載します。
今回は以下の3つのObjectの作成と環境差分の定義をします。 1. namespace 2. deployment 3. service
baseディレクトリとマニフェストの作成
baseディレクトリにはテンプレートとなるファイルを作成します。
base/ ├── deployment.yaml ├── kustomization.yaml └── service.yaml
kustomizeでメインとなるマニフェストファイルは kustomization.yaml
です。
このファイルを起点に他の2つのファイルが呼び出されます。
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - deployment.yaml - service.yaml
depoyment.yaml
と service.yaml
はk8sのマニフェストをそのまま書く形になります。
サンプルコードはnginxのバージョン1.25のPodを3つ建て、serviceと紐付けるシンプルなものです。
定義されるマニフェストを一括で閲覧します。
kubectlコマンドに組み込まれている kubectl kustomize
で生成することが可能です。
$ kubectl kustomize base/ apiVersion: v1 kind: Service metadata: labels: app: nginx name: nginx-service spec: ports: - port: 80 targetPort: 80 selector: app: nginx --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx:1.25 name: nginx ports: - containerPort: 80 resources: limits: cpu: 200m memory: 512Mi requests: cpu: 200m memory: 512Mi
overlaysディレクトリでマニフェストの書き換え
まずはdev環境で使用するために、 overlays/development/
ディレクトリで差分の定義をします。
今回の例ではdev環境ではdevelopmentというnamespaceを作成し、 そのnamespace上にnginx:1.24のPodを1つ立ち上げる よう変更します。
ディレクトリ構成は以下です。
$ tree overlays/development/ overlays/development/ ├── deployment.yaml ├── kustomization.yaml └── namespace.yaml
まずは overlays/development/kustomization.yaml
の定義を行います。
プロビジョニングする際は各ディレクトリの kustomization.yaml
が起点になるため、このファイルがdev環境の起点のファイルになります。各定義の説明はコメントに記載します。
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization # 作成する全てのObjectにlabelを付与することも可能です。 labels: - includeSelectors: true pairs: env: development # developmentのnamespace内にObjectを配置します。 namespace: development # MEMO: 重要な点です。 # 使用するマニフェストファイルを選択します。ここでbaseディレクトリのテンプレートを元に、同一ディレクトリのnamespace.yamlを統合したものを1つのマニフェストにまとめます。 resources: - ../../base - namespace.yaml # resourcesで作成されたマニフェストに変更を加えます。 # 今回はPodを3から1つに変更するために使用します。 patches: - path: deployment.yaml target: kind: Deployment # 指定したイメージnameのuriを書き換えます。 # 今回は1.25から1.24に変更します。 images: - name: nginx newName: nginx newTag: "1.24"
patches
で指定した deployment.yaml
です。Pod(replicas)を3つから1つに変更するための定義です。
apiVersion: apps/v1 kind: Deployment metadata: # このnameのDeploymentを対象にします name: nginx-deployment # 変更点を定義します spec: replicas: 1
この定義でビルドされるマニフェストを kubectl kustomize overlays/development.yaml
で閲覧します。
# $ kubectl kustomize overlays/development/ apiVersion: v1 kind: Namespace metadata: labels: env: development name: development --- apiVersion: v1 kind: Service metadata: labels: app: nginx env: development name: nginx-service namespace: development spec: ports: - port: 80 targetPort: 80 selector: app: nginx env: development --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx env: development name: nginx-deployment namespace: development spec: replicas: 1 selector: matchLabels: app: nginx env: development template: metadata: labels: app: nginx env: development spec: containers: - image: nginx:1.24 name: nginx ports: - containerPort: 80 resources: limits: cpu: 200m memory: 512Mi requests: cpu: 200m memory: 512Mi
namespaceが development
の作成とそこへの配置、labelsに env: development
の追加、Deploymentのreplicasが3つから1つ・imageが1.25から1.24に変更されたことがわかります。
プロビジョニング
baseディレクトリの確認
はじめに、テンプレートとなるbaseディレクトリをnamespace default
にプロビジョニングを試します。
こちらも kubectl kustomize <PATH>
同様に kubectl apply -k <PATH>
コマンドで適用ができます。
baseディレクトリを起点にapplyを行います。
$ kubectl apply -k base/
default namespaceにDeployment・Service・3台のPodが作成されていることを確認します。
$ kubectl get all -n default NAME READY STATUS RESTARTS AGE pod/nginx-deployment-6487695f74-pngkc 1/1 Running 0 23s pod/nginx-deployment-6487695f74-qjbcv 1/1 Running 0 23s pod/nginx-deployment-6487695f74-zz6mf 1/1 Running 0 23s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 34.118.224.1 <none> 443/TCP 3h29m service/nginx-service ClusterIP 34.118.238.247 <none> 80/TCP 23s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 3/3 3 3 23s NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-deployment-6487695f74 3 3 3 24s
nginxのバージョンが1.25であることを確認します。
$ kubectl get deployment -o yaml | grep "image: nginx" - image: nginx:1.25
baseディレクトリのプロビジョニングが成功しました。
起動確認のためにServiceにポートフォワードを行い、nginxの起動とバージョンを確認します。
$ kubectl port-forward service/nginx-service 8080:80 Forwarding from 127.0.0.1:8080 -> 80 Forwarding from [::1]:8080 -> 80
$ curl -I localhost:8080 HTTP/1.1 200 OK Server: nginx/1.25.3 Date: Tue, 14 Nov 2023 12:25:35 GMT Content-Type: text/html Content-Length: 615 Last-Modified: Tue, 24 Oct 2023 13:46:47 GMT Connection: keep-alive ETag: "6537cac7-267" Accept-Ranges: bytes
200 OK
でServerヘッダーに nginx/1.25.3
が入っていることを確認できました。
overlaysでそれぞれの環境をプロビジョニング
では差分があるdev環境のプロビジョニングを行ってみます。
改めて差分のおさらいです。
1. namespaceがdevelopmentを使用していること
2. nginxのreplicasが3台から1台になること
3. nginxのバージョンが1.25から1.24になること
baseと同様に、使用するパスを指定してプロビジョニングを行います。
apply
$ kubectl apply -k overlays/development
development
namespaceにDeployment・Service・1台のPodが作成されていることを確認します。
$ kubectl get all -n development NAME READY STATUS RESTARTS AGE pod/nginx-deployment-74bfdb9795-qvxzr 1/1 Running 0 131m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/nginx-service ClusterIP 34.118.229.212 <none> 80/TCP 133m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 1/1 1 1 133m NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-deployment-74bfdb9795 1 1 1 133m
nginxのバージョンが1.24であることを確認します。
$ kubectl get deployment -o yaml -n development | grep "image: nginx" - image: nginx:1.24
プロビジョニングが成功しました。
baseディレクトリと同様に、ポートフォワードで疎通確認を行います。
$ kubectl port-forward service/nginx-service 8080:80 -n development Forwarding from 127.0.0.1:8080 -> 80 Forwarding from [::1]:8080 -> 80
$ curl -I localhost:8080 HTTP/1.1 200 OK Server: nginx/1.24.0 Date: Tue, 14 Nov 2023 12:35:11 GMT Content-Type: text/html Content-Length: 615 Last-Modified: Tue, 11 Apr 2023 01:45:34 GMT Connection: keep-alive ETag: "6434bbbe-267" Accept-Ranges: bytes
200 OK
でServerヘッダーに nginx/1.24.0
が入っていることを確認できました。
お片付け
kustomizeコマンドで作成したものは kubectl get -k <PATH>
で閲覧することも可能です。
$ kubectl get -k overlays/development/ NAME STATUS AGE namespace/development Active 138m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/nginx-service ClusterIP 34.118.229.212 <none> 80/TCP 138m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx-deployment 1/1 1 1 138m
同様に kubectl delete -k <PATH>
で削除することも可能です。
$ kubectl delete -k overlays/development/ namespace "development" deleted service "nginx-service" deleted deployment.apps "nginx-deployment" deleted $ kubectl get all -n development No resources found in development namespace.
今回作成したクラスターごと削除してお片付け完了です。
$ gcloud container clusters delete "kustomize-example" The following clusters will be deleted. - [kustomize-example] in [asia-northeast1] Do you want to continue (Y/n)? Y Deleting cluster kustomize-example...
所感
個人的にkustomizeを使用することで環境差分を直感的に定義できることが魅力だと感じており、私自身好きなツールの1つです。
また、環境管理を行うに際には素のマニフェストファイルでの管理から乗り換えやすい点、kubectlコマンドがデフォルトで対応するようになった点も採用しやすいポイントです。
ただ、kustomize自体はlatestなのですがapiVersion自体はまだbetaです ( apiVersion: kustomize.config.k8s.io/v1beta1
)。
最近であれば kustomization.yaml
で使用可能だった patchesJson6902:
commonLabels:
等がdeprecatedになっていたり改善が続いています。
他のライブラリやツールでも同様ですが、kustomizeを使用する際はしっかりとアップデートを追う必要があります。
ちなみにkustomizeには kustomize edit fix
という優秀なコマンドがあり、簡単な修正であればこのコマンドを使うだけで自動で修正してくれる点も優秀です。