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

Canary release in StudySapuri

Canary release in StudySapuri

スタディサプリ/Quipper Product Meetup #3 発表資料

https://techplay.jp/event/737389

Fb1b9f3d7332a7a7e262b70013b5f7dd?s=128

Fumiaki MATSUSHIMA

July 18, 2019
Tweet

Transcript

  1. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 @mtsmfm

    Fumiaki Matsushima スタディサプリ/Quipper Product Meetup #3
  2. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 2 ➔ Web Dev at

    Quipper ◆ 主に学校向け機能の開発 ➔ Ruby と麻雀と DbD が好き ➔ 西日暮里.rb 主催 @mtsmfm.inspect
  3. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 Agenda | 01 02 03

    小中高におけるデプロイの流れ Canary release まとめ 3
  4. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 小中高におけるデプロイの流れ 01 4

  5. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 5 https://github.com/quipper/handbook/blob/aebe98243526b38ccbd6d488052d13e368f0a794/company-profile-ja.md

  6. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 Git flow で monorepo 上で開発

    6 https://quipper.hatenablog.com/entry/2019/04/02/quipper-web-git-flow-on-monorepo
  7. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 k8s namespace 7 Service Router

    (NGINX) student-api Server student-frontend Server User
  8. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 ディレクトリごと別サービス student-api student-frontend school-api school-frontend

    8
  9. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 各ディレクトリに k8s 関連ファイルがある student-api Dockerfile

    kubernetes kustomization.yaml deployment.yaml overlays production kustomization.yaml develop ... 9
  10. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 overlays - kustomize による環境毎の差分管理 10

    https://github.com/kubernetes-sigs/kustomize/blob/30b378a9244d757c1cda31b95694fabd6cbdb8e1/docs/images/overlay.jpg
  11. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 Build と Deploy は CircleCI

    から .circleci config.yml build.sh deploy.sh 11
  12. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 Deploy Test and Build student-api

    12 docker build docker push test student-frontend docker build docker push student-api test kustomize build kubectl apply student-frontend kustomize build kubectl apply
  13. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 13

  14. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 Canary release 02 14

  15. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 Canary release とは “Canary release

    is a technique to reduce the risk of introducing a new software version in production by slowly rolling out the change to a small subset of users before rolling it out to the entire infrastructure and making it available to everybody.” 15 https://martinfowler.com/bliki/CanaryRelease.html
  16. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 Canary release とは 新しいバージョンを全体公開する前に、一部のユーザへ先に出すことでリスクを 減らす手法

    16
  17. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 Feature Toggles 17 https://speakerdeck.com/ujihisa/almost-microservices?slide=60 @ujihisa

    "雑" / Almost Microservices Rails DM 2019
  18. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 k8s namespace 18 student-api Server

    User if enable_new_feature?(user) new_logic else old_logic end Service Router Feature Toggles
  19. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 k8s namespace 19 Service Router

    student-api Server student-api-new Server User Canary release if canary_release?(user) new_host else old_host end
  20. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 Canary release と Feature toggles

    20 ➔ Canary release ◆ プロセスごと分離するため、用いるライブラリのバージョンを変えられる ◆ プロセスを2系統上げておかないといけない ➔ Feature toggles ◆ プロセス内で分岐するため導入しやすい ◆ ライブラリのバージョンは変えられない
  21. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 やらないといけないこと ➔ 新旧フレームワークでテストを回して開発が止まらないようにする ◆ 簡単にフレームワークのバージョンが切り替えられるようにする

    ➔ 新旧フレームワーク両方デプロイされるようにする ➔ 割り振るルールを決める ➔ エラー監視 21
  22. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 やらないといけないこと ➔ 新旧フレームワークでテストを回して開発が止まらないようにする ◆ 簡単にフレームワークのバージョンが切り替えられるようにする

    ➔ 新旧フレームワーク両方デプロイされるようにする ➔ 割り振るルールを決める ➔ エラー監視 22
  23. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 新旧フレームワークでテストを回して開発が止まらないように する ➔ アップグレードに関わっている人よりそうでない人の方が多い ➔

    開発を停止するわけにはいかない ◆ 全員に両方でテストが通るコードを書いてもらう ➔ 依存する社内 gem も2系統で回す 23
  24. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 2種類のライブラリバージョン管理ファイルを持つ student-api Gemfile Gemfile.lock gemfiles

    new-version Gemfile Gemfile.lock 24
  25. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 2種類のライブラリバージョン管理ファイルを持つ student-api Gemfile Gemfile.lock gemfiles

    new-version Gemfile Gemfile.lock 25 元の Gemfile を引き継ぐ 方法は懇親会で!
  26. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 やらないといけないこと ➔ 新旧フレームワークでテストを回して開発が止まらないようにする ◆ 簡単にフレームワークのバージョンが切り替えられるようにする

    ➔ 新旧フレームワーク両方デプロイされるようにする ➔ 割り振るルールを決める ➔ エラー監視 26
  27. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 簡単にフレームワークのバージョンが切り替えられるように する ➔ 2種類のライブラリバージョン管理ファイルを持つ ◆

    Ruby で使われるパッケージ管理ツール (Bundler) の場合環境変数1 つで変えられるので便利 • BUNDLE_GEMFILE ➔ Dockerfile 上では ARG で差し替えられるようにしておく 27
  28. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 やらないといけないこと ➔ 新旧フレームワークでテストを回して開発が止まらないようにする ◆ 簡単にフレームワークのバージョンが切り替えられるようにする

    ➔ 新旧フレームワーク両方デプロイされるようにする ➔ 割り振るルールを決める ➔ エラー監視 28
  29. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 新旧フレームワーク両方デプロイされるようにする ➔ 既に Monorepo にしつつ各ディレクトリ

    == サービス ◆ シンボリックリンク + build arg や overlay のカスタマイズ • これにより各ディレクトリ == サービスの延長で考えられるので build、deploy スクリプトに大きく手を入れる必要がない 29
  30. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 シンボリックリンクで楽をする student-api Dockerfile kubernetes overlays

    production student-api-new kustomization.yaml student-api-new 30
  31. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 やらないといけないこと ➔ 新旧フレームワークでテストを回して開発が止まらないようにする ◆ 簡単にフレームワークのバージョンが切り替えられるようにする

    ➔ 新旧フレームワーク両方デプロイされるようにする ➔ 割り振るルールを決める ➔ エラー監視 31
  32. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 割り振るルールを決める ➔ 同じユーザには同じ挙動をしないと問い合わせ対応や再現確認が大変 ➔ ログインしていないユーザもいるかもしれない

    ➔ 一度新しいバージョンが使われたら戻ってほしくない ➔ 初回アクセス時に Cookie に canary release 用 id を振る ➔ 環境変数で Canary release の割合を制御 32
  33. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 k8s namespace 33 student-api Server

    User Cookie id = 0.0 ~ 1.0 Version = id < Ratio ? new : old Ratio = X Service Router (NGINX)
  34. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 k8s namespace 34 student-api Server

    User Cookie id = 0.3 Version = old Ratio = 0 Service Router (NGINX)
  35. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 k8s namespace 35 student-api Server

    User Cookie Ratio = 0.2 id = 0.3 Version = old Service Router (NGINX)
  36. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 k8s namespace 36 student-api Server

    User Cookie Ratio = 0.5 id = 0.3 Version = new id < Ratio になったので バージョン切り替え用の Cookie も付与 Service Router (NGINX)
  37. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 k8s namespace 37 student-api Server

    student-api-new Server User Cookie Version == new バージョン切り替え用の Cookie だけ見て Host 切り替え Service Router (NGINX)
  38. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 移行 ➔ 0 -> 0.1

    -> 1 -> 10 -> 50 -> 100 ◆ ロジックミスっていないかの確認のため 0 は挟んだほうがいい ◆ 念の為 curl で数百回回すスクリプト書いて確率通りか見る ◆ 一週間に1段階上げていた 38
  39. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 やらないといけないこと ➔ 新旧フレームワークでテストを回して開発が止まらないようにする ◆ 簡単にフレームワークのバージョンが切り替えられるようにする

    ➔ 新旧フレームワーク両方デプロイされるようにする ➔ 割り振るルールを決める ➔ エラー監視 39
  40. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 エラー監視 ➔ Sentry にフレームワークのバージョンをタグとして付与、そのタグがついて いる場合のエラー通知先を分離

    ◆ 普段は Slack の #exception-<service 名> 部屋に通知 ◆ 移行期間だけ #upgrade-rails 部屋に通知 ➔ タグがついていない場合も同じエラーが起きたことがあるか一通りチェック 40
  41. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 準備はできた いざ Canary release 41

  42. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 何が起きたか ➔ 本番でフレームワークのバージョン起因の問題は何も起きなかった ◆ ステージングは

    Canary release の割合を高めていた (最初から50%) のでエラーを拾って対処できた ◆ 自動テストがしっかりしていた ◆ 簡単に後戻りできる安心感があった ➔ 一度実験していると今後も使える ◆ フレームワークのバージョンは上げ続ける必要がある 42
  43. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 改善点 ➔ 段階を進めるのを週次リリースに合わせていたが時間かかりすぎ ◆ 全部で2ヶ月くらい

    ◆ 1日1段階、100%にするのに1週間くらいがいい? ➔ 新エラーの判別を楽したい ◆ 最後の方は全エラーの半分を背負うことになる 43
  44. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 まとめ 03 44

  45. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略 まとめ ➔ 新しいサービスを簡単に足せるようにさえなっていれば、Canary release は

    単純な実装で実現できる ◆ Monorepo だとサービスを足しやすかった ◆ その分 CI 周りは複雑になる ➔ 足回りの整備が進んでいることで Web Dev としても可能性が広がる ◆ SRE Dev ➔ アップグレードとの戦いはサービスが続く限り続く 45