【Kubernetes】DeploymentとServiceでブルーグリーンデプロイやってみる

スポンサーリンク

はじめに

Kubernetesのデプロイ戦略として、DeploymentとServiceだけでブルーグリーンデプロイを動かしてみます。

Kubernetesでの代表的なデプロイ戦略については、下記でざっくりまとめています。

【Kubernetes】デプロイ戦略についてざっくり理解する
はじめにKubernetesにおけるデプロイ戦略をざっくりまとめてみたいと思います。デプロイ戦略ここで紹介するデプロイ戦略は下記になります。ローリングアップデートRecreateブルーグリーンデプロイレインボーデプロイカナリアデプロイKub...

ブルーグリーンデプロイとは

ブルーグリーンデプロイは、新しいバージョンを実行してからトラフィックを切り替えるデプロイ方法です。

メリットデメリット
・ダウンタイムがゼロ
・異なるバージョンが同時に実行されない
・すぐに旧バージョンに戻せる
・2倍のリソースが必要

実際に試してみる

実際にブルーグリーンデプロイをやってみます。

ブルーグリーンデプロイを実装する方法はいくつかあると思いますが、今回はシンプルにDeploymentとServiceで実装してみたいと思います。

BlueとGreenのラベルを使い、Serviceでラベルを切り替えて、ブルーグリーンデプロイを実装します。

作成するマニフェスト

今回、作成するマニフェストは下記の通りです。

.
├── blue # Blueバージョン
│   ├── configmap.yml # html用
│   ├── deployment.yml # BlueバージョンのDeployment
│   └── service.yml # Blueバージョン専用Service
├── green # Greenバージョン
│   ├── configmap.yml # html用
│   ├── deployment.yml # GreenバージョンのDeployment
│   └── service.yml # Greenバージョン専用Service
└── service.yml # アプリのService

Blueバージョンのアプリをデプロイ

まずは、最初のバージョン(Blue)のアプリをデプロイします。

nginxで表示するHTMLファイルを、ConfigMapを使ってマウントします。

blue/configmap.ymlは下記の通りです。

apiVersion: v1
kind: ConfigMap
metadata:
  name: index-html-blue
data:
  index.html: |-
    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
    </head>
    <body style="background-color: blue">
      <h2>
        Blue app.
      </h2>
    </body>
    </html>

Blueバージョンのアプリは、Blueバージョン用のConfigMapをマウントしたものになります。

blue/deployment.ymlは、下記の通りです。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-blue # Blueバージョンの名前
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
        version: blue # Blueバージョンを表すラベル
    spec:
      containers:
      - name: web
        image: nginx
        ports:
          - containerPort: 80
        volumeMounts:
        - name: html-volume
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html-volume
          configMap:
            name: index-html-blue

blue/service.ymlは、Blueバージョン専用のServiceになります。

マニフェストは下記の通りです。

apiVersion: v1
kind: Service
metadata:
  name: myapp-service-blue
spec:
  ports:
  - name: http
    port: 80
  selector:
    app: myapp
    version: blue # Blueバージョンを指定
  type: NodePort

Blueバージョンのマニフェストを反映させて、デプロイします。

kubectl apply -f blue

Blueバージョンのアプリをデプロイできました。

❯ kubectl get pod,svc,cm
NAME                              READY   STATUS    RESTARTS   AGE
pod/myapp-blue-8695b867df-rrqth   1/1     Running   0          82s
pod/myapp-blue-8695b867df-zdmtp   1/1     Running   0          82s
pod/myapp-blue-8695b867df-zh688   1/1     Running   0          82s

NAME                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/myapp-service-blue   NodePort    10.103.153.114   <none>        80:30528/TCP   82s

NAME                         DATA   AGE
configmap/index-html-blue    1      82s

NodePortタイプのServiceからアプリにアクセスしてみます。ここではlocalhost:30528にアクセスします。

Blueバージョンのアプリであることが確認できます。

