Deploymentの動作を確認する 3

#はじめに
Deploymentには変更をロールバックする機能があります。今回はロールバックの動作を確認してみます。

#変更履歴の確認
##現状確認
まずは現在の状態を確認します。現在は、[前回](https://qiita.com/dingtianhongjie/items/1129883270e7e0b29459)が終わった後の状態です。

```
$ kubectl get deployments.apps
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
sample-pod4   4/4     4            4           23h
$ kubectl get rs -o wide
NAME                     DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES       SELECTOR
sample-pod4-597898b879   4         4         4       23h   nginx        nginx:1.16   app=nginx-dep,pod-template-hash=597898b879
sample-pod4-65fb458568   0         0         0       19h   nginx        nginx:1.17   app=nginx-dep,pod-template-hash=65fb458568
```

Deployment名「sample-pod4」に、二つのReplicaSetがあります。
現在はImageのバージョンが「1.16」のReplicaSetが使用されています。

##変更履歴の確認
kubectl rolloutコマンドで確認します。

```
$ kubectl rollout history deployment sample-pod4
deployment.apps/sample-pod4
REVISION  CHANGE-CAUSE
2         <none>
3         <none>
```
各リビジョンの詳細も確認します。

```
$ kubectl rollout history deployment sample-pod4 --revision 2
deployment.apps/sample-pod4 with revision #2
Pod Template:
  Labels:       app=nginx-dep
        pod-template-hash=65fb458568
  Containers:
   nginx:
    Image:      nginx:1.17
    Port:       <none>
    Host Port:  <none>
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>

$ kubectl rollout history deployment sample-pod4 --revision 3
deployment.apps/sample-pod4 with revision #3
Pod Template:
  Labels:       app=nginx-dep
        pod-template-hash=597898b879
  Containers:
   nginx:
    Image:      nginx:1.16
    Port:       <none>
    Host Port:  <none>
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>
```
図で表すと以下のような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/b41eaedd-3c9c-d999-685a-64b9cff33639.png)

図ではRevision.1も表していますが、同じReplicaSetに戻すと、過去のRevisionは表示されていませんね。
Revision.1が表示されるか確認してみます。

```
$ kubectl rollout history deployment sample-pod4 --revision 1
error: unable to find the specified revision
```
表示されませんでした。

#ロールバック
Revision.2にロールバックします。

```
$ kubectl rollout undo deployment sample-pod4 --to-revision 2
deployment.apps/sample-pod4 rolled back
$ kubectl get rs -o wide
NAME                     DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES       SELECTOR
sample-pod4-597898b879   0         0         0       23h   nginx        nginx:1.16   app=nginx-dep,pod-template-hash=597898b879
sample-pod4-65fb458568   4         4         4       19h   nginx        nginx:1.17   app=nginx-dep,pod-template-hash=65fb458568
```

1.16のReplicaSetが「0」になって、1.17のReplicaSetが「4」になっています。
なお、引数でRevisionを指定しないと、一つ前のRevisionに戻ります。

histroyを確認してみます。Revision.4が新しく追加されています。

```
$ kubectl rollout history deployment sample-pod4
deployment.apps/sample-pod4
REVISION  CHANGE-CAUSE
3         <none>
4         <none>
```

Revision.2に戻るのではなく、「Revision.2のReplicaSetに新しいRevisionで戻る」が正しいようです。
図にすると以下のようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/fb4b4762-c48e-8c35-25dc-856bd13b2502.png)


##詳細の確認
kubectl describeで詳細を確認してみます。

```
$ kubectl describe rs sample-pod4-65fb458568
Name:           sample-pod4-65fb458568
Namespace:      default
Selector:       app=nginx-dep,pod-template-hash=65fb458568
Labels:         app=nginx-dep
                pod-template-hash=65fb458568
Annotations:    deployment.kubernetes.io/desired-replicas: 4
                deployment.kubernetes.io/max-replicas: 5
                deployment.kubernetes.io/revision: 4
                deployment.kubernetes.io/revision-history: 2
・・・
```
AnnotationのRevisionが「4」になっているのと、「revision-history」という新しいAnnotationが設定されていて、値は「2」になっています。

