Save 37% off PRO during our Black Friday Sale! »

実践! Argo CD & Rollouts による canary release / Practical Canary release by Argo CD & Rollouts

Ef1341e83c896b7b1c5061674951aa2c?s=47 Hayato Okuma
November 05, 2021

実践! Argo CD & Rollouts による canary release / Practical Canary release by Argo CD & Rollouts

freee の SRE チームでは、直近 2 年をかけて EC2 上で稼働するサービスのインフラ基盤を Kubernetes (AWS EKS) に移行するプロジェクトを進めてきました。一番規模の大きな freee会計も2021年7月に移行が完了し、 GitOps の CD ツールである Argo CD によるデプロイを行っています。インフラ基盤の刷新に加えて Argo CD を導入したことで、デプロイフローにかかる時間や手間の削減に繋がりました。現在はデプロイフローをより良くするために、canary release を検証中です。

今回はその検証をもとに、Kubernetes 上でどのようなアーキテクチャによって canary release を実現するかについてお話しします。メイントピックとなるのは Argo Rollouts を導入する既存の CD の構成と、Argo Rollouts を本番運用するための方針及び課題です。

(CNDT2021 スポンサー枠登壇資料)

Ef1341e83c896b7b1c5061674951aa2c?s=128

Hayato Okuma

November 05, 2021
Tweet