アプリのServiceを作成

アプリのServiceを作成します。このServiceでBlueとGreenを切り替えます。

最初はBlueバージョンを指定して、作成します。

service.ymlは下記の通りです。

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  ports:
  - name: http
    port: 80
  selector:
    app: myapp
    version: blue
  type: NodePort

Serviceを作成します。

kubectl apply -f service.yml
❯ kubectl get service
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
myapp-service        NodePort    10.106.122.184   <none>        80:30070/TCP   4s
myapp-service-blue   NodePort    10.103.153.114   <none>        80:30528/TCP   19m

localhost:30070にアクセスするとBlueバージョンのアプリにアクセスできます。

Greenバージョンのアプリをデプロイ

Greenバージョンのアプリを準備していきます。

green/configmap.ymlは下記の通りです。

apiVersion: v1
kind: ConfigMap
metadata:
  name: index-html-green
data:
  index.html: |-
    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
    </head>
    <body style="background-color: green">
      <h2>
        Green app.
      </h2>
    </body>
    </html>

DeploymentはGreen用に名前とラベルを付けています。

green/deployment.ymlは下記の通りです。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-green # Greenバージョンの名前
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
        version: green # Greenバージョンを表すラベル
    spec:
      containers:
      - name: web
        image: nginx
        ports:
          - containerPort: 80
        volumeMounts:
        - name: html-volume
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html-volume
          configMap:
            name: index-html-green

Greenバージョン専用のServiceです。

green/service.ymlは下記の通りです。

apiVersion: v1
kind: Service
metadata:
  name: myapp-service-green
spec:
  ports:
  - name: http
    port: 80
  selector:
    app: myapp
    version: green # Greenバージョンを指定
  type: NodePort

Greenバージョンのマニフェストを反映させて、デプロイします。

kubectl apply -f green

Blueバージョンのアプリをデプロイできました。

❯ kubectl get pod,svc,cm
NAME                               READY   STATUS    RESTARTS   AGE
pod/myapp-blue-8695b867df-rrqth    1/1     Running   0          3h4m
pod/myapp-blue-8695b867df-zdmtp    1/1     Running   0          3h4m
pod/myapp-blue-8695b867df-zh688    1/1     Running   0          3h4m
pod/myapp-green-696b7b6cbc-5qz7s   1/1     Running   0          10m
pod/myapp-green-696b7b6cbc-5vd7s   1/1     Running   0          10m
pod/myapp-green-696b7b6cbc-mdgz4   1/1     Running   0          10m

NAME                          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/myapp-service         NodePort    10.106.122.184   <none>        80:30070/TCP   164m
service/myapp-service-blue    NodePort    10.103.153.114   <none>        80:30528/TCP   3h4m
service/myapp-service-green   NodePort    10.106.50.90     <none>        80:31429/TCP   10m

NAME                         DATA   AGE
configmap/index-html-blue    1      3h4m
configmap/index-html-green   1      10m

NodePortのポート番号を確認して、localhost:30528にアクセスします。

Greenバージョンのアプリであることが確認できます。

Greenバージョンに切り替え

アプリのバージョンをBlueからGreenに切り替えます。

現状のアプリのバージョンはBlueで、Greenはデプロイされていますが、トラフィックが流れてこない状態です。

service.ymlをグリーンに切り替えます。

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  ports:
  - name: http
    port: 80
  selector:
    app: myapp
    version: green # Greenバージョンに切り替え
  type: NodePort

マニフェストを反映させます。

kubectl apply -f service.yml

localhost:30070にアクセスすると、先ほどBlueバージョンだったのが、Greenバージョンに変わっていることが確認できます。

Blueバージョンの廃棄

Greenバージョンのアプリが無事切り替えられたので、Blueバージョンを廃棄します。

kubectl delete deploy myapp-blue

これで、ブルーグリーンデプロイの完了です。

参考

タイトルとURLをコピーしました