CKAD) Canary Deployment

# 概要
- 既存のバージョンを維持した上で、一部新規のバージョンをデプロイし、バージョンでバグがないか確認する

![스크린샷 2023-08-31 00.35.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961840/982e81ba-1e3d-dadf-899a-d2690adc30ca.png)
- サービスは`app`だけで、上記の`Green`を追加する
- ユーザは場合によって、`Blue`や`Green`でアクセスする

## 長所
- バージョンアップデートを進める上で、バグを確認したい場合、このリリースを適応する


## 短所
- アップデートの時間がかかる


# 例
##### 次のようなDeployment、Serviceを作成しなさい
- `stable`という名前で`smlinux/app:stable`イメージを持つPod2個を作成しなさい
  - ラベルは`name=app`、`version=stable`を利用し、ポートは`8080ポート`を利用する
- `canary-svc`サービスは`name=app`ラベルを利用し、`NodePort`タイプのサービスポートは80で運用しなさい
- `new`という名前で`smlinux/app:new-release`イメージを持つPodを1個を作成しなさい
  - ラベルは`name=app`、`version=new`を利用し、ポートは`8080ポート`を利用する

```
kubectl create deployment stable --image=smlinux/app:stable --replicas=2 --port=8080 --dry-run=client -o yaml > stable.yaml
```

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

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

---
apiVersion: v1
kind: Service
metadata:
  name: canary-svc
spec:
  type: NodePort
  selector:
    name: app
  ports:
  - name: name-of-service-port
    protocol: TCP
    port: 80
    targetPort: 8080
```

```今まで進行した結果.
controlplane $ kubectl get all
NAME                          READY   STATUS    RESTARTS   AGE
pod/stable-767bc79b4b-mntvs   1/1     Running   0          32s
pod/stable-767bc79b4b-vlnpq   1/1     Running   0          32s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/canary-svc   NodePort    10.108.184.166   <none>        80:32696/TCP   5m38s
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        22d

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/stable   2/2     2            2           32s

NAME                                DESIRED   CURRENT   READY   AGE
replicaset.apps/stable-767bc79b4b   2         2         2       32s

# 動作確認
controlplane $ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
canary-svc   NodePort    10.108.184.166   <none>        80:32696/TCP   10m
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        22d
controlplane $ kubectl get node
NAME           STATUS   ROLES           AGE   VERSION
controlplane   Ready    control-plane   22d   v1.27.1
node01         Ready    <none>          22d   v1.27.1
controlplane $ curl node01:32696
APP stable Service 
```

```
controlplane $ kubectl create deployment new --image=smlinux/app:new-release --port=8080 --replicas=1 --dry-run=client -o yaml > new.yaml
```

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

```(修正後)new.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    name: app
    version: new
  name: new
spec:
  replicas: 1
  selector:
    matchLabels:
      name: app
      version: new
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        name: app
        version: new
    spec:
      containers:
      - image: smlinux/app:new-release
        name: app
        ports:
        - containerPort: 8080
        resources: {}
status: {}
```

```sh
kubectl apply -f new.yaml
```


```今まで進行した結果.
controlplane $ kubectl get all
NAME                          READY   STATUS    RESTARTS   AGE
pod/new-7cc9bf77c8-tswbb      1/1     Running   0          32s
pod/stable-767bc79b4b-mntvs   1/1     Running   0          11m
pod/stable-767bc79b4b-vlnpq   1/1     Running   0          11m

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/canary-svc   NodePort    10.108.184.166   <none>        80:32696/TCP   16m
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        22d

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/new      1/1     1            1           32s
deployment.apps/stable   2/2     2            2           11m

NAME                                DESIRED   CURRENT   READY   AGE
replicaset.apps/new-7cc9bf77c8      1         1         1       32s
replicaset.apps/stable-767bc79b4b   2         2         2       11m

# 動作確認
controlplane $ curl node01:32696
NEW app service 
controlplane $ curl node01:32696
APP stable Service 
controlplane $ curl node01:32696
APP stable Service 
controlplane $ curl node01:32696
APP stable Service 
```