kubernetesのkustomizeに入門する

## はじめに

k8sにはkustomize（カスタマイズ）というツールがある。

k8sでyamlを量産していると運用においてつらいことがいくつか出てくる。

- yamlをたくさん書くのがつらい。共通化したい。
- 環境が複数ある時のyaml管理がつらい。ベースは同じだけど環境ごとに微妙に変数や設定を変更したい。

<img width="757" alt="スクリーンショット 2020-03-12 0.44.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164543/177391e3-5e57-98ce-07ee-bdee981a3490.png">


これらの問題を緩和するツールの一つがkustomizeである。

## 概要

basesとoverlaysを区別して記述することで上記の課題を解決していく。

- 各環境で共通設定となる記述をする → bases
- 個環境で差分となる設定を記述する → overlays

下図でいうとそのままapplyすれば本番環境になるし、ステージ環境用にapplyすればステージ環境用なる。みたいにする。


<img width="807" alt="スクリーンショット 2020-03-12 0.44.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164543/ad47cfb8-99ab-0cdb-1cf4-798af59e9dda.png">


もちろん何をベースとしたいかは開発者次第なので上図の限りではない。
baseで設定してない項目をoverlaysに書いてもいいし、baseで書いたが上書きしたい項目をoverlaysに書いてもいい。
いずれもkustomization.yamlというマニフェストファイルを軸に操作を行っていく。

例えば以下のようなフォルダ構成で進めていく。

```bash

kustomize-test
├── bases
│   ├── deployment.yaml
│   └── kustomization.yaml
└── overlays
    ├── staging
    │   ├── kustomization.yaml
    │   └── replica_count.yaml
    └── development
        ├── kustomization.yaml
        └── replica_count.yaml
```

まずはkustomizeのインストール。(Macの場合)

```
$ brew install kustomize
```

使い方はhelpコマンドで出てくる。
また、例えばbuildコマンドがわからない時は `kustomize build --help`と打つ。

```
$ kustomize help

Manages declarative configuration of Kubernetes.
See https://sigs.k8s.io/kustomize

Usage:
  kustomize [command]

Available Commands:
  build              Print configuration per contents of kustomization.yaml
  create             Create a new kustomization in the current directory
  edit               Edits a kustomization file
  help               Help about any command
  install-completion Install shell completion.
  version            Prints the kustomize version

Flags:
  -h, --help   help for kustomize

Additional help topics:
  kustomize resources          [Alpha] To enable set KUSTOMIZE_ENABLE_ALPHA_COMMANDS=true

Use "kustomize [command] --help" for more information about a command.
```


## kustomize使い方

basesを使えばそのまま本番環境になり、
overlaysを使い分けることでステージ環境・開発環境になるようにkustomizeしていく。

まずベースとなるマニフェストファイルを作成する。
この中ではdeploymentを定義するマニフェストファイルをresourcesとして記述している。

```bases/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
commonLabels:
  app: test
kind: Kustomization
resources:
- deployment.yaml
```

次にkustomization.yamlで指定した、deployment.yamlを作成する。

```bases/deployment.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Deployment
metadata:
  name: deployment-test
spec:
  template:
    metadata:
      labels:
        app: deployment-test
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
```

ここまでの途中結果を見てみる。

```bash

$ cd /kustomize-test
$ kustomize build ./base

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  labels:
    app: test
  name: deployment-test
spec:
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - image: nginx:alpine
        name: nginx
```

ちなみにbuildはkustomization.yamlの中身を標準出力したものである。
kustomization.yamlではdeployment.yamlをresourcesとして指定しており、その組み合わせの内容が出力される。

またbuildの対象となるのは、ファイルではなくディレクトリである。
もっというとkustomization.yamlがあるディレクトリである。

次に差分となるoverlaysを作成する。
はじめに/sataging/から。

```overlays/staging/kustomization.yaml
bases:
  - ../../base

patches:
- deployment.yaml
```

basesは先程作成した、basesディレクトリの場所。
patchesでは、そのディレクトリ（今回は/staging）の差分となるマニフェストファイルを記述する。


```overlays/staging/deployment.yaml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: deployment-test
spec:
  replicas: 3
  ports:
  - containerPort: 1010
```

apiVersion、kind、metadata.nameは、basesで設定したものと同じにする必要がある。

productionをbuildをしてみる。

```
$ kustomize build ./overlays/staging/
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Deployment
metadata:
  labels:
    app: test
  name: deployment-test
spec:
  ports:
  - containerPort: 1010           #NEW!
  replicas: 3                     #NEW!
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - image: nginx:alpine
        name: nginx
```


overlays/staging/deployment.yamlの設定が読み込まれ、反映されている。

次に/development/のマニフェストファイルを編集。
stagingのもの~~を使いまわし~~と同じ。

```overlays/development/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
commonLabels:
  app: test
kind: Kustomization
resources:
- deployment.yaml
```
developmentのdeployment.yamlを作成。

```overlays/development/deployment.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: deployment-test
spec:
  replicas: 1
  ports:
  - containerPort: 2020
```

buildしてみる。

```bash

$ kustomize build ./overlays/development/

kind: Deployment
metadata:
  labels:
    app: test
  name: deployment-test
spec:
  ports:
  - containerPort: 2020           #NEW!
  replicas: 1                     #NEW!
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
```


ベースは受け継ぎつつ、stagingとdevelopmentで差分をきちんと生んでくれている。

kustomizeの内容をクラスターに反映させたい時はapplyを叩く。

```bash

$ cd /kustomize-test

$ kustomize build ./base | kubectl apply -f -
deployment.apps/deployment-test created
```

KustomizeもTerraformと同様宗教があるようなので、勉強を続けつつ宗教を広げていこう。