Transcript

  1.   実践! Argo CD & Rollouts による canary release 


    2021.11.05

  2.   2 • profile
 ◦ 福岡県宗像市出身。
 • work
 ◦ 2020.04

    : freee に新卒入社
 ◦ 2020.10 : インフラ基盤のEC2=>EKS移行
 ◦ 2021.08 : CI/CD 周りの保守運用, 改善
 • trend
 ◦ ランニング, おうちk8s, 油そば(平太周)
 
 大隈 隼
 freee株式会社 / SRE
 Hayato Okuma - kumashun
 プロフィール画像の トリミング方法
  3.   3 本登壇のメインターゲット
 ⚠ 資料製作時点では、Argo Rollouts の本番導入までには至りませんでしたm
 
 Kubernetes 環境において、


    • 現在他の CD ツールを使っているが、Argo CD の導入を検討している方
 • Canary や Bule/Green などのデプロイ戦略の導入を検討している方
 • これから Argo Rollouts の導入 or Argo CD との併用を検討している方
 
 
 
 

  4. 4 01 freee の進化とプロダクトの成長
 02 freee の CD と Argo

    projects
 03 freee での Argo CD 導入過程
 04 freee会計と canary release
 05 Argo Rollouts 導入への道のり
 06 まとめ
 アジェンダ

  5.   freee の進化と
 プロダクトの成長


  6.   6 freee について
 • 創立 : 2012年7月
 • Mission

    : スモールビジネスを、世界の主役に。
 • Vision : だれもが自由に経営できる統合型経営プラットフォーム。
 ◦ 10以上のプロダクトで、創業から上場まであらゆるビジネスステージを網羅
 • 【freee】ブランドムービー2021「スモールビジネスを、世界の主役に。」
 
 
 
 
 

  7.   7 freee会計 freee開業 freee福利厚生 freeeアプリストア freee人事労務 freee会社設立 freeeスマート受発注 freeeプロジェクト管理

    freee資金調達 freee申告 freeeカード プロダクトラインナップ

  8.   8 2012 2013 2014 2015 2016 2017 200 100

    150 50 2020 エンジニア数(人) プロダクトと開発組織の成長
 2019 2018 プロダクト リリース 会計freee freee 人事労務 freee 会社設立 マイナンバー 開業 freee申告 freeeカード アプリストア公 開 プロジェクト管 理freee freee finance lab株式会社 設立 API公開 サービス 分割開始 チーム制 導入 クラウドERP コンセプト発 表 マイクロサー ビス化 開始 基盤投資 加速 プラット フォーム 元年 新規 プロダクト加 速
  9.   freee の CI/CD と
 Argo projects


  10.   10 CI/CD の標準化を進めたい
 • 既存のプロダクトのマイクロサービス化や新規プロダクトの爆速リリースによって、多く の Kubernetes cluster が生まれた。


    ◦ freee ではシングルテナント戦略を採用。
 
 • manifest の管理は SRE が行っているものの、image build やデプロイフローなどの CI/CD の仕組みはチームによってバラバラだった。
 
 • それらを標準形に移行させ、保守運用していく = SRE の CLC チーム
 ◦ CLC : Container Logistics Co. という造語の略称
 
 
 
 

  11.   11 freee の cluster 運用
 • computing : Amazon

    EKS
 • routing : ELB -> envoy proxy -> service -> pod
 • AWS リソース及び cluster 本体や node group の設定な どは Terraform による IaC
 
 
 
 

  12.   12 freee の cluster 運用
 • manifest 管理
 ◦

    Helm + Helmfile を使用。
 ◦ サービス共通で使い回せる common chart を定義。
 
 • common chart はアプリエンジニアとSREの責務を分ける目的で 2 種類に分類。
 ◦ app 系 : ビジネスロジック (Rails, Go などのアプリケーション) が載る。
 ◦ system 系 : Daemonset や APM など (fluentd, envoy-proxy, Datadog) が載る。
 
 
 
 
 
 

  13.   13 freee の cluster 運用
 • CI
 ◦ GitHub

    Actions self hosted runner による image build
 • CD
 ◦ 内製 GitOps ツールによる helmfile sync の実行
 => Argo CD に移行中
 
 
 
 

  14.   14 Argo projects
 • intuit が開発した Kubernetes 向け OSS

    の総称
 • プロダクトの種類
 ◦ Argo CD
 ▪ GitOps のための CD ツール
 ◦ Argo Rollouts
 ▪ デプロイ戦略を提供
 ◦ Argo Workflow
 ▪ データ処理パイプラインの Argo Workflows 移行を検討した話 
 ◦ Argo Events
 ▪ event source を受けて、workflow へのトリガーを管理する
 
 
 
 

  15.   15 Argo CD
 • GitOps のための Kubernetes 向け CDツール。


    • manifest の PR merge をトリガーにデプロイ= sync で きる。
 • 実体はすべて CRD であり、自身も Argo CD によるデ プロイが可能。
 
 
 
 https://argo-cd.readthedocs.io/en/stable/assets/argocd_architecture.png
  16.   16 デプロイ対象ごとに必要なリソース
 • kind: Application
 ◦ Argo CD でのデプロイ対象となるKubernetes

    リ ソースのグループ
 
 • kind: AppProject
 ◦ 複数の kind: Application のグループ
 ◦ デプロイ元となるソースコードやデプロイ先の cluster などを制限することが可能。
 
 
 
 

  17.   17 Argo CD のアーキテクチャ
 dex-server
 Argo CD における SAML

    SP
 repo-server
 repogitory を clone して helmfile template を行う
 argocd-server
 web UI や API endpoint を提供する
 application-controller
 kind: Application を監視し、定義に従ってライフサイクルイベント (sync など) を実行する
 redis-ha
 argocd-repo-server が render した manifest をキャッシュする
 ref : Argo CD はどのように manifest をキャッシュしているのか? 
 redis-ha-haproxy
 redis-ha の proxy

  18.   18 Argo Rollouts
 • Canary や Blue/Green のようなデプロイ戦略を 導入するための

    Kubenertes controller 及び CRD の総称。
 • Ingress controller や Service mesh への integration も用意されている。
 
 
 
 
 https://argoproj.github.io/argo-rollouts/architecture-assets/argo-rollout-architecture.png
  19.   19 kind: Rollout
 • kind: Deployment を拡張したイメージ。
 • spec.strategy

    に応じて複数の replicasets を管理す る。
 • spec.strategy.canary の場合
 ◦ stable/canary の 2 つの replicasets 。
 ◦ steps : canary のリリース段階
 ▪ manifest をデプロイ直後、canary の pod 数は全体の 20 %
 ▪ 1 step 進める = promote すると全体の 50%
 ▪ さらに promote すると 100% = release 完了
 
 
 
 
 strategy: canary: stableMetadata: labels: role: stable canaryMetadata: labels: role: canary steps: - setWeight: 20 - pause: {} - setWeight: 50 - pause: {}
  20.   freee での Argo CD 導 入過程


  21.   21 Argo CD 導入前
 • Circle CI を使った内製 GitOps

    ツールでデプロイ。
 • manifest を管理している repository への PR 上のコメント経由で、helmfile コマ ンドを叩いていた。(例)
 ◦ hoge deploy -c <cluster_name> --dry-run=true ▪ helmfile -f /path/to/<cluster_name>/helmfile.yaml diff ◦ hoge deploy -c <cluster_name> ▪ helmfile -f /path/to/<cluster_name>/helmfile.yaml sync ◦ 本番環境へのデプロイには dry-run が必須になる仕組み
 • デプロイ時は基本的に image tag を書き換える PR を出して、そこでコマンド実 行していた。
 
 
 
 

  22.   22 内製ツールのgood/bad
 • good
 ◦ アプリエンジニアでも簡単にデプロイできる。
 ◦ cluster ごとのデプロイ手順が共通化する。


    • bad
 ◦ Circle CI に強力な権限を渡す必要があった。
 ◦ 誰でも PR にコメント = デプロイできてしまう。
 ◦ app 系と system 系の両方がデプロイ対象になるので、
 ▪ デプロイ時間が遅い。
 ▪ dry-run の結果にデプロイに関わりのない(system 系の) diff が出てしま う。
 
 
 
 

  23.   23 そこで Argo CD !!
 • tekton, FluxCD と合わせて比較を行った結果、Argo

    CD を採用。
 ◦ 使い勝手の良さで判断。
 
 • 内製ツールの bad への対応
 ◦ Circle CI に強力な権限を渡す必要があった。
 => VPC 内でデプロイフローが完結する。
 
 ◦ 誰でも PR にコメント = デプロイできてしまう。
 => appProject ごとに実行権限を分けて管理できる。
 
 ◦ app 系と system 系の両方がデプロイ対象になる
 => app 系と system 系で application を分けることで回避。
 
 
 
 

  24.   24 Argo CD によるデプロイの手順
 1. image tag 変更の PR

    を作成する。
 2. 内製 Argo CD 連携アプリによって PR- 実リソース間の diff を取得。
 a. 想定通りの diff であれば、PR をマージする。
 b. 意図しない diff があれば、問題ないか確認する。
 3. Argo CD の UI 上から master ブランチ- 実リソース間の diff を確認。
 a. 想定通りの diff であれば、sync を実行する。
 b. 意図しない diff があれば、問題ないか確認する。
 
 
 
 

  25.   25 内製 Argo CD 連携アプリ
 • UI 上から確認できる diff

    は、target revision として指定した branch と実リソースとの 間にあるもの。
 ◦ master マージするまで、valid な manifest かどうかが不明。
 
 
 
 

  26.   26 内製 Argo CD 連携アプリ
 • GitHub Actions をトリガーとして、連携アプリが処理を行う。


    ◦ 変更のあったファイルのディレクトリ構成などから PR に label を付与。
 ▪ application の名前を特定できるような labeling
 ◦ label が貼られたのをトリガーに、連携アプリが Argo CD の API を叩く。
 ▪ argocd app diff ${ application_name } \ --revision ${ PR の commit hash } --grpc-web
 ◦ 取得した diff を PR にコメントする。
 ▪ diff の内容を含めてPRレビューが可能に!
 
 
 
 

  27.   27 Argo CD の導入手順 
 Argo CD 本体のデプロイしたうえで、各 cluster ごとに以下を行う。


    1. helmfile を app 系/system系の 2 つに分離
 2. 権限周りの設定追加
 3. Application, AppProject の作成
 4. 内製 GitOps ツールからのデプロイ禁止設定
 
 
 

  28.   freee会計と
 canary release


  29.   29 freee 会計
 • 有料課金ユーザー企業数※1 293K 以上のクラウド会計ソフト。
 • freee

    のサービス群の中で最も規模の大きなサービス。
 
 
 
 
 ※1 2021年6月末時点。有料課金ユーザー企業数に 䛿個人事業主を含む https://contents.xj-storage.jp/xcontents/AS08692/330086ca/ca2e/48ce/a618/7936926a5dff/20210813130156762s.pdf
  30.   30 EKS 移行
 • 直近の2年間で ほぼ全てのサービスのインフラ基盤 を EC2 から

    EKS に移行。
 ◦ 規模や与える影響的に freee 会計は終盤に。
 • やったこと
 ◦ アプリケーションのコンテナ化
 ◦ common chart の整備 & helmfile 作成
 ◦ 環境変数の移行
 ◦ Argo CD 周りの設定
 ◦ ALB target group による weigthed traffic の切り 替え
 
 
 

  31.   31 EKS 移行 ( + Argo CD 導入) による影響


    • デプロイ/ロールバックの時間及び作業コストの大幅な削減
 • Argo CD の Web UI による Kubernetes リソースの可視化
 
 一方で、EC2 時代にあった canary release がデグレした状態。
 
 
 

  32.   32 freee 会計の canary release
 • freee のサービスは、ユーザーの売上や経営状況に関わるようなセンシティブな データを扱う。


    • freee 会計は大規模ゆえ他サービスとの連携機能が多数あり、障害の影響も伝播 しやすい。
 
 • canary release を導入して、新機能のリリースに伴うサービス障害の影響範囲を小 さくすることで、
 ◦ ロールバックを容易にする。
 ◦ 新機能のリリースの心理的ハードルを下げる。
 
 
 

  33.   33 sticky session
 • 影響範囲 = ユーザー数を少数に固定するために、sticky session を導入していた。


    ◦ front が canary release で処理した場合、 canary release された server にのみリクエスト が飛ぶようにする。
 ◦ sticky session がなければ、結局アクセスした全ユーザーが対象になってしまう。
 
 • L7 (ALB listener rule) での cookie によるトラフィック管理で実現。
 
 
 

  34.   34 canary release 再導入への期待
 • EKS移行後初の確定申告期間中(アクセス急増)も安心してデプロイするために、や はり canary release

    は必要。
 
 • sticky session 含め、仕組みは Kubernetes 内で完結させたい。
 ◦ AWS Ingress controller のような Kubernetes 外のリソースを manifest で管理する のは freee の cluster 戦略に合わない。
 
 • Argo CD に次ぐ Argo project として Argo Rollouts での実装を検討。
 
 

  35.   Argo Rollouts 導入への道のり


  36.   36 cluster 構成の before/after


  37.   37 canary release の手順
 1. image tag 変更の PR

    をマージする。
 2. Argo CD の sync を実行する。
 3. canary の 1st step に入って、定義に従った台数分 canary pod が立ち上 がる。
 4. metrics や bug など canary の状態を 一定時間 watch して、問題がない か確認
 a. 問題がなければ、canary を promote して次の step へ、または promote-full で一気にデプロイを進める。
 b. 問題があれば canary を abort して、canary pod が 0 台の状態に戻 す。
 
 
 
 

  38.   38 導入作業
 • kind: Rollout をコードベースで利用可能にする
 • RBAC の追加


    • stable/canary ごとの bug や metrics の出し分け設定
 
 
 
 

  39.   39 kind: Rollout をコードベースで利用可能にする
 • Deployment => Rollout への変更


    • CRD のインストール
 
 
 
 

  40.   40 Deployment => Rollout への変更
 • app 系の common

    chart に対して
 ◦ kind: Rollout を入れる。
 ◦ spec.strategy の内容を kind: Rollout 用に変える。
 
 • 書き換える方針として
 ◦ 既存の chart の version を上げる。
 ◦ <chart_name>-canary のような別 chart として作成する。
 
 
 
 

  41.   41 (方針1) 既存の chart の version を上げる
 • freee

    では common chart の version 管理を行っている。
 ◦ version を切ると、GitHub Actions によって chart を S3 に upload。
 ◦ semantic versioning により、chart の新機能を特定の cluster 内に先行して導入でき る。
 
 

  42.   42 (方針1) 既存の chart の version を上げる
 • chart

    内の template で、Argo Rollouts を 使うかどうかに応じて kind を書き換える。 (spec.strategy も同様)
 
 
 
 # <chart_name>/templates/deployment.yaml {{- if .Values.argoRollouts.canary.enabled }} apiVersion: argoproj.io/v1alpha1 kind: Rollout {{- else -}} apiVersion: apps/v1 kind: Deployment {{- end }} # <chart_name>/values.yaml argoRollouts: canary: enabled: false # defaultでは無効 v1.2.2
 v1.2.3
 v1.3.0
 common chart A

  43.   43 (方針2) 別 chart として作成する
 
 
 • kind:

    Rollout 用に書き換え済みの <chart_name>-canary として新規に chart を作成する。
 
 
 
 v1.2.2
 v1.2.3
 common chart A
 v1.0.0
 common chart A-canary
 # <chart_name>-canary/templates/deployment.yaml apiVersion: argoproj.io/v1alpha1 kind: Rollout
  44.   44 方針の比較
 • 既存の chart の version を上げる。
 ◦

    pros
 ▪ 従来の chart version 管理に沿っている。
 ▪ chart の修正が deployment, rollout どちらに対しても反映される。
 ◦ cons
 ▪ chart の中身が rollout を知らない開発者にとって混乱を招く。
 • <chart_name>-canary のような別 chart として作成する。
 ◦ pros
 ▪ 用途によって chart を使い分ければ良いことが明確になる。
 ◦ cons
 ▪ 双方の chart に共通した修正を入れる場合に面倒。
 • どちらかに修正を入れ忘れる、ということがありそう。
 
 

  45.   45 方針の比較
 • 既存の chart の version を上げる。
 ◦

    pros
 ▪ 従来の chart version 管理に沿っている。
 ▪ chart の修正が deployment, rollout どちらに対しても反映される。
 ◦ cons
 ▪ chart の中身が rollout を知らない開発者にとって混乱を招く。
 • <chart_name>-canary のような別 chart として作成する。
 ◦ pros
 ▪ 用途によって chart を使い分ければ良いことが明確になる。
 ◦ cons
 ▪ 双方の chart に共通した修正を入れる場合に面倒。
 • どちらかに修正を入れ忘れる、ということがありそう。
 
 

  46.   46 CRD のインストール
 
 
 • kind: Rollout 用に書き換えた

    common chart を使 う前に、CRD のインストールが必要。
 • 公式 Helm Chart 経由で、common chart 外でイ ンストールしておく。
 ◦ system 系 の helmfile の一部として管理。
 
 
 
 
 # argo-rollouts/helmfile.yaml repositories: - name: argo url: https://argoproj.github.io/argo-helm releases: - name: argo-rollouts namespace: argo-rollouts forceNamespace: argo-rollouts chart: argo/argo-rollouts version: 2.3.0 wait: true timeout: 7200
  47.   47 導入作業
 • kind: Rollout をコードベースで利用可能にする
 • RBAC の追加


    • stable/canary ごとの bug や metrics の出し分け設定
 
 
 
 

  48.   48 RBAC 追加
 • Argo CD の UI から

    canary を進めるため。
 • argo-cd-config に Argo Rollouts 向けの policy を追加する。
 ◦ ※ 検証中なので一旦 * 指定
 
 
 
 
 apiVersion: v1 kind: ConfigMap metadata: name: argocd-rbac-cm namespace: argocd data: policy.default: role:readonly policy.csv: | p, role:org-admin, applications, *, */*, allow p, role:org-admin, applications, action/argoproj.io/Rollout/*, */*, allow p, role:org-admin, clusters, get, *, allow p, role:org-admin, repositories, get, *, allow p, role:org-admin, repositories, create, *, allow p, role:org-admin, repositories, update, *, allow p, role:org-admin, repositories, delete, *, allow g, your-github-org:your-team, role:org-admin
  49.   49 stable/canary ごとの bug や metrics の出し分け
 • Ephemeral

    Metadata をもとに出し分けが可能。
 ◦ pod の metadata に (stable|canary)Metadata の値が入る。
 ◦ canary release の進行に合わせて、 canary => stable に書き換わる。
 
 
 
 # kind: Pod labels: app: helm-guestbook release: helm-argo-rollouts-example role: canary rollouts-pod-template-hash: cb5c9b94b labels: app: helm-guestbook release: helm-argo-rollouts-example role: stable rollouts-pod-template-hash: cb5c9b94b # kind: Rollout strategy: canary: stableMetadata: labels: role: stable canaryMetadata: labels: role: canary
  50.   50 metrics, log への対応
 • Datadog を利用。
 ◦ 公式

    Helm Chart を使って設定を管理。
 • Helm Chart の podLabelsAsTags に role label を設定する。
 ◦ Datadog で canary デプロイメントの状態を監視する 
 
 
 
 
 podLabelsAsTags: role: kube_role
  51.   51 error monitoring への対応
 • bugsnag を利用。
 • role

    label を環境変数に渡して、bugsnag 上の stage として canary を識 別させる。
 ◦ canary release 完了後に restart する必要あり。
 
 
 
 
 # kind: Rollout containers - env: - name: RELEASE_STAGE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.labels['role'] # ruby config.release_stage = ENV['RELEASE_STAGE'] == 'canary' ? 'canary' : ENV['RAILS_ENV']
  52.   52 要検証な課題
 • sticky session の実装
 • envoy proxy

    の設定変更
 • kind: AppProject レベルで canary を進められるか
 • canary をスキップしてデプロイしたい場合の対応
 
 
 
 

  53.   53 (不要) sticky session の実装
 • Nginx Ingress controller

    や Istio 上での実現方法を検討していたが、実装が不要と なった。
 • 影響範囲を狭くするため という sticky session 導入の目的が、高速でロールバック が行えることで達成できると判断したから。
 ◦ Argo Rollouts のロールバック ( canary abort) は即座に canary pod が terminating になる = ユーザー影響を与えなくなるため十分早い。
 
 
 

  54.   54 envoy proxy の設定変更
 • sticky session が必須でなくなったため、traffic 管理の設定を追加する必要ない認識

    ではあるが、要検証。
 
 
 

  55.   55 kind: AppProject レベルで canary を進められるか
 • kind: AppProject

    内にある全ての rollout の操作を一括で進めたい
 ◦ 特定の rollout だけタイミングをずらす事はまずない。
 • 用意されている UI 的に rollout の数ぶんポチポチは避けられない...?
 ◦ Argo CD 2.1 で可能性を探る!
 
 
 
 
 まとめて promote させたい まとめて promote させたい
  56.   56 kind: AppProject レベルで canary を進められるか
 • staragety.canary.steps.pause を指定すれば、promte

    は自動で進むから楽かも。
 ◦ abort する場合だけ UI 操作が発生する。
 
 
 strategy: steps: - setWeight: 10 - pause: { duration: 30m } - setWeight: 50 - pause: { duration: 10m }
  57.   57 canary をスキップしてデプロイしたい場合の対応
 • 急ぎの場合、hotfix など。
 • strategy.canary.steps が

    1 段階 ( 1:9 => 10:0 ) なら watch せずに即 promote-full すれば良さそう。
 ◦ 多段に設定する必要が出てきた場合を想定して、sync 後に自動で promote-full す る仕組みを用意しておきたい。
 
 
 
 

  58.   58 canary をスキップしてデプロイしたい場合の対応
 • staragety.canary.steps.pause をとても短く設定すれば、一気にリ リースできそう。
 ◦ common

    chart に skipCanary=true を指定すると こう書き換えてくれる オプションを付ける。
 
 
 
 strategy: steps: - setWeight: 10 - pause: { duration: 1s } - setWeight: 50 - pause: { duration: 1s } strategy: steps: - setWeight: 10 - pause: { duration: 30m } - setWeight: 50 - pause: { duration: 10m }
  59.   まとめ


  60.   60 まとめ
 • 内製ツールから Argo CD への移行により、Kuberentes 環境のデプロイがより簡単 &

    高速 & セキュアになった。
 • 繁忙期でも安心してデプロイできるように canary release 導入に向けて、Argo Rollouts を検証中。
 • 本番環境での運用の前にクリアすべき課題は少なくないが、徹底したコード管理を行 いつつ手法を探る。
 
 
 
 

  61.   61 失敗して攻めよう
 学びのある失敗をして最速で成長しよう。学 びのある失敗とはチームやプロダクトの成長 につながる失敗。学びのある失敗をしていな いのは挑戦が足りない。


  62.   Job Board 載せてます!!


  63. スモールビジネスを、世界の主役に。