Skip to content

Argo Rolloutsの適用

本章では、Qmonus Value Streamを使って、ステージング環境へBlue/Green Deploymentによりアプリケーションをデプロイします。

Qmonus Value Stream - CI/CD パイプライン生成編

初めてのQmonus Value Stream - CI/CD パイプライン生成編)の実施を前提としています。

以降のステップでは、具体的に以下の動作を通じて、サンプルアプリケーションをデプロイし、バージョンの切り替えをblue/greenデプロイで行うことを確認します。

  • Argo Rolloutsを用いてサンプルアプリケーションをblue/greenデプロイ可能な状態でデプロイする。
  • バージョンを変更し改めてアプリケーションのデプロイを実施する。その後プロモートを行うことでバージョンが切り替わることを確認する。

1. アプリケーションデザインパターンの編集 (CLI)

前回チュートリアルで作成したローカルリポジトリで今回のチュートリアル用のブランチを作成します。

bash
# Privateリポジトリからcloneしたディレクトリに移動
cd applications-qvs-demo
# Cloud Native Adapter編集用のブランチを作成する ※ブランチ名は任意
git checkout -b argorollouts-demo

初めてのQmonus Value Stream - Cloud Native Adapterの拡張編の手順1と同様にCloud Native Adapterを編集しアプリケーションの構成を変更します。 前回チュートリアルではdeploymentリソースを作成していましたが、今回はrolloutリソースとして作成します。
編集後のmain.cueと変更箇所について下記を参考に作成してください。

bash
# localディレクトリに移動
cd simple-api/.valuestream/local

# main.cueを編集する
vim main.cue
  • main.cue
go
package local

_const: {
	#name: "simple-api"
	#port: 5000
}

DesignPattern: {
	name: "local"

	parameters: {
		k8sNamespace: string
		imageName:    string
	}

	resources: app: {
		deployment: _deployment
	}

	let _selector = {
		app: _const.#name
	}
	let _container = {
		name:  _const.#name
		image: parameters.imageName
		ports: [{
			containerPort: _const.#port
		}]
		resources: {
			requests: {
				cpu:    "5m"
				memory: "32Mi"
			}
			limits: {
				cpu:    "10m"
				memory: "64Mi"
			}
		}
	}
	_deployment: {
		apiVersion: "argoproj.io/v1alpha1"
		kind:       "Rollout"
		metadata: name: _const.#name
		spec: {
			replicas: 3
			revisionHistoryLimit: 2
			selector: matchLabels: _selector
			template: {
				metadata: labels: _selector
				spec: containers: [
					_container,
				]
			}
            strategy: blueGreen: {
                activeService: "bluegreen-demo"
                previewService: "bluegreen-demo-preview"
                autoPromotionEnabled: false
                previewReplicaCount: 1
                scaleDownDelaySeconds: 30
			}
		}
	}

	// apply namespace
	_deployment: metadata: namespace: parameters.k8sNamespace
}
  • 変更箇所 main.cue