1.16の方も詳細を確認してみます。

```
$ kubectl describe rs sample-pod4-597898b879
Name:           sample-pod4-597898b879
Namespace:      default
Selector:       app=nginx-dep,pod-template-hash=597898b879
Labels:         app=nginx-dep
                pod-template-hash=597898b879
Annotations:    deployment.kubernetes.io/desired-replicas: 4
                deployment.kubernetes.io/max-replicas: 5
                deployment.kubernetes.io/revision: 3
                deployment.kubernetes.io/revision-history: 1
・・・
```
こちらは、revisionが「3」、revision-historyが「1」になってますね。

ここで気が付くことは、Revision 1->2、2->3は、yamlファイルを更新してkubectl applyで変更しました。
Revision 3->4は、kubectl rolloutで変更しました。
コマンドは異なりますが、動作やAnnotationの設定は同じです。

実際の運用を考えると、kubectl rolloutコマンドを使用するよりも、yamlファイルを更新してkubectl applyコマンドで反映した方が、CI/CDパイプラインで扱いやすいかなと思います。

#recordオプション
マニュアルに以下の記載があります。このrecordオプションを試してみます。

>備考: 実行したコマンドをkubernetes.io/change-causeというアノテーションに記録するために–recordフラグを指定できます。これは将来的な問題の調査のために有効です。例えば、各Deploymentのリビジョンにおいて実行されたコマンドを見るときに便利です。
[kubernetes.io](https://kubernetes.io/ja/docs/concepts/workloads/controllers/deployment/#creating-a-deployment)

##確認
いったん既存のDeploymentを削除して、同じyamlファイルでapplyします。その際、--recordオプションを付与します。

```
$ kubectl apply -f sampleDep.yaml --record
deployment.apps/sample-pod4 created
```
yamlファイルを編集し、再度applyします。

```
$ kubectl apply -f sampleDep.yaml --record
deployment.apps/sample-pod4 configured
$ kubectl get rs -o wide
NAME                     DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES       SELECTOR
sample-pod4-597898b879   0         0         0       2m40s   nginx        nginx:1.16   app=nginx-dep,pod-template-hash=597898b879
sample-pod4-65fb458568   3         3         3       12s     nginx        nginx:1.17   app=nginx-dep,pod-template-hash=65fb458568
```

履歴を確認します。

```
$ kubectl rollout history deployment sample-pod4
deployment.apps/sample-pod4
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=sampleDep.yaml --record=true
2         kubectl apply --filename=sampleDep.yaml --record=true
```

--recordオプションを付与しないでapplyした時の履歴はこちらです。

```
$ kubectl rollout history deployment sample-pod4
deployment.apps/sample-pod4
REVISION  CHANGE-CAUSE
2         <none>
3         <none>
```

CHANGE-CAUSEのカラムに実行したコマンドが表示されて、何をやったかがわかるようになってますね。

リビジョンの詳細も確認してみます。

```
$ kubectl rollout history deployment sample-pod4 --revision 2
deployment.apps/sample-pod4 with revision #2:frowning2:
Pod Template:
  Labels:       app=nginx-dep
        pod-template-hash=65fb458568
  Annotations:  kubernetes.io/change-cause: kubectl apply --filename=sampleDep.yaml --record=true　　<--これが追加されてる。
  Containers:
   nginx:
    Image:      nginx:1.17
    Port:       <none>
    Host Port:  <none>
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>
```
Annotationsの項目が追加されてますね。

--recordオプションを付与すると操作が記録されますのでつけた方がいいですが、ないと困るかと言うとそこまでではない気がします。

#まとめ
Deploymentのロールバックの動作を確認しました。
コンテナはデプロイの機会が多いので、それだけロールバックする機会もあると思います。実際にはデプロイもロールバックも自動化して運用すると思いますが、基本的な動作は理解しておきたいですね。