Spinnaker+Kayentaでカナリアリリース Pipeline編 (local Kubernetes)

# はじめに
前回、Local環境にSpinnakerとKayentaを導入しました。
https://qiita.com/sugimount/items/0627f99b1bdabf511927

今回は、Spinnaker上にCanaryReleaseを行うための、Pipelineを設定します。


# 全体像
Kubernetesで何らかのサービスを提供している時の構成を、以下の構成と仮定します。

画像の左側に記載しているClientが、Kubernetes上のServiceを経由して、Deployment Prodで作成されるPodへアクセスする構成です。
ProdはVersion 1で稼働しています。
![1104_4301.png](https://qiita-image-store.s3.amazonaws.com/0/104247/d942b508-dee0-516e-b636-105f81d5278d.png)


SpinnakerでCanaryReleaseを行う際には、新しいバージョン(Version 2)と現行バージョン(Version 1)のMetricを比較することにより、新しいバージョンに問題が無い事を確認する手法になります。Spinnakerを開発したNetflixやGoogleは、BaselineとCanaryを新たにDeployする方法を推奨しています。
もちろん、本番で稼働している環境を使用してMetric比較することは出来ますが、長時間稼働しているProdと、新たに作成するCanary間では、Metricの信頼度が異なる場合があるため、新たにBaselineを作成する構成を推奨しています。

DeploymentのProd, Baseline, Canary を同じServiceにぶら下げることにより、Podの数によってトラフィックを分散させる方法です。なお、Istioのように柔軟にトラフィックコントロールが出来るものを取り入れると、数ではなくより柔軟にコントロールが出来るのではないかと予想しています。
![1180_4341.png](https://qiita-image-store.s3.amazonaws.com/0/104247/afa7fad7-50e9-361f-7c83-518990940a08.png)


Canary分析に問題がなければ、Prod環境を全てVersion2に移行し、BaselineとCanaryは削除することにより、安全にリリースすることが出来ます。
![1050_4131.png](https://qiita-image-store.s3.amazonaws.com/0/104247/321eb537-99f4-1503-9bf5-f9089e55fc58.png)

# PIPELINE構築
## Application作成
SpinnakerでPIPELINEを定義するには、Applicationと呼ばれる枠組みを作成する必要があります。
Applicationメニューから、Create Application をクリック。Spinnaker上で、アプリケーションという枠組みを作成します。 (Kubernetesクラスタは何も変わりません)
![1428_7581.png](https://qiita-image-store.s3.amazonaws.com/0/104247/3502974f-6899-917a-3bef-c19c925777cb.png)


適当に、Nameと Email を入力
![615_5051.png](https://qiita-image-store.s3.amazonaws.com/0/104247/3298904a-188b-a61f-20d2-18baa48eb07c.png)


Applicationが作成されました。初期状態では、Canaryは有効になっていないので、有効にするためにCONFIGを選択します
![1423_7571.png](https://qiita-image-store.s3.amazonaws.com/0/104247/abcfc313-4cec-7069-3461-00f9a3cdddea.png)

FEATURES から Canary を選択して、Save Changes
![1421_7581.png](https://qiita-image-store.s3.amazonaws.com/0/104247/a1d0a505-0278-3699-b690-6c1ba7be8130.png)

画面を更新するために、一度Searchメニューを選択
![1423_7611.png](https://qiita-image-store.s3.amazonaws.com/0/104247/bafe13ef-0ffe-01fb-6320-c6f6d35d24c8.png)

Recently viewedから、作成したApplication 「testcanary2」 を選択します
![1418_7521.png](https://qiita-image-store.s3.amazonaws.com/0/104247/b8765495-7644-9db6-9f63-84861483d826.png)

元々、PIPELINE というメニューが、DELIVERY に変化しています。
![1423_7211.png](https://qiita-image-store.s3.amazonaws.com/0/104247/76483cee-aba3-b6cc-9e54-d93ee0d32c7b.png)


## CanaryConfig作成
DELIVERY - CANARY CONFIG メニューを開きます
![1425_7581.png](https://qiita-image-store.s3.amazonaws.com/0/104247/e0678f09-086b-204d-9768-c919d12f9978.png)

Add configurationを選択
Canary分析の時に、何のMetricをどのように分析するかを設定します
![1422_6901.png](https://qiita-image-store.s3.amazonaws.com/0/104247/a2de44dd-79b7-a30c-b5f8-0cb3a4edd601.png)

今回はtest用にCPUのMetricを使用してカナリー分析を行います。
実際の本番環境では、アプリケーションの挙動に関するMetricをカナリー分析で利用すると良いです。
Webアプリケーションの場合は、HTTPステータスコード、応答時間、例外数、負荷平均などを確認すると良いとおもいます。

適当に Configuration Nameを入れます。　
Name: cpu-canary
![1423_7521.png](https://qiita-image-store.s3.amazonaws.com/0/104247/fd1b2518-bd50-affc-6968-629449318052.png)

まず、FILTER TEMPLATES で　Add Templateを押します。
Canary分析のために、今回はPrometheusを使用しますが、Prometheusで収集しているMetricから、今回のアプリケーションで該当しているMetricのみ取得するようにFilterする設定となります。
![1412_6741.png](https://qiita-image-store.s3.amazonaws.com/0/104247/34b3b797-770f-c4c7-d7f8-bca2519953f5.png)

以下のパラメータを入力します。
Name : cpu_filtertemplate
Template : pod_name=~"spinnaker-${scope}.*"
![607_2571.png](https://qiita-image-store.s3.amazonaws.com/0/104247/940f730f-00cc-b8fa-3436-c9de3dafc8b4.png)

上記のパラメータは、Canary分析で利用するMetricDatastoreに依存します。今回は、Prometheusを利用するため、Prometheusで「何のMetric」を「どのようにFilterする」というのを考えながら設定する必要があります。
今回は、testとしてPrometheusの「container_cpu_usage_seconds_total」のMetricを利用します。
下記の画像は、Prometheus上で「container_cpu_usage_seconds_total」のMetric表示させています
![1587_7371.png](https://qiita-image-store.s3.amazonaws.com/0/104247/ea38e204-a488-6487-267e-e1ce6e0b3056.png)

上記のMetricには、Labelに pod_name が付与されていて、該当のPod名前でFilterを行う事が出来ます。
Prometheus上でFilterを行うと、以下の式を指定すると、Podの名前が[spinnaker-prod]で始まるもののみ取得するようにFilterを掛けることが出来ます。
container_cpu_usage_seconds_total{pod_name=~"spinnaker-prod.*"}
Spinnaker上のFilterTemplateには、この式の {} 内に記載する文字列を指定します。
![1587_5551.png](https://qiita-image-store.s3.amazonaws.com/0/104247/83892778-1a34-03d7-6a56-e963c5c7c8c6.png)

SpinnakerのFilter Templateには「pod_name=~"spinnaker-${scope}.*"」と指定していますが、scopeは、Pipeline上の変数を指定する形式のなります。
scopeは後述しますが、baselineという文字と、canaryという文字が入ります。これにより、Prometheus上のMetricを正しくFilterして評価することが出来ます。
![609_2441.png](https://qiita-image-store.s3.amazonaws.com/0/104247/231496a9-a1e4-78ce-702e-530e80008711.png)

次に、Canary分析時に、どのMetricを使用するかを指定します。METRICSメニューで該当のMetricをグループ分けを行うことが出来ます。グループ分けを行うことで、グループごとにMetric評価の重みを付けることが出来ます。
DefaultでGROUP1が存在するので、これの名前を変更します。
![1423_7581.png](https://qiita-image-store.s3.amazonaws.com/0/104247/1fc999fa-9e1d-30e0-a706-e8c675346071.png)


CPUと名前を変更します
![1424_7541.png](https://qiita-image-store.s3.amazonaws.com/0/104247/8c493e20-9568-9599-efe0-4ce054fb6502.png)

CPUグループ内で、Add Metricを押します
![1417_7041.png](https://qiita-image-store.s3.amazonaws.com/0/104247/ad828f70-ab95-0fac-7945-d41f49e25835.png)

以下のパラメータを入力します。

- Name : cpu_utils 任意の名前を指定します。	
- Fail on : CanaryとBaselineを比較した時に、Failとする条件を指定します。以下の3パターンあります。	
  - Increase : 比較して増加している場合はFail
  - Decrease : 比較して減少している場合はFail
  - Either : 増加・減少の両方ともFail
- Criticality : このMetricをFailと判断した場合は、即座にCanary分析を失敗とします。最重要なMetricが失敗したときの挙動の設定の用途です。	
- NaN Storategy : Metricが存在しない場合の処理内容を指定。Default(remove) は削除して計算を行う。	
- Metric Name : Prometheus上のMetricの名前を指定	
![1581_7281.png](https://qiita-image-store.s3.amazonaws.com/0/104247/933b7f09-eb03-dddc-b42e-b5014e66ab4d.png)

追加されます。
![1578_6861.png](https://qiita-image-store.s3.amazonaws.com/0/104247/38a7a30f-6735-503e-ecd4-bfccbb023e85.png)

最後に、各グループの評価の重みづけを行います。
合計で100になるように指定します。今回は1グループしか存在しないので、100を指定します。
Canary分析のJudgeアルゴリズムは「NetflixACAJudge-v1.0」となっており、これは、指定した全てのMetricが成功した割合を基に、判定を行います。
例えばPassを75%と指定している場合は、100個のMetricのうち、75個が成功(pass)している場合は、Canary分析を成功と判断します。
![1443_7631.png](https://qiita-image-store.s3.amazonaws.com/0/104247/1fa9f7c1-21c5-ab3a-0746-5a31899c3cf1.png)


CanaryConfigが作成されます。
![1434_7571.png](https://qiita-image-store.s3.amazonaws.com/0/104247/d4952291-4691-fc43-865c-4b7842ef444a.png)



## Pipeline設定 初期設定
PIPELINESメニューを選択し、Configure a new pipeline を選びます。
![1427_7531.png](https://qiita-image-store.s3.amazonaws.com/0/104247/9b3c5a12-e324-7211-63af-bfc45a5f5f59.png)

名前を入れます。
![623_2401.png](https://qiita-image-store.s3.amazonaws.com/0/104247/cc485df6-0b48-5a40-18ef-b4d1c876a72b.png)

Pipelineの全体像で書いたように、以下のStepを作成していきます。
Step 1. Baseline(現行バージョン)とCanary(新バージョン)のDeploymentをDeploy
Step 2. Canary分析
Step 3. Canary分析をPassした場合は、Prodを新バージョンに入れ替え
Step 4. BaselineとCanaryを削除

まずは、Pipelineの初期設定(Configuration)を設定します。
Pipelineのトリガーは、DockerHubへ新たなImageがBuildされたことをトリガーにします。
Add Trigger を選択
![1422_7591.png](https://qiita-image-store.s3.amazonaws.com/0/104247/fb428ebd-febe-f14b-4972-3a4aec3757f2.png)


Triggerに、DockerRegistoryを選択
![1420_7291.png](https://qiita-image-store.s3.amazonaws.com/0/104247/4fe4c114-1697-5ccf-5697-c8c9fb672826.png)

DockerHubのRegistoryの場所を指定します。DockerHubのRegistory自体は、Halyardで設定しています。
![1429_7511.png](https://qiita-image-store.s3.amazonaws.com/0/104247/f0562475-fbed-b73d-7f63-6aa1410f19e6.png)

Add Artifactを選択します。
![1419_7141.png](https://qiita-image-store.s3.amazonaws.com/0/104247/de1f2624-51b7-90d6-4096-87825bc9cc19.png)

Dockerを選択
![1420_7221.png](https://qiita-image-store.s3.amazonaws.com/0/104247/2e554ba2-4995-f413-a4c7-ae41833d8935.png)

DockerImageに、Trigger元に含まれているであろう情報を指定し、Save Changes を押します。
index.docker.io/sugimount/spin-kub-v2-demo
index.docker.io はDockerHubです。
![1434_7651.png](https://qiita-image-store.s3.amazonaws.com/0/104247/8fdb0010-9a05-3340-8ab6-b2a27fe3f5ed.png)



## Pipeline設定 Baseline, CanaryのDeploy
次に、Step 1 として、Kubernetesクラスタ上に、CanaryとBaselineのDeploymentを作成します。
クラスタ内には既に本番環境として Service や Deploymentが存在しています。

PIPELINE で Add stage を選択します。stage は、pipelineの中で、実行するタスクの単位となります。
![1432_7531.png](https://qiita-image-store.s3.amazonaws.com/0/104247/0f03bd82-44e0-e0d3-13ed-9fe2dc73d855.png)

Stageが追加されます。Deploy (Manifest) を選択します。注意点としてはManifestを直接扱う「Deploy (Manifest)」は、現在開発中のため仕様が変わる可能性があります。
![1425_7611.png](https://qiita-image-store.s3.amazonaws.com/0/104247/f9df3bf8-41e6-7be4-73c5-ce5a65be5984.png)

Stage Name を入力
![1430_7601.png](https://qiita-image-store.s3.amazonaws.com/0/104247/51f2af12-3d22-9821-5f1b-1722562abe6c.png)

Manifestを指定する方法は、直接Textで指定する方法と、Artifactとして外部参照する方法があります。Artifactで参照する方法は、制限事項がおおく扱いにくいため、Textで扱う方式とします。
TextareaにManifestファイルを直接指定します。
![1419_7621.png](https://qiita-image-store.s3.amazonaws.com/0/104247/565e56dc-155e-7f52-8674-f8308d863eac.png)

張り付けるManifestファイルの例

```
- apiVersion: apps/v1beta2
  kind: Deployment
  metadata:
    labels:
      app: spinnaker
      source: demo
      stack: frontend
    name: spinnaker-canary
    namespace: default
  spec:
    replicas: 1
    selector:
      matchLabels:
        app: spinnaker
        source: demo
    template:
      metadata:
        labels:
          app: spinnaker
          source: demo
      spec:
        containers:
          - envFrom:
              - configMapRef:
                  name: spinnaker-demo-config
            image: index.docker.io/sugimount/spin-kub-v2-demo
            name: primary
            ports:
              - containerPort: 80
            readinessProbe:
              httpGet:
                path: /
                port: 80
```

Req. Artifacts To Bindを選択します。これにより、Textで指定したManifestファイルのimageの指定が、Trigger元のDockerHubのイメージtagに書き換えられます。
※ 書き換えには、Textで指定したイメージ名と、Trigger元のイメージ名が一致している必要があります。
Text : index.docker.io/sugimount/spin-kub-v2-demo
Trigger元 : index.docker.io/sugimount/spin-kub-v2-demo:0.0.28
書き換え : index.docker.io/sugimount/spin-kub-v2-demo:0.0.28
![1425_7941.png](https://qiita-image-store.s3.amazonaws.com/0/104247/c91157ca-35b4-83b3-d2c3-db84ff3d140c.png)

次に、BaselineをDeployするStageを設定します。
まず、現行環境のprodで使用しているイメージのタグ情報を取得するstageを追加します。
Add stage を選択し、Typeを選びます。
![1421_7781.png](https://qiita-image-store.s3.amazonaws.com/0/104247/54d7193c-6dfa-2d7b-793b-267ac17fc603.png)

Stage Name と Depends On を選択します。
![1415_7941.png](https://qiita-image-store.s3.amazonaws.com/0/104247/dfee1699-62e7-8a01-9cd3-f9a032561635.png)

KubernetesクラスタからImage情報を取得するための、パラメータを指定します。
![1426_8431.png](https://qiita-image-store.s3.amazonaws.com/0/104247/9a2953e6-183f-5e86-d7ad-546e7d9097eb.png)


指定した条件を基に、下位のStageで使用するArtifact情報を生成します。
Produces Artifacts から、 Add Artifact を選択
![1420_8261.png](https://qiita-image-store.s3.amazonaws.com/0/104247/9d7c4ced-7838-17c0-aebe-5026f945be2a.png)

Dockerの指定と、Docker image を指定します
index.docker.io/sugimount/spin-kub-v2-demo
![1425_8351.png](https://qiita-image-store.s3.amazonaws.com/0/104247/36ef051e-5c1e-2b9d-8414-22c6a16faf20.png)

これで、Prod環境で使用しているImage情報を、下位のStageへArtifactとしてお知らせする準備が出来たため、Baseline Deploymentを作成するStageを作ります。
Add stage
![1437_7491.png](https://qiita-image-store.s3.amazonaws.com/0/104247/4dc6f33e-fda7-fcbb-415e-422dfaf11460.png)

Typeなどを指定します
![1431_8441.png](https://qiita-image-store.s3.amazonaws.com/0/104247/878841c5-6423-97c4-0f86-3b52d02af9e0.png)

Manifestの内容をTextとして指定します
![1411_8471.png](https://qiita-image-store.s3.amazonaws.com/0/104247/a0e34e23-16bf-17a6-4cb2-1afda4149fdd.png)

Manifestファイルを書き換える情報をbindします。どちらが find で生成した Artifact か判断できませんが、基本的には下側になっていると思います。下側を選びます
後程Pipelineの動作確認を行います。
![1431_8301.png](https://qiita-image-store.s3.amazonaws.com/0/104247/d2a0f956-ab2d-1a8e-4666-a0f20cf6d5af.png)

保存します。
![1441_7971.png](https://qiita-image-store.s3.amazonaws.com/0/104247/20952238-257d-7bb6-3454-39193f9f6e20.png)

Pipelineの動作確認を行います。
Pipelineのメニューを開き、Start Manual Excution を選択します。
※ Pipeline のTriggerをDockerHub (SpinnakerがDockerHubをPullする形)を指定しているので、手動でPipelineを実行することが出来ますが、GitHubからWebHookでPushされる形にすると、基本的には手動実行は出来ません。Pushされる形で手動実行すると、Artifactが生成されないため、手動実行に失敗します。
![1414_8231.png](https://qiita-image-store.s3.amazonaws.com/0/104247/c5cba628-13aa-37fd-4a35-9d2682e33651.png)

対象のImageIDを指定します。
![621_3391.png](https://qiita-image-store.s3.amazonaws.com/0/104247/8726a5ee-ccb3-689e-f5f6-ec7fe9c68f02.png)

実行されています。
![1442_7741.png](https://qiita-image-store.s3.amazonaws.com/0/104247/5276d0e2-224b-74e6-bdb2-2a28849b1118.png)

正しく生成されています。IMAGES の列で、baselineとcanaryで正しいtagが使用されていることを確認します。

```
root@qicoo-k8s-master01(default kubernetes-admin):~# kubectl get deployments -o wide
NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINERS    IMAGES                                              SELECTOR
spinnaker-baseline   1         1         1            1           50s       primary       index.docker.io/sugimount/spin-kub-v2-demo:0.0.27   app=spinnaker,source=demo
spinnaker-canary     1         1         1            1           50s       primary       index.docker.io/sugimount/spin-kub-v2-demo:0.0.28   app=spinnaker,source=demo
spinnaker-prod       1         1         1            1           12h       primary       index.docker.io/sugimount/spin-kub-v2-demo:0.0.27   app=spinnaker,source=demo
```

Pipelineの実行が終了しています。
![1440_7641.png](https://qiita-image-store.s3.amazonaws.com/0/104247/5f55409a-8f07-c115-beb4-39738317ff0e.png)




## Pipeline設定 CanaryAnalysis
Canary分析を行います。
PipelineのConfigureを押します。
![1432_7901.png](https://qiita-image-store.s3.amazonaws.com/0/104247/7eeb2601-285e-9abb-1921-92fe2814b38b.png)

Add stage
![1425_8491.png](https://qiita-image-store.s3.amazonaws.com/0/104247/12fb6e3a-f325-0d7b-31a5-10af4587a47d.png)

Stageのパラメータを入力します。
![1429_8561.png](https://qiita-image-store.s3.amazonaws.com/0/104247/da20bd6d-678b-df00-33aa-86d3cf2f75d8.png)

Canary Config を入力します。

- Acalysis Type : Real Time
- Config Name : 作成済みのCanary Configを指定 (cpu-canary)
- Interval : 1 minutes
- Lookback Type : Growing
- Baseline : baseline (ここで指定する文字列が、PrometheusからMetricを取得する際の、変数scope の値となる。CanaryConfigの中にあるFilterTemplateに使用される)
- Baseline Location : default (これも同様に、FilterTemplate内で使用できるが、現在は使用していない。変数locationの値)
- Canary : canary (ここで指定する文字列が、PrometheusからMetricを取得する際の、変数scope の値となる。CanaryConfigの中にあるFilterTemplateに使用される)
- CanaryLocation : default (これも同様に、FilterTemplate内で使用できるが、現在は使用していない。変数locationの値)
- Lifetime : 0 hours 1minutes (Canary分析で分析を行う期間を指定。推奨としては3時間といった長い期間が推奨されている。)
![1418_8111.png](https://qiita-image-store.s3.amazonaws.com/0/104247/605d7a8b-937e-43ff-0c2a-36c248153f04.png)


Marginal : 50 (50%以上のScoreの場合は、人の目による判断を行う設定方法が出来る)
Pass : 75 (75%以上のScoreが出ると成功とする)
![1437_7981.png](https://qiita-image-store.s3.amazonaws.com/0/104247/fba002e2-a5e9-4bc3-246a-2ffea57b6d47.png)

CanaryPipelineの動作確認
![1431_8431.png](https://qiita-image-store.s3.amazonaws.com/0/104247/894f34a7-5e97-39da-ba0b-d5e91afd8d6e.png)

前回は、0.0.28を使用したため、今回はtestで0.0.27 を使用
![609_3321.png](https://qiita-image-store.s3.amazonaws.com/0/104247/4b4f9f2d-6aea-1785-fd03-f266a7bd9ecf.png)

実行されています。
![1428_7021.png](https://qiita-image-store.s3.amazonaws.com/0/104247/28e1b999-5358-e2bf-193d-731a732e50e2.png)

正常に実行出来た場合は、CANARY REPORTS のページで、カナリー分析の詳細を確認できます。
![1425_8451.png](https://qiita-image-store.s3.amazonaws.com/0/104247/036f6a46-e862-5d0d-8e28-322d7d883087.png)



## Pipeline設定 Prod環境へDeploy
Step3. Canary分析が成功した場合は、Prod環境をCanaryで使用したImageに置き換えます。
Add stage
![1427_8261.png](https://qiita-image-store.s3.amazonaws.com/0/104247/dade51fb-246e-fe47-91d6-ddc063896d8c.png)

stageのパラメータ入力
![1417_8181.png](https://qiita-image-store.s3.amazonaws.com/0/104247/6285b355-324d-a98d-af82-9260de7a1a95.png)

Manifestファイルを指定
![1427_8551.png](https://qiita-image-store.s3.amazonaws.com/0/104247/53f0d785-6f3e-b3d9-ae7b-e6c5a1eeb80f.png)

ArtifactのBindを指定。上側の物が、Canary用の新しいバージョンだとおもいます
![1435_8731.png](https://qiita-image-store.s3.amazonaws.com/0/104247/ce2a4794-0a96-cc15-90ba-ec65b66e4e60.png)


## Pipeline設定 Baseline, Canaryの削除
Step 4. として、BaselineとCanaryで作成したDeploymentを削除します。
Add stage
![1429_8351.png](https://qiita-image-store.s3.amazonaws.com/0/104247/bd5796dd-d259-e79e-9005-82829c88d5ee.png)

Stageのパラメータ入力
![1441_8481.png](https://qiita-image-store.s3.amazonaws.com/0/104247/56e2a285-c37e-9723-bfe6-70a42122d3f3.png)

削除対象のDeploymentのパラメータを指定し、保存します。
![1441_8101.png](https://qiita-image-store.s3.amazonaws.com/0/104247/e8dd7ba2-dc29-dd6a-a9eb-57ea2cc1db61.png)

同様にCanaryも削除します。
Add stage
![1428_8231.png](https://qiita-image-store.s3.amazonaws.com/0/104247/2ecee411-9a10-5c48-3f4b-e1ee112d300b.png)

Stageのパラメータを指定します。
![1434_7751.png](https://qiita-image-store.s3.amazonaws.com/0/104247/512ba9b1-9a02-3755-4e2c-a90a215b4d66.png)

削除対象の情報を指定し、保存します。
![1433_8071.png](https://qiita-image-store.s3.amazonaws.com/0/104247/5819fdcb-59ef-6b3a-d136-a482728d153b.png)

動作確認のために、手動でPipelineを実行します
![1435_8341.png](https://qiita-image-store.s3.amazonaws.com/0/104247/5f6550f1-fdff-e7ee-1204-26771b80945e.png)

0.0.28を指定
![615_3371.png](https://qiita-image-store.s3.amazonaws.com/0/104247/5100f5d6-68bb-2f37-73b1-005b877d002f.png)

Baseline, CanaryのDeploy後のKubernetesの状態↓

```
root@qicoo-k8s-master01(default kubernetes-admin):~# kubectl get deployments -o wide
NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINERS    IMAGES                                              SELECTOR
spinnaker-baseline   1         1         1            1           49m       primary       index.docker.io/sugimount/spin-kub-v2-demo:0.0.27   app=spinnaker,source=demo
spinnaker-canary     1         1         1            1           49m       primary       index.docker.io/sugimount/spin-kub-v2-demo:0.0.28   app=spinnaker,source=demo
spinnaker-prod       1         1         1            1           13h       primary       index.docker.io/sugimount/spin-kub-v2-demo:0.0.27   app=spinnaker,source=demo
```


ProdをCanary用イメージに入れ替え後↓

```
root@qicoo-k8s-master01(default kubernetes-admin):~# kubectl get deployments -o wide
NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINERS    IMAGES                                              SELECTOR
spinnaker-baseline   1         1         1            1           50m       primary       index.docker.io/sugimount/spin-kub-v2-demo:0.0.27   app=spinnaker,source=demo
spinnaker-canary     1         1         1            1           50m       primary       index.docker.io/sugimount/spin-kub-v2-demo:0.0.28   app=spinnaker,source=demo
spinnaker-prod       1         2         1            1           13h       primary       index.docker.io/sugimount/spin-kub-v2-demo:0.0.28   app=spinnaker,source=demo
```


Baseline, Canaryを削除後↓

```
root@qicoo-k8s-master01(default kubernetes-admin):~# kubectl get deployments -o wide
NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINERS    IMAGES                                              SELECTOR
spinnaker-prod   1         1         1            1           13h       primary       index.docker.io/sugimount/spin-kub-v2-demo:0.0.28   app=spinnaker,source=demo
```

正常に実行されたことを確認できます
![1417_7081.png](https://qiita-image-store.s3.amazonaws.com/0/104247/25cdcffb-06a1-c4a5-ec14-01e59029574b.png)



# まとめ

SpinnakerとKayentaを利用して、CanaryReleaseを行うPipelineを確認出来ました。ただ、まだ以下の課題があると考えています。

- Pipelineのコード化
- CanaryAnalysisで利用するべきMetricの選択
- MetricをPassかFailか判断するときのアルゴリズムが不明。(どれくらいの差であればPassとなるのか？Marginは設定可能なのか？)

Pipelineのコード化は、spincliで構成する方法があるようですので、これを確認したいと考えています。
CanaryAnalysisで利用するべきMetricについては、アプリケーションへの依存している部分が大きいため、アプリケーション専用のExporterを準備するやり方が良いのではないかと考えています。こちらもどういうやり方が良いかふくめて、引き続き検討したいと思います。