go
@@ -15,7 +15,6 @@ DesignPattern: {
 
        resources: app: {
                deployment: _deployment
-               service:    _service
        }
 
        let _selector = {
@@ -39,11 +38,12 @@ DesignPattern: {
                }
        }
        _deployment: {
-               apiVersion: "apps/v1"
-               kind:       "Deployment"
+               apiVersion: "argoproj.io/v1alpha1"
+               kind:       "Rollout"
                metadata: name: _const.#name
                spec: {
-                       replicas: 1
+                       replicas: 3
+                       revisionHistoryLimit: 2
                        selector: matchLabels: _selector
                        template: {
                                metadata: labels: _selector
@@ -51,24 +51,16 @@ DesignPattern: {
                                        _container,
                                ]
                        }
-               }
-       }
-
-       _service: {
-               apiVersion: "v1"
-               kind:       "Service"
-               metadata: name: _const.#name
-               spec: {
-                       type: "LoadBalancer"
-                       ports: [{
-                               port:       80
-                               targetPort: _const.#port
-                       }]
-                       selector: _selector
+            strategy: blueGreen: {
+                activeService: "bluegreen-demo"
+                previewService: "bluegreen-demo-preview"
+                autoPromotionEnabled: false
+                previewReplicaCount: 1
+                scaleDownDelaySeconds: 30
+                       }
                }
        }
 
        // apply namespace
        _deployment: metadata: namespace: parameters.k8sNamespace
-       _service: metadata: namespace:    parameters.k8sNamespace

Config Compilerを使用して、正しくmanifestが生成されるかを確認します。
実際にはQmonus Value StreamとのAssemblyLineの動作の中でパラメータが自動的に渡されてCloud Native Adapterのコンパイルが行われます。
今はコンパイルが正しく動作することを手動で確認するために、params.jsonというパラメータファイルを一時的に作成します。

bash
# .valuestream ディレクトリに移動
cd ../
# params.jsonを作成する(実際にはValue Streamの中で自動的に作成される)
vim params.json
json
{
    "params": [
        {
            "name": "k8sNamespace",
            "value": "argo-demo"
        },
        {
            "name": "imageName",
            "value": "argoproj/rollouts-demo:green"
        }
    ]
}

Cloud Native Adapterが正しくコンパイルできるかどうかを確認します。

bash
# Config Compilerの実行
cd applications-qvs-demo/simple-api/.valuestream/

config-compiler manifest -c qvs.yaml -p params.json -m .
less output/mainfests.yaml
  • manifestsファイル例
YAML
provider: kubernetes
metadata:
  name: deployargo
  namespace: argo-demo
apiVersion: argoproj.io/v1alpha1
kind: Rollout
output: []
spec:
  replicas: 3
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: deployargo
  template:
    metadata:
      labels:
        app: deployargo
        ver: green
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: deployargo
        image: argoproj/rollouts-demo:green
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        resources:
          requests:
            memory: 32Mi
            cpu: 5m
  strategy:
    blueGreen:
      activeService: bluegreendemo
      previewService: bluegreendemopreview
      autoPromotionEnabled: false
      previewReplicaCount: 1
      scaleDownDelaySeconds: 30

生成されたmanifestファイルについて解説します。
ほぼ、通常のdeploymentと同様な記載をしています。異なる点として6行目のkindにてRolloutを指定しています。
またstrategyアトリビュートを追加しdeployment戦略をblueGreenと指定し追加しています。 strategyの設定値について要点のみ解説するとアクティブ/プレビューサービスを指定し、このあと行う手順4でアプライするサービスをそれぞれ指定しています。
また、解説にも記載していますがautoPromotionEnabled: false でfalseと値を取ることで自動プロモートを許可しない設定としており、明示的にプロモートを行う必要があります。
このステートについて詳しくはArgo Rollouts - Kubernetes Progressive Delivery Controllerをご確認ください。

git add、 git commit、 git pushを行い、リモートリポジトリに変更を反映します。

bash
# リモートリポジトリにpushする
git add local/main.cue
git commit -m "argorollouts-demo for VS tutorial" 
git push origin argorollouts-demo

2. パイプラインデザインパターンの編集 (CLI)

Simple APIをビルド・デプロイするCI/CD Task定義およびCI/CD Pipeline定義を編集します。
初めてのQmonus Value Stream - CI/CD パイプライン生成編)と同様にCI/CD パイプラインのデザインパターンを編集します。
初めてのQmonus Value Stream - Google Cloud編 (初めてのQmonus Value Stream - Azure編)で使用したパイプライン(simple.cue)に、Approval処理とPromote処理を追加します。

simple.cueを修正します。

bash
# Pipeline Cloud Native Adapter を編集してPromoteの機能を追加する
vim design-pattern/pipeline/deploy/simple.cue
import (
	"github.com/qmonus/design-pattern/pipeline/tasks:gitCheckout"
	"github.com/qmonus/design-pattern/pipeline/tasks:compileDesignPattern"
	"github.com/qmonus/design-pattern/pipeline/tasks:deploymentWorker"
+	"github.com/axis-edge/design-patterns/argo:promote"
)
bash
DesignPattern: {
        useDebug:     pipelineParameters.useDebug
				}
					runAfter: ["checkout"]
- 					approvalRequired: true
				}
				"deploy": deploymentWorker.#Builder & {
					runAfter: ["compile"]
				}
+				 "promote": promote.#Builder & {
+ 					 runAfter: ["deploy"]
+ 					approvalRequired: true
+				}

QVS Configについては初めてのQmonus Value Stream - CI/CD パイプライン生成編)で編集した物をそのまま使用します。

manifestファイルを生成し、Pipeline/TaskをQmonus Value Streamへ登録します。

bash
# config-compilerを用いてコンパイル。manifestファイルはoutput配下に生成される。
config-compiler pipeline -c test/argo-demo/simple/qvs.yaml -m .

# 生成されたmanifestファイルの確認
ls output/

3. kubeconfigとNamespaceの作成 (CLI)

初めてのQmonus Value Stream - Google Cloud編と同様にkubeconfigを作成し、Namespaceを用意します。

