Deploymentの動作を確認する 1

#はじめに
これまで、Pod、ReplicaSetの動作を確認してきましたので、今回はDeploymentの動作を確認します。
Deploymentは、ReplicaSet、Podの上位概念で、以下のような関係になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/9a59d19f-5c64-8863-36a8-706224c5991f.png)

#Deploymentの作成
##yamlファイルの作成とapply
以下のyamlファイルを作成しました。

```sampleDep.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-pod4
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-dep
  template:
    metadata:
      labels:
        app: nginx-dep
    spec:
      containers:
        - name: nginx
          image: nginx:1.16
```
applyします。

```
$ kubectl apply -f sampleDep.yaml
deployment.apps/sample-pod4 created
```

##確認
作成したDeploymentを確認します。

```
$ kubectl get deployment
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
sample-pod4   3/3     3            3           30s
$ kubectl get rs
NAME                     DESIRED   CURRENT   READY   AGE
sample-pod4-597898b879   3         3         3       40s
$ kubectl get pod
NAME                           READY   STATUS    RESTARTS   AGE
sample-pod4-597898b879-29zwd   1/1     Running   0          49s
sample-pod4-597898b879-phfrf   1/1     Running   0          49s
sample-pod4-597898b879-rwtd5   1/1     Running   0          49s
```
DeploymentがReplicaSetを作成して、ReplicaSetがPodを作成しているのがわかりますね。
・ReplicaSet名は、「[Deploymet名]＋任意の文字列」
・Pod名は、「[ReplicaSet名]＋任意の文字列」
になっています。

kubectl describeコマンドで詳細も確認しておきます。

```
$ kubectl describe rs sample-pod4-597898b879
・・・
Annotations:    deployment.kubernetes.io/desired-replicas: 3
                deployment.kubernetes.io/max-replicas: 4
                deployment.kubernetes.io/revision: 1
・・・
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  115s  replicaset-controller  Created pod: sample-pod4-597898b879-rwtd5
  Normal  SuccessfulCreate  115s  replicaset-controller  Created pod: sample-pod4-597898b879-phfrf
  Normal  SuccessfulCreate  115s  replicaset-controller  Created pod: sample-pod4-597898b879-29zwd
```

#ローリングアップデートとバージョン管理
Deploymentの特徴である、ローリングアップデートとバージョン管理の動作を確認します。

##ローリングアップデート
yamlファイルを編集して、nginxのバージョンを1.16から「1.17」に変更します。
変更したyamlファイルをapplyします。

```
$ kubectl apply -f sampleDep.yaml
deployment.apps/sample-pod4 configured
```
アップデートの状況をkubectl rolloutコマンドで確認します。

```
$ kubectl rollout status deployment sample-pod4
Waiting for deployment "sample-pod4" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample-pod4" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample-pod4" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample-pod4" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "sample-pod4" rollout to finish: 1 old replicas are pending termination...
deployment "sample-pod4" successfully rolled out
```
1.17のレプリカが作成されて、1.16のレプリカが停止していることがわかりますね。

アップデート後の状態を確認します。

```
$ kubectl get deployments sample-pod4
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
sample-pod4   3/3     3            3           6m15s
$ kubectl get rs -o wide
NAME                     DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES       SELECTOR
sample-pod4-597898b879   0         0         0       6m48s   nginx        nginx:1.16   app=nginx-dep,pod-template-hash=597898b879
sample-pod4-65fb458568   3         3         3       59s     nginx        nginx:1.17   app=nginx-dep,pod-template-hash=65fb458568
$ kubectl get pod
NAME                           READY   STATUS    RESTARTS   AGE
sample-pod4-65fb458568-cnqvv   1/1     Running   0          71s
sample-pod4-65fb458568-rfhkj   1/1     Running   0          69s
sample-pod4-65fb458568-vqtj5   1/1     Running   0          73s
```
1.16のReplicaSet（sample-pod4-597898b879）のレプリカ数は「0」で、1.17のReplicaSet（sample-pod4-65fb458568）は「3」になっていて、新しいPodがデプロイされていることが確認できます。

##バージョン管理
kubectl describeコマンドでそれぞれのReplicaSetのバージョンを確認します。

```
$ kubectl describe rs sample-pod4-65fb458568
Name:           sample-pod4-65fb458568
・・・
Annotations:    deployment.kubernetes.io/desired-replicas: 3
                deployment.kubernetes.io/max-replicas: 4
                deployment.kubernetes.io/revision: 2
・・・
  Containers:
   nginx:
    Image:        nginx:1.17
・・・
```
1.17のReplicaSetのRevisionがAnnotationに設定されていて、「2」に上がっていることが確認できます。

1.16の方も確認しておきます。

