(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Kubernetes】カナリアリリースでデプロイを行う

スポンサーリンク

はじめに

カナリアリリース/カナリーリリース(Canary Release)とはサービスを一部ユーザーのみが利用できるようにリリースし、問題がないことを確認しながら段階的に全体に向けて展開していくデプロイ手法を指します。

本記事では2種類のnginxのバージョンをカナリーデプロイメントにて共存させる流れをハンズオン形式で実践します。

事前準備

以下デプロイメントとサービスのyamlファイルがあるとします。

$ cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 10
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
$ cat nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 80

レプリカ数は10になっているのでデプロイメントを起動すると以下のように10個のPodが立ち上がり

> kubectl apply -f .\nginx-deployment.yaml
deployment.apps/nginx-deployment created
> kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-5754944d6c-6425z   1/1     Running   0          12s
nginx-deployment-5754944d6c-6sssz   1/1     Running   0          12s
nginx-deployment-5754944d6c-872dh   1/1     Running   0          12s
nginx-deployment-5754944d6c-8tm6d   1/1     Running   0          12s
nginx-deployment-5754944d6c-8vwrm   1/1     Running   0          12s
nginx-deployment-5754944d6c-b2z66   1/1     Running   0          12s
nginx-deployment-5754944d6c-dmj4d   1/1     Running   0          12s
nginx-deployment-5754944d6c-l4rt8   1/1     Running   0          12s
nginx-deployment-5754944d6c-vd2w2   1/1     Running   0          12s
nginx-deployment-5754944d6c-z6sdz   1/1     Running   0          12s

サービスを起動すれば

> kubectl apply -f .\nginx-service.yaml
service/nginx created
> kubectl get service
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
nginx        LoadBalancer   10.X.X.X   localhost     60000:32040/TCP   3s

localhostにてnginxの起動が確認できます。

指定したポートでnginxが起動している

カナリアリリース

サービスの確認のために存在しないURLに対してリクエストを行うと以下のようにバージョンと共にエラーが返ってきます。

$ curl localhost:60000/hoge
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.7.9</center>
</body>
</html>

もちろん1000回リクエストを繰り返しても結果は1000回とも同じバージョンでエラーが返ってきます。

$ for i in `seq 1 1000`;do curl localhost:60000/hoge 2> /dev/null| grep hr;done | sort | uniq -c
   1000 <hr><center>nginx/1.7.9</center>

ここでimageを以下とした別名のnginx-canary.yamlを用意してレプリカ数を1で起動すれば

image: nginx:1.7.8

以下のように一つだけ異なるデプロイメントでPodが起動し

> kubectl apply -f .\nginx-canary.yaml
deployment.apps/nginx-canary created
> kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-canary-5c8784fd6d-ctqzk       1/1     Running   0          4s
nginx-deployment-5754944d6c-6425z   1/1     Running   0          20m
nginx-deployment-5754944d6c-6sssz   1/1     Running   0          20m
nginx-deployment-5754944d6c-872dh   1/1     Running   0          20m
nginx-deployment-5754944d6c-8tm6d   1/1     Running   0          20m
nginx-deployment-5754944d6c-8vwrm   1/1     Running   0          20m
nginx-deployment-5754944d6c-b2z66   1/1     Running   0          20m
nginx-deployment-5754944d6c-dmj4d   1/1     Running   0          20m
nginx-deployment-5754944d6c-l4rt8   1/1     Running   0          20m
nginx-deployment-5754944d6c-vd2w2   1/1     Running   0          20m
nginx-deployment-5754944d6c-z6sdz   1/1     Running   0          20m

同一のリクエストを飛ばしても

$ for i in `seq 1 1000`;do curl localhost:60000/hoge 2> /dev/null| grep hr;done | sort | uniq -c
     93 <hr><center>nginx/1.7.8</center>
    907 <hr><center>nginx/1.7.9</center>

約1:10の割合で別バージョンにリクエストがいっていることが分かります。カナリアリリースが成功です。

終わりに

カナリアリリースでは、以下のロールアウトではなく明示的に共存をさせます。そして問題が無ければ明示的に割合を変えていくことも可能です。

炭鉱で毒ガスを検知する「カナリア」から来ている本手法ですが、DevOpsにおけるリリースの形としてはよく見るので実際に動かしながらイメージを掴むと良いと思います。

以上、ご参考になれば幸いです。