MicroK8sにArgoCDをインストールするでMicroK8sにArgoCDをインストールしたので機能を試しています。その一貫として、今日はItioとRolloutsを連携してカナリアデプロイメントを試します。
- 事前準備
- Itioをインストールする
- Argo Rolloutsをインストールする
- yamlを作成する
- Rolloutを作成する
- Gatewayを作成する
- VirtualServiceを作成する
- Serviceを作成する
- デプロイする
- Githubに登録する
- ArgoCDのApplicationを作成する
- GithubとArgoCDを同期する
- カナリアデプロイをする
- Rolloutを編集する
- GithubとArgoCDを同期する
- カナリアデプロイを確認する
事前準備
Itioをインストールする
MicroK8sのIstioを有効化して、Istioをインストールします。インストールは以下の記事で実施しているので、今回はスキップします。
MicroK8sでIstioによるABテストを試してみる(1/2)
Argo Rolloutsをインストールする
カナリアデプロイをするにはRolloutというリソースが必要になるので、以下のURLを参考にそのArgo Rolloutsをインストールします。
https://argoproj.github.io/argo-rollouts/features/kubectl-plugin/
ArgoCDによるBlueGreenデプロイを試すでインストール済みなので、今回はスキップします。
yamlを作成する
以下のURLを参考に、IstioとArgo Rolloutsのyamlを作成します。
https://argoproj.github.io/argo-rollouts/features/traffic-management/istio/
Rolloutを作成する
IstioのSubsetでバージョン毎に流量制御を行うで作成したhelloaアプリケーションのv1/v2を利用して、カナリアデプロイ用のRolloutを作成します。
以下のyamlを使って、レプリカ数 4個のhelloa:v1アプリケーションを実行するhelloa-istio-canaryを作成します。helloa-istio-canaryは、アプリケーションアップデート時に25%分(1個)だけ新しいバージョンをデプロイし、30秒間canary-svcを経由してアクセスを受け付けます。30秒経過すると、新しいバージョンのアプリケーションを100%分(4個)デプロイし、stable-svcを経由してアクセスを受け付けます。
apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: helloa-istio-canary namespace: istio-app spec: replicas: 4 revisionHistoryLimit: 2 selector: matchLabels: app: helloa template: metadata: labels: app: helloa spec: containers: - name: helloa image: localhost:32147/helloa:v1 imagePullPolicy: Always ports: - containerPort: 8080 strategy: canary: steps: - setWeight: 25 - pause: duration: 30s canaryService: canary-svc stableService: stable-svc trafficRouting: istio: virtualService: name: rollout-vsvc routes: - primary
Serviceを作成する
helloa-istio-canaryで指定したServiceを作成します。以下のyamlで、helloaをポート8080で公開するcanary-svcとstable-svcを作成します。
kind: Service apiVersion: v1 metadata: name: canary-svc namespace: istio-app spec: selector: app: helloa type: ClusterIP ports: - protocol: TCP port: 8080 targetPort: 8080 --- kind: Service apiVersion: v1 metadata: name: stable-svc namespace: istio-app spec: selector: app: helloa type: ClusterIP ports: - protocol: TCP port: 8080 targetPort: 8080
Gatewayを作成する
外部からの通信を受け付けるために、IstioのGatewayを作成します。以下のyamlは、デフォルトのGatewayに対する80番ポートを全て受け付けるGatewayです。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: helloa-gateway namespace: istio-app spec: selector: istio: ingressgateway # use Istio default gateway implementation servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"
VirtualServiceを作成する
以下のyamlを使って、canary-svcとstable-svcに通信を割り振るrollout-vsvcを作成します。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: rollout-vsvc namespace: istio-app spec: hosts: - "*" gateways: - helloa-gateway http: - name: primary route: - destination: host: stable-svc weight: 100 - destination: host: canary-svc weight: 0
デプロイする
Githubに登録する
上記で作成したyamlをGitHubに登録し、その後以下のコマンドでArgoCDにGitHubを登録します。
$ argocd repo add https://github.com/[user名]/[レポジトリ名] --username [user名]
ArgoCDのApplicationを作成する
以下のコマンドで、登録したGitレポジトリを使ってApplicationを作成します。デプロイ先のnamespaceはIstioインジェクション済みであることに注意してください。インジェクション方法は、MicroK8sでIstioによるABテストを試してみる(2/2)で紹介しています。
$ argocd app create istio-canary --repo [レポジトリURL] --path [ディレクトリ] --dest-namespace [Injection済みnamespace] --dest-server [ClusterURL]
GithubとArgoCDを同期する
以下のコマンドで、ApplicationをGitHubと同期してyamlからデプロイします。
$ argocd app sync istio-canary
作成が完了すると、以下の図のようになります。

カナリアデプロイをする
Rolloutを編集する
helloa-istio-canaryのイメージタグをv1からv2に変更し、再度GitHubに登録します。
image: localhost:32147/helloa:v2
GithubとArgoCDを同期する
再度以下のコマンドでGitHubと同期して変更を反映します。
$ argocd app sync istio-canary
カナリアデプロイを確認する
GUIで確認すると、以下のように25%分をデプロイしていることがわかります。(以下の画像は、一世代前のPodが削除される直前です。)

通信経路を確認すると、stable-svcに75%(1世代前のPod)、canary-svcに25%(新規Pod)通信を割り振っていることがわかります。(以下の画像は、一世代前のPodが削除される直前です。)

30秒後、以下のように新規Podが100%になります。

最終的には以下の画面になります。一世代前のReplicaSetが残っていることが確認できます。

以上です!