```
$ kubectl describe rs sample-pod4-597898b879
Name:           sample-pod4-597898b879
・・・
Annotations:    deployment.kubernetes.io/desired-replicas: 3
                deployment.kubernetes.io/max-replicas: 4
                deployment.kubernetes.io/revision: 1
・・・
  Containers:
   nginx:
    Image:        nginx:1.16
・・・
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  10m    replicaset-controller  Created pod: sample-pod4-597898b879-rwtd5
  Normal  SuccessfulCreate  10m    replicaset-controller  Created pod: sample-pod4-597898b879-phfrf
  Normal  SuccessfulCreate  10m    replicaset-controller  Created pod: sample-pod4-597898b879-29zwd
  Normal  SuccessfulDelete  4m59s  replicaset-controller  Deleted pod: sample-pod4-597898b879-rwtd5
  Normal  SuccessfulDelete  4m57s  replicaset-controller  Deleted pod: sample-pod4-597898b879-phfrf
  Normal  SuccessfulDelete  4m55s  replicaset-controller  Deleted pod: sample-pod4-597898b879-29zwd
```
こちらの方はRevisionは「1」のままです。また、Podの作成/削除の履歴も確認できます。

#（おまけ）ReplicaSetのローリングアップデート
ふと、ReplicaSetでもyamlファイルのバージョン変えれば、ローリングアップデートできるんじゃ？？と思ってやってみました。

作成したyamlファイルはこちら。

```sampleRS.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: sample-pod5
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-dep
  template:
    metadata:
      labels:
        app: nginx-dep
    spec:
      containers:
        - name: nginx
          image: nginx:1.16
```
applyします。

```
$ kubectl apply -f sampleRS.yaml
replicaset.apps/sample-pod5 created
```
確認します。

```
$ kubectl get rs -o wide
NAME          DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES       SELECTOR
sample-pod5   3         3         3       18s   nginx        nginx:1.16   app=nginx-dep
$ kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
sample-pod5-2t5tx   1/1     Running   0          4s
sample-pod5-6xd6b   1/1     Running   0          4s
sample-pod5-xhvk2   1/1     Running   0          4s
$ kubectl describe rs
Name:         sample-pod5
・・・
  Containers:
   nginx:
    Image:        nginx:1.16
・・・
```
念のためコンテナにログインして、バージョンを確認します。

```
$ kubectl exec -it sample-pod5-xhvk2 /bin/bash
root@sample-pod5-xhvk2:/# nginx -v
nginx version: nginx/1.16.1
root@sample-pod5-xhvk2:/# exit
exit
```

##ReplicaSetでローリングアップデートできるか確認
yamlファイルのバージョンを書き換えてapplyします。

```
$ kubectl apply -f sampleRS.yaml
replicaset.apps/sample-pod5 configured
```
確認します。

```
$ kubectl get rs -o wide
NAME          DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES       SELECTOR
sample-pod5   3         3         3       4m11s   nginx        nginx:1.17   app=nginx-dep
```
イメージのバージョンは上がってますね。

Podを確認します。

```
$ kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
sample-pod5-2t5tx   1/1     Running   0          4m15s
sample-pod5-6xd6b   1/1     Running   0          4m15s
sample-pod5-xhvk2   1/1     Running   0          4m15s
```
Podは変わってないです。

kubectl describeでも確認します。

```
$ kubectl describe rs
Name:         sample-pod5
・・・
  Containers:
   nginx:
    Image:        nginx:1.17
・・・
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  4m30s  replicaset-controller  Created pod: sample-pod5-xhvk2
  Normal  SuccessfulCreate  4m30s  replicaset-controller  Created pod: sample-pod5-2t5tx
  Normal  SuccessfulCreate  4m30s  replicaset-controller  Created pod: sample-pod5-6xd6b
```
こちらもイメージのバージョンは変わってるけど、Podはそのままですね。

ログインして確認します。

```
$ kubectl exec -it sample-pod5-xhvk2 /bin/bash
root@sample-pod5-xhvk2:/# nginx -v
nginx version: nginx/1.16.1
root@sample-pod5-xhvk2:/# exit
exit
```

やっぱり1.16のままですね。

#まとめ
Deployment/ReplicaSet/Podの機能を以下にまとめます。

||Deployment|ReplicaSet|Pod|
|:---|:--:|:--:|:--:|
|ローリングアップデート|✓|||
|バージョン管理|✓|||
|セルフヒーリング|✓|✓
|スケーリング|✓|✓
|コンテナ作成|✓|✓|✓


大は小を兼ねるではありませんが、機能的にDeploymentはすべて包含してますので、仮に1Pod/1コンテナしか使わない場合でもDeploymentを使用することが推奨されています。

Deploymentの動作については、もう少し調べてみたいと思います。