Kustomizeによるmanifest管理

# 使用する背景
現在、アプリケーション開発をしていく中で、podに変更を加える際に、`kubectl apply`を使ったりしている方も多いと思います。

そこには、変更対象の間違いや、manifestの選択ミスなど様々なヒューマンエラーの原因が潜んでいます。

そこで、使われるのが`kustomize`です。
これを使うことで、上記のようなことを防ぐ手助けをkubernetesはしてくれています。


# 準備

検証用directoryを作成します。

```
# mkdir kustomize-manifest
```

その下に、`base`と`production`という2つのdirectoryを作成します。

baseの下に以下3つのファイルを作成します。

```nginx-deployment.yml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
```

```nginx-service.yml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: ClusterIP
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 80
      targetPort: 80
  selector:
    app: nginx
```

```kustomization.yml
resources:
- nginx-deployment.yml
- nginx-service.yml
images:
- name: nginx
  newTag: "1.17.0"
```

次に、productionの下に以下２つを作成します。

```production-nginx-service.yml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: LoadBalancer
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 80
      targetPort: 80
```

```kustomization.yml
bases:
- ../base
namespace: "production"
patchesStrategicMerge:
- production-nginx-service.yml
```

# kustomizeコマンド

それでは、`kustomize-manifest`ディレクトリ下に戻り、以下のコマンドを打ってみましょう。

```
# kubectl kustomize base
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ports:
  - name: http-port
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.17.0
        name: nginx
        ports:
        - containerPort: 80
```

deploymentのymlとsvcのymlが合わさったものが表示されたのがわかります。

では、次に以下のコマンドを実施します。

```
# kubectl kustomize production
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: production
spec:
  ports:
  - name: http-port
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: production
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.17.0
        name: nginx
        ports:
        - containerPort: 80
```

合わさったymlが表示されたうえで、svcのtypeが`LoadBalancer`に変化したのがわかります。

これは、productionのkustomize.ymlにて

```
bases:
- ../base
```

として、ベースとなるmanifestを指定してあげて、

```
patchesStrategicMerge:
- production-nginx-service.yml
```

と書くことで、svcに関しては、`production-nginx-service.yml`に変更してあげることができます。
こうしてproduction用にLoadBalancerを設定することができました。

# kustomizeにて作成したものでdeploy

kustomizeで作成されたものは以下のようなコマンドで、deployできます。

```
# kubectl kustomize base | kubectl apply -f -
service/nginx-service created
deployment.apps/nginx-deployment created
```