ArgoRolloutsとIstioを連携したカナリアデプロイ

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が残っていることが確認できます。

以上です!