ここで、gcp_project_idはGoogle Cloud Project ID、cluster_nameはKubernetesクラスタ名、zoneはGKEのZone名を指定します。
k8sNamespaceは、今回デプロイするKubernetes Namespace名です。本チュートリアルではargo-demoという名前のNamespaceを作成します。
ここで指定したNamespace名は、以降の手順でCDパイプラインを実行する際に、実行パラメータとして使用されます。

bash
# 利用するKubernetesへ接続
gcloud --project=${gcp_project_id} container clusters get-credentials ${cluster_name} --zone ${zone}

# Kubeconfigの生成
qvsctl plugin gen-kubeconfig -n argo-demo

なお、gcloudコマンドをはじめて実行する場合は、以下の手順によりgcloudazコマンドを初期化してください。

bash
gcloud auth login

4. アプリケーションクラスタへServiceの登録 (CLI)

本チュートリアルでデプロイするアプリケーションはアクティブサービスとプレビューサービスを登録します。
それぞれのサービスとBlue/Green デプロイの動きについて解説します。

まずはserviceとdeploymentを2セット用意します。
用意するものとして、serviceはActive ServiceとPreview Serviceを用意
deploymentは1つ目のバージョン(v1)と2つ目のバージョン(v2)をそれぞれ用意します。

v1でアプリケーションが稼働しているとして、v2をデプロイすると下図のようになります。

Qmonus Value Stream - CLI

自動または手動でv2が昇格(Active Serviceの向き先を変更)することで、混在状態がなくデプロイできv1は自動的に破棄されます。

Qmonus Value Stream - CLI

serviceの構成ファイルとしてargorollouts-svc.yamlを作成し下記のyamlを記載します。 bluegreendemo/bluegreendemopreviewという名前のアクティブ/プレビューserviceを作成します。

bash
vim argorollouts-svc.yaml
yaml
kind: Service
apiVersion: v1
metadata:
  name: bluegreendemo
spec:
  selector:
    app: deployargo
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name: bluegreendemopreview
spec:
  selector:
    app: deployargo
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

上記のserviceをアプリケーションクラスタへapplyします。

bash
# serviceのアプライ
kubectl -n argo-demo apply -f argorollouts-svc.yaml

# 作成したServiceの確認
kubectl get svc argo-demo

5. Tekton Taskの登録 (CLI)

manifestファイルを生成し、Pipeline/TaskをQmonus Value Streamへ登録します。
今回、手順2にてPromoteタスクを追加したため、改めてQmonus Value Streamにアプライする必要があります。 projectName はQmonus Value StreamのProject Nameです。Project Nameは、qvsctl project list で取得したPROJECT NAMEを指定してください。

bash
# config-compilerを用いてコンパイル。manifestファイルはoutput配下に生成される。
config-compiler pipeline -c test/argo-demo/simple/qvs.yaml -m .

# 生成されたmanifestファイルの確認
ls output/

# qvsctl auth コマンドを使用して認証する(出力されたurlへアクセスしてください)
qvsctl auth

# Project Nameを取得する
qvsctl project list

# manifestファイルのapply 
qvsctl pipeline apply -p ${projectName} -f output/manifest.yaml

6. AssemblyLineの確認 (GUI)

CLIで登録したAssemblyLineをGUIから確認します。手順9で登録したAssemblyLine argoapp-deploy 設定を確認します。

  1. 左メニューより、AssemblyLineを選択します。
  2. 画面中央に表示される argoapp-deploy を選択します。
  3. AssemblyLineと構成するPipeline Stagesが表示されることを確認します。
  4. Pipeline Stagesに表示されている deploy カードを選択します。
  5. 利用されるパラメータ一覧が表示されることを確認します。

7. AssemblyLineの実行 (GUI)

登録したAssemblyLineを実行し、argodemoアプリケーションをKubernetesにデプロイします。
本手順ではまず、Assemnblylineの動作を確認とアプリケーションがデプロイが可能であることを確認します。
のちの手順12にてイメージを変更したもののデプロイとプロモートを行います。

  1. 左メニューより、AssemblyLineを選択します。
  2. 画面中央に表示される argoapp-deploy を選択します。
  3. Pipelines (Stages) に表示されている deploy カードを選択し、全てのパラメータが埋まっていることを確認します。
  4. 以下のInput Parameterを入力し、 RUN ボタンを押下してCI/CDを開始します。
    • gitRevision: argorollouts-demo(ブランチ名)
    • imageTag: blue
  5. 初めてのQmonus Value Stream - CI/CD パイプライン生成編)と同様にAssemblyLineの実行後のResultsの画面にて30秒ほど経過すると、Pipeline Taskにてapproval-compileの右上に目のマークのアイコンが出ていることを確認します。approval-compileのTaskを押下すると、Approval Request のポップアップが現れるので、 APPROVE を押下し、以降の処理を進めることを承諾します。その後、全ての処理が完了することを確認します。

