kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Kubernetes の YAML をカスタマイズする kustomize の基本を学べる Examples「helloWorld」

「Kubernetes 完全ガイド 第2版」「第14章 マニフェストの汎用化を行うオープンソースソフトウェア」を読んでいたら「第1版」では紹介されていなかった(正確には名前は載っていた)kustomize の解説が新しく追加されていた.本書を読みながら概要を理解したため,GitHub に公開されている kustomizeExamples を試しながら理解を深めていく.今回は「helloWorld」を試す.

github.com

前提

今回は Docker Desktop for Mac "Edge" を使って,以下の Kubernetes 環境で試した.kustomize コマンドは brew install kustomize で使えるようにした.なお,現在は kubectl と統合されて kubectl kustomize というコマンドも使えるけど,本書にコラムが載っている通り,バージョンが異なる.

$ kubectl version --short
Client Version: v1.18.6
Server Version: v1.18.6

$ kustomize version --short
{3.8.1  2020-07-16T05:11:04+01:00  }

Examples「helloWorld」とは?

kustomizeExamples「helloWorld」 は,kustomize の第一歩として,メタデータ関連のフィールドを更新したり,Overlay(オーバーレイ)を使って環境ごとにマニフェストを作ったり,リソースにパッチを適用する流れを学ぶ.さっそく試していく!

1. 事前準備

まず,作業ディレクトリを作って,変数 DEMO_HOME に設定しておく.手順書では mktemp コマンドを使っているけど,自由に変えられる.今回は自分用のマニフェストリポジトリにした.そして,もう1つ作っている base ディレクトリは,変換元になる「ベースマニフェスト」を置く場所として使う.

$ DEMO_HOME=~/helloWorld
$ BASE=${DEMO_HOME}/base
$ mkdir -p ${BASE}

次に GitHub に公開されているマニフェストを base ディレクトリにダウンロードする.tree コマンドの結果を見ればわかる通り,ConfigMap / Deployment / Service リソースのマニフェストをダウンロードする.もう1個は kustomize の設定ファイルとして kustomization.yaml もダウンロードする.kustomization.yaml に関しては後述する.

$ curl -s -o "${BASE}/#1.yaml" "https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/examples/helloWorld\
/{configMap,deployment,kustomization,service}.yaml"

$ tree ${DEMO_HOME}
~/helloWorld
└── base
    ├── configMap.yaml
    ├── deployment.yaml
    ├── kustomization.yaml
    └── service.yaml

2. kustomize build を実行する

ダウンロードした base/service.yaml の一部を以下に載せておく.base ディレクトリに置いてあるマニフェストを直接適用するのではなく,kustomize でビルドをするため,あくまで「ベースマニフェスト」になる.

kind: Service
apiVersion: v1
metadata:
  name: the-service
spec:
  selector:
    deployment: hello
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 8666
    targetPort: 8080

次に base/kustomization.yaml を確認する.構文として commonLabelsresources の概要を以下に載せておく.簡単に言えば「3種類のマニフェストに labelsselector を追加する」と言える.

  • commonLabels : ベースマニフェストに labelsselector を追加する
  • resources : kustomize build を実行するときに含めるリソースファイルのリストを指定する
commonLabels:
  app: hello

resources:
- deployment.yaml
- service.yaml
- configMap.yaml

さっそく kustomize build を実行すると,ビルドしたマニフェストが標準出力に表示される.今回は Service リソースを抜粋した.base/service.yaml と比較すると,新しく metadata.labels.appspec.selector.app が追加されている.

$ kustomize build ${BASE}

(中略)

apiVersion: v1
kind: Service
metadata:
  labels:
    app: hello
  name: the-service
spec:
  ports:
  - port: 8666
    protocol: TCP
    targetPort: 8080
  selector:
    app: hello
    deployment: hello
  type: LoadBalancer

(中略)

3. Overlay(オーバーレイ)を追加する

さらに kustomize の良さを学んでいくため,次はリソースにパッチを適用する「Overlay(オーバーレイ)」を試す.まず,overlays ディレクトリを作り,さらに overlays/staging ディレクトリと overlays/production ディレクトリを作っておく.

$ OVERLAYS=${DEMO_HOME}/overlays
$ mkdir -p ${OVERLAYS}/staging
$ mkdir -p ${OVERLAYS}/production

base ディレクトリと overlays ディレクトリの関係はザッと以下のようになる.このように構成することにより,共通的なマニフェストを base ディレクトリに置きつつ,環境ごとに異なる設定を overlays ディレクトリに置くことができる.kustomize 便利!

f:id:kakku22:20200817144209p:plain

次に overlays ディレクトリに置く「計4ファイル」を紹介する.

overlays/staging/kustomization.yaml

まず,staging 環境のための overlays/staging/kustomization.yaml を作る.新しく出てくる構文を紹介する.

  • namePrefix : リソース名の命名規則としてプレフィックスを追加する
  • commonAnnotations : ベースマニフェストに annotations を追加する
  • bases : resources と同じ(現在 bases は deprecated になっている)
  • patchesStrategicMerge : ベースマニフェストに適用する「パッチマニフェスト」のリストを指定する

よって,staging 環境ではリソース名に staging- プレフィックスを付けたり,labelsselectorannotations を追加する.

