Rolling UpdateとBlue/Green Deploymentの違いを整理する

# はじめに
RollingUpdateとBlue/Green Deployment(以下BGデプロイ)の違いが脳内でごっちゃになってきたので、整理するためのメモです。
説明のために、以下構成のWEBサーバーのデプロイを考えます。
![スクリーンショット 2024-06-05 7.36.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159675/3ae73c9f-0e77-8801-9e8b-93020716e269.png)

LBがあって、サーバーが3台で冗長化されているシンプルな構成です。

# Rolling Update
Rolling　Updateは旧モジュールを残したまま新モジュールを少しずつ起動していき、新旧モジュールの比率を徐々に新に寄せていくデプロイ方式です。

＜メリット＞
- 無停止でデプロイ可能
- リソースコストが低い
    - 後述するBGデプロイは環境を丸ごと用意しないといけない

＜デメリット＞
- 新旧モジュールが一時的に共存することになる
- 新旧モジュールが共存してる状態でロールバックが必要になった際、煩雑な手順が発生しうる

## やってみる
実際にKubernetesでRolling Updateを実施して、モジュールの入れ替わる様子を見ていきましょう。

まず以下のyamlを用意します。
https://github.com/tttol/bbf-kubernetes/blob/main/chapter-06/deployment.yaml
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.24.0
        ports:
        - containerPort: 80
```

nginxサーバーを3台立てるDeploymentです。
CLIから以下を実行してnginxサーバー×3を起動します。
```bash
$ kubectl apply -f deployment.yaml    
deployment.apps/nginx-deployment configured
```

`kubectl get pod`で起動確認します。
```bash
$ kubectl get pod                 
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-696bfc48dd-csgxx   1/1     Running   0          58s
nginx-deployment-696bfc48dd-shsg4   1/1     Running   0          58s
nginx-deployment-696bfc48dd-wwh8l   1/1     Running   0          58s
```

次にnginxのバージョンを上げて再度デプロイします。
```diff
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
-        image: nginx:1.24.0
+        image: nginx:1.25.3
        ports:
        - containerPort: 80
```

デプロイの前に、別ターミナルで`kubectl get pod --watch`を実行しておき、Podの入れ替わり状況をリアルタイムでウォッチします。
```
$ kubectl get pod --watch
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-696bfc48dd-csgxx   1/1     Running   0          58s
nginx-deployment-696bfc48dd-shsg4   1/1     Running   0          58s
nginx-deployment-696bfc48dd-wwh8l   1/1     Running   0          58s
```

nginx:1.25.3をデプロイします。
```bash
$ kubectl apply -f deployment.yaml    
deployment.apps/nginx-deployment configured
```

別ターミナルの状況を見てみます。
```bash
kubectl get pod --watch
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-696bfc48dd-csgxx   1/1     Running   0          58s
nginx-deployment-696bfc48dd-shsg4   1/1     Running   0          58s
nginx-deployment-696bfc48dd-wwh8l   1/1     Running   0          58s
nginx-deployment-6f7c65f4f4-rnkjb   0/1     Pending   0          0s
nginx-deployment-6f7c65f4f4-rnkjb   0/1     Pending   0          0s
nginx-deployment-6f7c65f4f4-rnkjb   0/1     ContainerCreating   0          0s
nginx-deployment-6f7c65f4f4-rnkjb   1/1     Running             0          1s
nginx-deployment-696bfc48dd-csgxx   1/1     Terminating         0          70s
nginx-deployment-6f7c65f4f4-x257f   0/1     Pending             0          0s
nginx-deployment-6f7c65f4f4-x257f   0/1     Pending             0          0s
nginx-deployment-6f7c65f4f4-x257f   0/1     ContainerCreating   0          0s
nginx-deployment-696bfc48dd-csgxx   0/1     Terminating         0          70s
nginx-deployment-6f7c65f4f4-x257f   1/1     Running             0          1s
nginx-deployment-696bfc48dd-csgxx   0/1     Terminating         0          71s
nginx-deployment-696bfc48dd-csgxx   0/1     Terminating         0          71s
nginx-deployment-696bfc48dd-csgxx   0/1     Terminating         0          71s
nginx-deployment-696bfc48dd-wwh8l   1/1     Terminating         0          71s
nginx-deployment-6f7c65f4f4-x8nqc   0/1     Pending             0          0s
nginx-deployment-6f7c65f4f4-x8nqc   0/1     Pending             0          0s
nginx-deployment-6f7c65f4f4-x8nqc   0/1     ContainerCreating   0          0s
nginx-deployment-696bfc48dd-wwh8l   0/1     Terminating         0          71s
nginx-deployment-696bfc48dd-wwh8l   0/1     Terminating         0          72s
nginx-deployment-6f7c65f4f4-x8nqc   1/1     Running             0          1s
nginx-deployment-696bfc48dd-wwh8l   0/1     Terminating         0          72s
nginx-deployment-696bfc48dd-wwh8l   0/1     Terminating         0          72s
nginx-deployment-696bfc48dd-shsg4   1/1     Terminating         0          72s
nginx-deployment-696bfc48dd-shsg4   0/1     Terminating         0          72s
nginx-deployment-696bfc48dd-shsg4   0/1     Terminating         0          73s
nginx-deployment-696bfc48dd-shsg4   0/1     Terminating         0          73s
nginx-deployment-696bfc48dd-shsg4   0/1     Terminating         0          73s
```

これだけ見てもいまいちわかりにくいので、図にします。

![RollingUpdate.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159675/b0f666cd-8857-8dc5-af2d-34bf896fcc79.jpeg)

- 青・・・稼働中の旧Pod
- 灰・・・終了した旧Pod
- 黄・・・新Pod

「Podが1個増えては1個減る」を順番に繰り返していることがわかります。

# BGデプロイ
BGデプロイは現環境の複製を丸々作り、複製した環境の動作確認がOKになったタイミングでトラフィックを新に切り替えるデプロイ方式です。
BGデプロイでは、旧モジュールをBlue環境・新モジュールをGreen環境と定義して、1つのアプリケーションに対してBlue/Greenの2つの環境を作成し、最終的にBlueを削除してGreenだけにします。


![BGデプロイ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159675/d520eb5a-156b-8289-cb8d-d7c02b85c3d9.jpeg)

＜メリット＞
- 無停止でデプロイ可能
- ロールバックが容易
    - Blueをそのまま稼働させて、Greenを削除するだけ
    - 本番環境に影響が出にくい

＜デメリット＞
- 環境を丸々複製するのでリソースコストが高い
    - 今回はシンプルなWEBサーバーを例に取ったが、アプリサーバー・DBサーバー・WEBサーバーなど様々なリソースが入り乱れるアーキテクチャではなかなか大変

# 参考

https://tech.nri-net.com/entry/aws_ecs_deploy

https://www.shoeisha.co.jp/book/detail/9784798183961