kubectl に統合された Kustomize をさわってみた

# はじめに

Kubernetes 1.14 がリリースされました。

[kubernetes-1-14-release-announcement](https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement/) によると、kubectl に統合予定とされていた Kustomize が kubectl に統合されたとのことです。

早速さわってみました。

# 検証環境
- macOS High Sierra 10.13.3
- kubectl v1.14.0
- kubernetes v1.11.8-eks-7c34c0

# 検証

kubectl に統合された Kustomize には、

* `kubectl kustomize dir/` のようにして、カスタマイズしたマニフェストを標準出力に出す
* `kubectl apply -k dir/` のようにして、カスタマイズしたマニフェストを即座に適用する

といった使い方があるようです。

それぞれ試しました。

## 用意したファイル

以下のような構成で 4 ファイル用意しました。

```
$ tree
.
├── base
│   ├── deployment.yaml
│   ├── kustomization.yaml
│   └── service.yaml
└── kustomization.yaml
```

それぞれ内容は以下の通りです。

```kustomization.yaml
bases:
- base

nameSuffix: -sample
commonLabels:
  app: front-sample

imageTags:
  - name: nginx
    newTag: 1.15.9
```

```base/deployment.yaml
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: front
spec:
  replicas: 1
  selector:
    matchLabels:
      app: front
  template:
    metadata:
      labels:
        app: front
    spec:
      containers:
      - name: main
        image: nginx:alpine
        ports:
        - containerPort: 80
```

```base/service.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: front
spec:
  selector:
    app: front
  ports:
    - port: 80
      targetPort: 80
  type: NodePort
```

```base/kustomization.yaml
resources:
- deployment.yaml
- service.yaml
```

## 統合前の Kustomize を実行する

kubectl に統合された Kustomize を使う前に、統合されていない kustomize コマンドを試してみます。

上記のディレクトリで `kustomize build` を実行すると以下のようになります。

```console
apiVersion: v1
kind: Service
metadata:
  labels:
    app: front-sample
  name: front-sample
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: front-sample
  type: NodePort
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: front-sample
  name: front-sample
spec:
  replicas: 1
  selector:
    matchLabels:
      app: front-sample
  template:
    metadata:
      labels:
        app: front-sample
    spec:
      containers:
      - image: nginx:1.15.9
        name: main
        ports:
        - containerPort: 80
```

これを実行したい場合、パイプで `kubectl apply  -f -` に繋げることになります。

```console
$ kustomize build | kubectl apply -f -
service/front-sample created
deployment.extensions/front-sample created
```

リソースが無事作成されました。

```console
$ kubectl get deployment
NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
front-sample   1         1         1            1           57s
$ kubectl get service
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
front-sample   NodePort    172.20.154.74   <none>        80:32215/TCP   1m
kubernetes     ClusterIP   172.20.0.1      <none>        443/TCP        25m
```

以後の検証のため、一度リソースを削除しておきます。

```console
$ kustomize build . | kubectl delete -f -
service "front-sample" deleted
deployment.extensions "front-sample" deleted
```

## kubectl kustomize dir/

さて、ここから kubectl に統合された Kustomize を実行してみます。

```console
$ kubectl kustomize .
apiVersion: v1
kind: Service
metadata:
  labels:
    app: front-sample
  name: front-sample
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: front-sample
  type: NodePort
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: front-sample
  name: front-sample
spec:
  replicas: 1
  selector:
    matchLabels:
      app: front-sample
  template:
    metadata:
      labels:
        app: front-sample
    spec:
      containers:
      - image: nginx:1.15.9
        name: main
        ports:
        - containerPort: 80
```

無事マニフェストが出力されました。

念のため diff を確認しても、`kustomize build` を実行した場合と全く差はありませんでした。

```
$ diff <(kustomize build .) <(./kubectl kustomize .)
```

## kubectl apply -k dir/

kubectl に統合された Kustomize を使う場合、先ほどのように標準出力を介すことなく apply まで実行できるようです。

試してみると ...

```console
$ ./kubectl apply -k .
service/front-sample created
deployment.extensions/front-sample created
$ kubectl get deployment
NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
front-sample   1         1         1            1           6s
$ kubectl get service
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
front-sample   NodePort    172.20.139.202   <none>        80:32512/TCP   10s
kubernetes     ClusterIP   172.20.0.1       <none>        443/TCP        27m
```

無事リソースが作成されました。

当たり前ですが、Kubernetes クラスタ側のバージョンが 1.14 でなくても問題ありませんでした。

# おわりに

Kustomize をインストールする手間が減っただけではありますが、個人的には地味にうれしいです。

余談ですが、[kubectl のドキュメント](https://kubectl.docs.kubernetes.io/pages/app_composition_and_deployment/structure_directories.html) には Kustomize を使う際のディレクトリ構成の例も記載されています。結構参考になりそうです。