namePrefix: staging-
commonLabels:
  variant: staging
  org: acmeCorporation
commonAnnotations:
  note: Hello, I am staging!
bases:
- ../../base
patchesStrategicMerge:
- map.yaml

overlays/staging/map.yaml

次に patchesStrategicMerge に指定していた overlays/staging/map.yaml を作る.これは「パッチマニフェスト」として使う ConfigMap リソースのマニフェストとなり,altGreetingenableRisky の設定値を登録している.なお,kustomizeConfigMap を組み合わせた configMapGenerator 構文に関しては次回の記事に載せる予定!

apiVersion: v1
kind: ConfigMap
metadata:
  name: the-map
data:
  altGreeting: "Have a pineapple!"
  enableRisky: "true"

overlays/production/kustomization.yaml

staging 環境と同様に production 環境のための overlays/production/kustomization.yaml も作る.production 環境ではリソース名に production- プレフィックスを付ける.なお,今回の例では ConfigMap のパッチは適用せず,Deployment のパッチを適用する.

namePrefix: production-
commonLabels:
  variant: production
  org: acmeCorporation
commonAnnotations:
  note: Hello, I am production!
bases:
- ../../base
patchesStrategicMerge:
- deployment.yaml

overlays/production/deployment.yaml

最後に overlays/production/deployment.yaml を作る.一般的に production 環境は staging 環境よりも Pod を多く起動するため,以下のマニフェストでは Deployment リソースの replicas10 に更新している.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: the-deployment
spec:
  replicas: 10

最終的な構成を tree コマンドで確認すると,以下のようになる.

$ tree ${DEMO_HOME}
~/helloWorld
├── base
│   ├── configMap.yaml
│   ├── deployment.yaml
│   ├── kustomization.yaml
│   └── service.yaml
└── overlays
    ├── production
    │   ├── deployment.yaml
    │   └── kustomization.yaml
    └── staging
        ├── kustomization.yaml
        └── map.yaml

4. 環境ごとにマニフェストを適用する

Overlay の設定もしたため,最後にまた kustomize build コマンドを使って staging 環境と production 環境のマニフェストを確認する.今回はマニフェストを kubectl apply -f - にパイプすることにより,直接適用もする.

# staging
$ kustomize build ${OVERLAYS}/staging

$ kustomize build $OVERLAYS/staging | kubectl apply -f -
configmap/staging-the-map created
service/staging-the-service created
deployment.apps/staging-the-deployment created

# production
$ kustomize build ${OVERLAYS}/production

$ kustomize build $OVERLAYS/production | kubectl apply -f -
configmap/production-the-map created
service/production-the-service created
deployment.apps/production-the-deployment created

✅ プレフィックスを確認する

例えば ConfigMap を確認すると,リソース名に staging-production- が追加されている!

$ kubectl get configmaps
NAME                 DATA   AGE
production-the-map   2      5s
staging-the-map      2      20s

✅ アノテーションを確認する

例えば Pod を確認すると,アノテーションが追加されている!

$ kubectl describe pods staging-the-deployment-6cd65cfc7f-2lcts | grep Annotations
Annotations:  note: Hello, I am staging!

$ kubectl describe pods production-the-deployment-bb7fd8b65-29b52 | grep Annotations
Annotations:  note: Hello, I am production!

✅ ConfigMap のパッチを確認する

kubectl describe configmapsConfigMap の値を確認する.

$ kubectl describe configmaps staging-the-map
Name:         staging-the-map
Namespace:    default
Labels:       app=hello
              org=acmeCorporation
              variant=staging
Annotations:  note: Hello, I am staging!

Data
====
altGreeting:
----
Have a pineapple!
enableRisky:
----
true
Events:  <none>

altGreetingenableRisky の値を base/configMap.yaml と比較すると,staging 環境では値を書き換えられている!

Key base staging production
altGreeting Good Morning! Have a pineapple! Good Morning!
enableRisky false true false

✅ Deployment のレプリカ数を確認する

kubectl describe deploymentsDeployment のレプリカ数を確認する.production 環境ではレプリカ数を更新できている!

$ kubectl describe deployments | egrep 'Name:|Replicas:'
Name:                   production-the-deployment
Replicas:               10 desired | 10 updated | 10 total | 10 available | 0 unavailable
Name:                   staging-the-deployment
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable

5. リソースを削除する

手順には入っていなかったけど,試したらリソースを削除しておく.

$ kustomize build ${OVERLAYS}/staging | kubectl delete -f -
configmap "staging-the-map" deleted
service "staging-the-service" deleted
deployment.apps "staging-the-deployment" deleted

$ kustomize build ${OVERLAYS}/production | kubectl delete -f -
configmap "production-the-map" deleted
service "production-the-service" deleted
deployment.apps "production-the-deployment" deleted

まとめ

「Kubernetes 完全ガイド 第2版」で解説が新しく追加されていた kustomize を試した.GitHub に公開されている Examples「helloWorld」kustomize の基本を学べてオススメ!なお,今回は kustomization.yaml の構文として以下を使った.詳しくはドキュメントを見てみてもらえればと!

  • bases
  • commonAnnotations
  • commonLabels
  • namePrefix
  • patchesStrategicMerge
  • resources

kubernetes-sigs.github.io