【Kubernetes】DeploymentとServiceでブルーグリーンデプロイやってみる
はじめに
Kubernetesのデプロイ戦略として、DeploymentとServiceだけでブルーグリーンデプロイを動かしてみます。
Kubernetesでの代表的なデプロイ戦略については、下記でざっくりまとめています。
【Kubernetes】デプロイ戦略についてざっくり理解する
:::affiliate-message 本ページはAmazonアフィリエイトのリンクを含みます。
ブルーグリーンデプロイとは
ブルーグリーンデプロイは、新しいバージョンを実行してからトラフィックを切り替えるデプロイ方法です。
メリット | デメリット |
---|---|
・ダウンタイムがゼロ ・異なるバージョンが同時に実行されない ・すぐに旧バージョンに戻せる | ・2倍のリソースが必要 |
実際に試してみる
実際にブルーグリーンデプロイをやってみます。
ブルーグリーンデプロイを実装する方法はいくつかあると思いますが、今回はシンプルにDeploymentとServiceで実装してみたいと思います。
BlueとGreenのラベルを使い、Serviceでラベルを切り替えて、ブルーグリーンデプロイを実装します。
作成するマニフェスト
今回、作成するマニフェストは下記の通りです。
1.
2├── blue # Blueバージョン
3│ ├── configmap.yml # html用
4│ ├── deployment.yml # BlueバージョンのDeployment
5│ └── service.yml # Blueバージョン専用Service
6├── green # Greenバージョン
7│ ├── configmap.yml # html用
8│ ├── deployment.yml # GreenバージョンのDeployment
9│ └── service.yml # Greenバージョン専用Service
10└── service.yml # アプリのService
Blueバージョンのアプリをデプロイ
まずは、最初のバージョン(Blue)のアプリをデプロイします。
nginxで表示するHTMLファイルを、ConfigMapを使ってマウントします。
blue/configmap.yml
は下記の通りです。
1apiVersion: v1
2kind: ConfigMap
3metadata:
4 name: index-html-blue
5data:
6 index.html: |-
7 <!DOCTYPE html>
8 <html lang="ja">
9 <head>
10 <meta charset="UTF-8">
11 </head>
12 <body style="background-color: blue">
13 <h2>
14 Blue app.
15 </h2>
16 </body>
17 </html>
Blueバージョンのアプリは、Blueバージョン用のConfigMapをマウントしたものになります。
blue/deployment.yml
は、下記の通りです。
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: myapp-blue # Blueバージョンの名前
5spec:
6 replicas: 3
7 selector:
8 matchLabels:
9 app: myapp
10 template:
11 metadata:
12 labels:
13 app: myapp
14 version: blue # Blueバージョンを表すラベル
15 spec:
16 containers:
17 - name: web
18 image: nginx
19 ports:
20 - containerPort: 80
21 volumeMounts:
22 - name: html-volume
23 mountPath: /usr/share/nginx/html
24 volumes:
25 - name: html-volume
26 configMap:
27 name: index-html-blue
blue/service.yml
は、Blueバージョン専用のServiceになります。
マニフェストは下記の通りです。
1apiVersion: v1
2kind: Service
3metadata:
4 name: myapp-service-blue
5spec:
6 ports:
7 - name: http
8 port: 80
9 selector:
10 app: myapp
11 version: blue # Blueバージョンを指定
12 type: NodePort
Blueバージョンのマニフェストを反映させて、デプロイします。
1kubectl apply -f blue
Blueバージョンのアプリをデプロイできました。
1❯ kubectl get pod,svc,cm
2NAME READY STATUS RESTARTS AGE
3pod/myapp-blue-8695b867df-rrqth 1/1 Running 0 82s
4pod/myapp-blue-8695b867df-zdmtp 1/1 Running 0 82s
5pod/myapp-blue-8695b867df-zh688 1/1 Running 0 82s
6
7NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
8service/myapp-service-blue NodePort 10.103.153.114 <none> 80:30528/TCP 82s
9
10NAME DATA AGE
11configmap/index-html-blue 1 82s
NodePortタイプのServiceからアプリにアクセスしてみます。ここではlocalhost:30528
にアクセスします。
Blueバージョンのアプリであることが確認できます。
アプリのServiceを作成
アプリのServiceを作成します。このServiceでBlueとGreenを切り替えます。
最初はBlueバージョンを指定して、作成します。
service.yml
は下記の通りです。
1apiVersion: v1
2kind: Service
3metadata:
4 name: myapp-service
5spec:
6 ports:
7 - name: http
8 port: 80
9 selector:
10 app: myapp
11 version: blue
12 type: NodePort
Serviceを作成します。
1kubectl apply -f service.yml
1❯ kubectl get service
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
3myapp-service NodePort 10.106.122.184 <none> 80:30070/TCP 4s
4myapp-service-blue NodePort 10.103.153.114 <none> 80:30528/TCP 19m
localhost:30070
にアクセスするとBlueバージョンのアプリにアクセスできます。
Greenバージョンのアプリをデプロイ
Greenバージョンのアプリを準備していきます。
green/configmap.yml
は下記の通りです。
1apiVersion: v1
2kind: ConfigMap
3metadata:
4 name: index-html-green
5data:
6 index.html: |-
7 <!DOCTYPE html>
8 <html lang="ja">
9 <head>
10 <meta charset="UTF-8">
11 </head>
12 <body style="background-color: green">
13 <h2>
14 Green app.
15 </h2>
16 </body>
17 </html>
DeploymentはGreen用に名前とラベルを付けています。
green/deployment.yml
は下記の通りです。
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: myapp-green # Greenバージョンの名前
5spec:
6 replicas: 3
7 selector:
8 matchLabels:
9 app: myapp
10 template:
11 metadata:
12 labels:
13 app: myapp
14 version: green # Greenバージョンを表すラベル
15 spec:
16 containers:
17 - name: web
18 image: nginx
19 ports:
20 - containerPort: 80
21 volumeMounts:
22 - name: html-volume
23 mountPath: /usr/share/nginx/html
24 volumes:
25 - name: html-volume
26 configMap:
27 name: index-html-green
Greenバージョン専用のServiceです。
green/service.yml
は下記の通りです。
1apiVersion: v1
2kind: Service
3metadata:
4 name: myapp-service-green
5spec:
6 ports:
7 - name: http
8 port: 80
9 selector:
10 app: myapp
11 version: green # Greenバージョンを指定
12 type: NodePort
Greenバージョンのマニフェストを反映させて、デプロイします。
1kubectl apply -f green
Blueバージョンのアプリをデプロイできました。
1❯ kubectl get pod,svc,cm
2NAME READY STATUS RESTARTS AGE
3pod/myapp-blue-8695b867df-rrqth 1/1 Running 0 3h4m
4pod/myapp-blue-8695b867df-zdmtp 1/1 Running 0 3h4m
5pod/myapp-blue-8695b867df-zh688 1/1 Running 0 3h4m
6pod/myapp-green-696b7b6cbc-5qz7s 1/1 Running 0 10m
7pod/myapp-green-696b7b6cbc-5vd7s 1/1 Running 0 10m
8pod/myapp-green-696b7b6cbc-mdgz4 1/1 Running 0 10m
9
10NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
11service/myapp-service NodePort 10.106.122.184 <none> 80:30070/TCP 164m
12service/myapp-service-blue NodePort 10.103.153.114 <none> 80:30528/TCP 3h4m
13service/myapp-service-green NodePort 10.106.50.90 <none> 80:31429/TCP 10m
14
15NAME DATA AGE
16configmap/index-html-blue 1 3h4m
17configmap/index-html-green 1 10m
NodePortのポート番号を確認して、localhost:30528
にアクセスします。
Greenバージョンのアプリであることが確認できます。
Greenバージョンに切り替え
アプリのバージョンをBlueからGreenに切り替えます。
現状のアプリのバージョンはBlueで、Greenはデプロイされていますが、トラフィックが流れてこない状態です。
service.yml
をグリーンに切り替えます。
1apiVersion: v1
2kind: Service
3metadata:
4 name: myapp-service
5spec:
6 ports:
7 - name: http
8 port: 80
9 selector:
10 app: myapp
11 version: green # Greenバージョンに切り替え
12 type: NodePort
マニフェストを反映させます。
1kubectl apply -f service.yml
localhost:30070
にアクセスすると、先ほどBlueバージョンだったのが、Greenバージョンに変わっていることが確認できます。
Blueバージョンの廃棄
Greenバージョンのアプリが無事切り替えられたので、Blueバージョンを廃棄します。
1kubectl delete deploy myapp-blue
これで、ブルーグリーンデプロイの完了です。
参考
- Zero-downtime Deployment in Kubernetes with Jenkins | Kubernetes
- Podを構成してConfigMapを使用する | Kubernetes