CKAD) Blue-Green Update

# 概要
- 旧バージョン、新バージョンが両方動作し、トラフィックだけ新バージョンで転換

![스크린샷 2023-08-29 23.53.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961840/9b181102-c75b-612e-4cad-2913326c5283.png)


## 長所短所
### 長所
- アップデートするのに、時間がかからない
リソースがすでに公開している途中で、トラフィックだけ修正するとアップデートが終わるので

- ロールバックする時間が短い
旧バージョンもすでに動いている途中でトラフィックだけ修正するので

### 短所
- パソコンのリソースをが普段よりかかる
旧バージョン、新バージョン両方動くので
- ダウンタイム発生
短い時間かもしれないが、トラフィックを変わる時間でダウンタイムが発生

## 例
次のような`Deployments`、`Service`を動作しなさい
- `Blue`という名前で`smlinux/nginx:blue`イメージを持つPodを2個デプロイしなさい
  - Labelは`version=blue`を利用し、ポート番号は`8080`
- `app-svc`サービスを`version=blue`ラベルで集め、 NodePortタイプのサービス、ポート番号は80で運用しなさい
- `Green`という名前で`smlinux/nginx:green`イメージを持つPodを2個デプロイしなさい
  - Labelは`version=blue`を利用し、ポート番号は`8080`
- `app-svc`サービスのラベルを`version=green`で変更しなさい

```sh
kubectl create deployment blue --image=smlinux/nginx:blue --port=8080 --replicas=2 --dry-run=client -o yaml > deployments.yaml
```

```(修正前)deployments.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: blue
  name: blue
spec:
  replicas: 2
  selector:
    matchLabels:
      app: blue
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: blue
    spec:
      containers:
      - image: smlinux/nginx:blue
        name: nginx
        ports:
        - containerPort: 8080
        resources: {}
status: {}
```


```(修正後)deployments.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    version: blue
  name: blue
spec:
  replicas: 2
  selector:
    matchLabels:
      version: blue
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        version: blue
    spec:
      containers:
      - image: smlinux/nginx:blue
        name: nginx
        ports:
        - containerPort: 8080
        resources: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    version: green
  name: green
spec:
  replicas: 2
  selector:
    matchLabels:
      version: green
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        version: green
    spec:
      containers:
      - image: smlinux/nginx:green
        name: nginx
        ports:
        - containerPort: 8080
        resources: {}
---
apiVersion: v1
kind: Service
metadata:
  name: app-svc
spec:
  type: NodePort
  selector:
    version: blue
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
```
```vim
:wq!
```
```sh
kubectl apply -f ./deployments.yaml
```

##### 準備結果
```shell
controlplane $ kubectl get svc   
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
app-svc      NodePort    10.97.110.208   <none>        80:31380/TCP   2m8s
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        21d
controlplane $ kubectl get deployments
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
blue    2/2     2            2           2m15s
green   2/2     2            2           58s
controlplane $ kubectl get pods 
NAME                     READY   STATUS    RESTARTS   AGE
blue-5f6556c4d-p6l69     1/1     Running   0          2m12s
blue-5f6556c4d-zcr22     1/1     Running   0          2m11s
green-56c68bfddb-85kth   1/1     Running   0          60s
green-56c68bfddb-bpwwp   1/1     Running   0          60s
controlplane $ kubectl get nodes
NAME           STATUS   ROLES           AGE   VERSION
controlplane   Ready    control-plane   21d   v1.27.1
node01         Ready    <none>          21d   v1.27.1
controlplane $ curl node01:32684
BLUE app service: nginx_1.14 
```

##### 解決
1. edit コマンドを叩く
   ```
   kubectl edit svc app-svc
   ```

   ```(修正前)edit svc app-svc.yaml
     # Please edit the object below. Lines beginning with a '#' will be ignored,
    # and an empty file will abort the edit. If an error occurs while saving this file will be
    # reopened with the relevant failures.
    #
    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        kubectl.kubernetes.io/last-applied-configuration: |
          {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"app-svc","namespace":"default"},"spec":{"ports":[{"port":80,"protocol":"TCP","targetPort":8080}],"selector":{"version":"blue"},"type":"NodePort"}}
      creationTimestamp: "2023-08-29T15:36:39Z"
      name: app-svc
      namespace: default
      resourceVersion: "3557"
      uid: cfa13548-483f-4c8d-bca4-756d2108c66d
    spec:
      clusterIP: 10.104.250.28
      clusterIPs:
      - 10.104.250.28
      externalTrafficPolicy: Cluster
      internalTrafficPolicy: Cluster
      ipFamilies:
      - IPv4
      ipFamilyPolicy: SingleStack
      ports:
      - nodePort: 32684
        port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        version: blue
      sessionAffinity: None
      type: NodePort
    status:
      loadBalancer: {}

   ```
1. 修正を行う
   ```(修正後)edit svc app-svc.yaml
     # Please edit the object below. Lines beginning with a '#' will be ignored,
    # and an empty file will abort the edit. If an error occurs while saving this file will be
    # reopened with the relevant failures.
    #
    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        kubectl.kubernetes.io/last-applied-configuration: |
          {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"app-svc","namespace":"default"},"spec":{"ports":[{"port":80,"protocol":"TCP","targetPort":8080}],"selector":{"version":"blue"},"type":"NodePort"}}
      creationTimestamp: "2023-08-29T15:36:39Z"
      name: app-svc
      namespace: default
      resourceVersion: "3557"
      uid: cfa13548-483f-4c8d-bca4-756d2108c66d
    spec:
      clusterIP: 10.104.250.28
      clusterIPs:
      - 10.104.250.28
      externalTrafficPolicy: Cluster
      internalTrafficPolicy: Cluster
      ipFamilies:
      - IPv4
      ipFamilyPolicy: SingleStack
      ports:
      - nodePort: 32684
        port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        version: green # 修正箇所
      sessionAffinity: None
      type: NodePort
    status:
      loadBalancer: {}

   ```
1. 保存する
   ```vim
   :wq!
   ```
1. 結果確認
    ```sheel
    controlplane $ curl node01:32684
    BLUE app service: nginx_1.14 
    controlplane $ kubectl edit service app-svc
    service/app-svc edited
    controlplane $ curl node01:32684
    GREEN app service: nginx_1.15 
    ```