8. デプロイされたサンプルアプリケーションの確認 (CLI)

Kubernetesにアクセスして、デプロイに成功したアプリケーションを確認します。
アプリケーションクラスタにコンテキストが切り替わっていることをご注意ください。

デプロイしたアプリケーションのrolloutsリソースを確認することでデプロイされたアプリケーションの情報を取得できます。

bash

# kubectl のコンテキストがアプリケーションクラスタであることを確認
kubectl config get-contexts
CURRENT     NAME    ...
  *アプリケーションクラスタ    ...
... 

# アプリケーションの確認 (Statusが✔ Healthyになっていることを確認)
kubectl argo rollouts -n argo-demo get rollouts argodemo-app

Serviceリソースを確認することで、サンプルアプリケーションにアサインされたグローバルIPアドレスを確認できます。そのIPアドレスを指定して、HTTPリクエストを送ることで、サンプルアプリケーションのAPIを確認します。

bash
# Podの確認 (Runningになっていることを確認)
kubectl get pod -n argo-demo

# Serviceの確認(EXTERNAL-IPがアサインされていることを確認)
kubectl get service -n argo-demo

# 上記ServiceにアサインされたEXTERNAL-IPにアクセス
curl http://${external_ip}; echo

9. イメージを変更してAssemblyLineの実行とBlue greenデプロイの確認 (GUI)

次はimageTagを変更してAssemblyLineを実行し、デプロイおよびプロモートを行います。
本手順でBlue greenの動きを詳細に確認します。
まずはapprovalを行う前まで通常通りassemblylineを実行します。
approval処理についてはあくまでパイプラインの処理を一時停止するためだけに使用しております。

  1. 左メニューより、AssemblyLineを選択します。
  2. 画面中央に表示される argoapp-deploy を選択します。
  3. Pipelines (Stages) に表示されている deploy カードを選択し、全てのパラメータが埋まっていることを確認します。
  4. 以下のInput Parameterを入力し、 RUN ボタンを押下してCI/CDを開始します。
    • gitRevision: argorollouts-demo(ブランチ名)
    • imageTag: green
  5. AssemblyLineの実行後のResultsの画面にて30秒ほど経過すると、Pipeline Taskにてapproval-compileの右上に目のマークのアイコンが出ていることを確認します。今回はこの先へ処理を進めずにstopさせます。

approval処理についてはあくまで下図のようにパイプラインの処理を一時停止するためだけに使用しています。

Qmonus Value Stream promote

imageTagを変更し、デプロイまでを行いました。しかし、プロモートを行っていないためHTTPリクエストの応答は変わりません。

bash
# デプロイされたrolloutリソースのイメージが変更されていることの確認
kubectl describe rollouts deployargo -n argo-demo | grep Image:

# Serviceの確認(EXTERNAL-IPがアサインされていることを確認)
kubectl get service -n argo-demo

# 上記ServiceにアサインされたEXTERNAL-IPにアクセス
curl http://${external_ip}; echo

次はapprovalを行いプロモートまで処理を進めて改めて確認します。
approval-compileのTaskを押下すると、Approval Request のポップアップが現れるので、 APPROVE を押下し、以降の処理を進めることを承諾します。その後、全ての処理が完了することを確認します。

bash
# アプリケーションの確認 (Statusが✔ Healthyになっていることを確認)
kubectl argo rollouts -n argo-demo get rollouts argodemo-app

# Podの確認 (Runningになっていることを確認)
kubectl get pod -n argo-demo

# Serviceの確認(EXTERNAL-IPがアサインされていることを確認)
kubectl get service -n argo-demo

# 上記ServiceにアサインされたEXTERNAL-IPにアクセス
curl http://${external_ip}; echo

応答がblueからgreenに変わりblue/greenデプロイができていることが確認できます。

解説

本チュートリアルではArgorolloutの機能を利用しプロモートを行うことでblue/greenデプロイができていることを確認しました。
今回はimageTagを変更し再デプロイとプロモートを行いましたが、同様にアプリケーションのバージョンアップなどを行う際に同様な手順を行うことでblue/greenデプロイを行うことができます。
また、自動プロモートを有効にすることも可能となっています。(本チュートリアルではoffにしている)