Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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 スポンサー枠登壇資料)

Hayato Okuma

November 05, 2021
Tweet

More Decks by Hayato Okuma

Other Decks in Programming

Transcript

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

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


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

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

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

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

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

  5.   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 コンセプト発 表 マイクロサー ビス化 開始 基盤投資 加速 プラット フォーム 元年 新規 プロダクト加 速
  6.   10 CI/CD の標準化を進めたい
 • 既存のプロダクトのマイクロサービス化や新規プロダクトの爆速リリースによって、多く の Kubernetes cluster が生まれた。


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

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

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

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

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

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

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

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

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

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


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

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

  13.   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

  14.   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
  15.   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: {}
  16.   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 を出して、そこでコマンド実 行していた。
 
 
 
 

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


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

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

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

  19.   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 があれば、問題ないか確認する。
 
 
 
 

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

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

  21.   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レビューが可能に!
 
 
 
 

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


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

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

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

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

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


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

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


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

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


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

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

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

  29.   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 台の状態に戻 す。
 
 
 
 

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


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

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

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

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

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

  33.   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

  34.   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
  35.   44 方針の比較
 • 既存の chart の version を上げる。
 ◦

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

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

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

  37.   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
  38.   47 導入作業
 • kind: Rollout をコードベースで利用可能にする
 • RBAC の追加


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

  39.   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
  40.   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
  41.   50 metrics, log への対応
 • Datadog を利用。
 ◦ 公式

    Helm Chart を使って設定を管理。
 • Helm Chart の podLabelsAsTags に role label を設定する。
 ◦ Datadog で canary デプロイメントの状態を監視する 
 
 
 
 
 podLabelsAsTags: role: kube_role
  42.   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']
  43.   52 要検証な課題
 • sticky session の実装
 • envoy proxy

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

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

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

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

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

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

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

  48.   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 }
  49.   60 まとめ
 • 内製ツールから Argo CD への移行により、Kuberentes 環境のデプロイがより簡単 &

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