$30 off During Our Annual Pro Sale. View Details »

Canary release in StudySapuri

Canary release in StudySapuri

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

https://techplay.jp/event/737389

Fumiaki MATSUSHIMA

July 18, 2019
Tweet

More Decks by Fumiaki MATSUSHIMA

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  7. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    k8s namespace
    7
    Service Router
    (NGINX)
    student-api
    Server
    student-frontend
    Server
    User

    View Slide

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

    View Slide

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

    View Slide

  10. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    overlays - kustomize による環境毎の差分管理
    10
    https://github.com/kubernetes-sigs/kustomize/blob/30b378a9244d757c1cda31b95694fabd6cbdb8e1/docs/images/overlay.jpg

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  16. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    Canary release とは
    新しいバージョンを全体公開する前に、一部のユーザへ先に出すことでリスクを
    減らす手法
    16

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  20. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    Canary release と Feature toggles
    20
    ➔ Canary release
    ◆ プロセスごと分離するため、用いるライブラリのバージョンを変えられる
    ◆ プロセスを2系統上げておかないといけない
    ➔ Feature toggles
    ◆ プロセス内で分岐するため導入しやすい
    ◆ ライブラリのバージョンは変えられない

    View Slide

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

    View Slide

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

    View Slide

  23. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    新旧フレームワークでテストを回して開発が止まらないように
    する
    ➔ アップグレードに関わっている人よりそうでない人の方が多い
    ➔ 開発を停止するわけにはいかない
    ◆ 全員に両方でテストが通るコードを書いてもらう
    ➔ 依存する社内 gem も2系統で回す
    23

    View Slide

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

    View Slide

  25. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    2種類のライブラリバージョン管理ファイルを持つ
    student-api
    Gemfile
    Gemfile.lock
    gemfiles
    new-version
    Gemfile
    Gemfile.lock
    25
    元の Gemfile を引き継ぐ
    方法は懇親会で!

    View Slide

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

    View Slide

  27. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    簡単にフレームワークのバージョンが切り替えられるように
    する
    ➔ 2種類のライブラリバージョン管理ファイルを持つ
    ◆ Ruby で使われるパッケージ管理ツール (Bundler) の場合環境変数1
    つで変えられるので便利
    ● BUNDLE_GEMFILE
    ➔ Dockerfile 上では ARG で差し替えられるようにしておく
    27

    View Slide

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

    View Slide

  29. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    新旧フレームワーク両方デプロイされるようにする
    ➔ 既に Monorepo にしつつ各ディレクトリ == サービス
    ◆ シンボリックリンク + build arg や overlay のカスタマイズ
    ● これにより各ディレクトリ == サービスの延長で考えられるので
    build、deploy スクリプトに大きく手を入れる必要がない
    29

    View Slide

  30. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    シンボリックリンクで楽をする
    student-api
    Dockerfile
    kubernetes
    overlays
    production
    student-api-new
    kustomization.yaml
    student-api-new
    30

    View Slide

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

    View Slide

  32. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    割り振るルールを決める
    ➔ 同じユーザには同じ挙動をしないと問い合わせ対応や再現確認が大変
    ➔ ログインしていないユーザもいるかもしれない
    ➔ 一度新しいバージョンが使われたら戻ってほしくない
    ➔ 初回アクセス時に Cookie に canary release 用 id を振る
    ➔ 環境変数で Canary release の割合を制御
    32

    View Slide

  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)

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

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

    View Slide

  38. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    移行
    ➔ 0 -> 0.1 -> 1 -> 10 -> 50 -> 100
    ◆ ロジックミスっていないかの確認のため 0 は挟んだほうがいい
    ◆ 念の為 curl で数百回回すスクリプト書いて確率通りか見る
    ◆ 一週間に1段階上げていた
    38

    View Slide

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

    View Slide

  40. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    エラー監視
    ➔ Sentry にフレームワークのバージョンをタグとして付与、そのタグがついて
    いる場合のエラー通知先を分離
    ◆ 普段は Slack の #exception- 部屋に通知
    ◆ 移行期間だけ #upgrade-rails 部屋に通知
    ➔ タグがついていない場合も同じエラーが起きたことがあるか一通りチェック
    40

    View Slide

  41. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    準備はできた
    いざ Canary release
    41

    View Slide

  42. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    何が起きたか
    ➔ 本番でフレームワークのバージョン起因の問題は何も起きなかった
    ◆ ステージングは Canary release の割合を高めていた (最初から50%)
    のでエラーを拾って対処できた
    ◆ 自動テストがしっかりしていた
    ◆ 簡単に後戻りできる安心感があった
    ➔ 一度実験していると今後も使える
    ◆ フレームワークのバージョンは上げ続ける必要がある
    42

    View Slide

  43. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    改善点
    ➔ 段階を進めるのを週次リリースに合わせていたが時間かかりすぎ
    ◆ 全部で2ヶ月くらい
    ◆ 1日1段階、100%にするのに1週間くらいがいい?
    ➔ 新エラーの判別を楽したい
    ◆ 最後の方は全エラーの半分を背負うことになる
    43

    View Slide

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

    View Slide

  45. #sapurimeetup Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略
    まとめ
    ➔ 新しいサービスを簡単に足せるようにさえなっていれば、Canary release は
    単純な実装で実現できる
    ◆ Monorepo だとサービスを足しやすかった
    ◆ その分 CI 周りは複雑になる
    ➔ 足回りの整備が進んでいることで Web Dev としても可能性が広がる
    ◆ SRE Dev
    ➔ アップグレードとの戦いはサービスが続く限り続く
    45

    View Slide