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

Railsメジャーバージョンアップを 安全にカナリアリリースする

uuushiro
December 17, 2021

Railsメジャーバージョンアップを 安全にカナリアリリースする

銀座Rails#40 登壇資料

最近、弊社のRailsアプリケーションをv5.1からv6.1へメジャーバージョンアップしました。メジャーバージョンアップは大きな変更ですが、カナリアリリースにより安全にリリースすることができました。この発表では、Railsアプリケーションの各種プロセス(puma, sidekiq, delayed_job, cronなど)をカナリアリリースする際のチップス、及びバージョンアップする際に問題となった箇所について共有します。

uuushiro

December 17, 2021
Tweet

More Decks by uuushiro

Other Decks in Technology

Transcript

  1. Railsメジャーバージョンアップを 安全にカナリアリリースする

  2. ⾃⼰紹介 2 松⾕ 勇史朗 株式会社スタメン CTO 愛知県出⾝ 2018年: 銀座Rails#1に登壇

  3. 3 事業紹介 Our Business 2つのエンゲージメント事業 この2つのRailsアプリケーションの メジャーバージョンアップを実施しました。 SaaSモデルの "社内制度運用クラウド" と

    "組織コンサルティング" をワンストップサービスで提 供し、顧客企業の組織課題に貢献するプラットフォーム事業です。 エンゲージメント経営プラットフォーム TUNAG コミュニティ運営に必要な機能をワンストップで提供し、コミュニティのエンゲージメント向上 と収益化を支援するプラットフォーム事業です。 オンラインサロンプラットフォーム FANTS
  4. FANTS - オンラインサロンプラットフォーム オンラインサロンを開設・運営するためのプラットフォーム。SNS + サブスク をアプリで。 2つ⽬の事業として2020年5⽉にリリース。コロナ禍でのコミュニティ運営や収益化を⽀援。

  5. FANTS - 主なオンラインサロン プロスポーツチーム、アイドルユニット、タレントや著名⼈、レジャー施設、YouTuber、 協同組合、スクールや習い事など、幅広いカテゴリーでオンライサロン展開が拡⼤中。

  6. None
  7. Railsメジャーバージョンアップを 安全にカナリアリリースする

  8. ㊗Rails7🎉 (今⽇は5.1 から 6.1へ上げた話です🙏)

  9. • 各種プロセスのカナリアリリース ◦ puma ◦ sidekiq ◦ delayed_job ◦ cron

    • 発⽣した課題 ◦ カナリアリリース中のデプロイ ◦ Aurora MySQLのクエリキャッシュ ◦ rackの挙動変更 ◦ CSRFトークンが異なる アジェンダ 最近、弊社のRailsアプリケーションをv5.1からv6.1へメジャーバージョンアップしました。 メジャーバージョンアップは⼤きな変更ですが、カナリアリリースにより安全にリリースすることができ ました。⼯夫した点について共有します。
  10. 各種プロセスの カナリアリリース⽅法

  11. 前提 • EC2インスタンス上で動いていたRailsアプリケーションを、ECS上のDockerコンテナへ移⾏ • capistranoによるデプロイから、ECSのローリングアップデート・Blue/Greenデプロイメン ト⽅式へ移⾏ 今回は、Railsバージョンアップだけではなく、同時に以下のような変更を⾏いました。 コンテナ化と同時に実施した理由は。。。 ⻑い間Railsバージョンアップしておらず、メジャーバージョンはじめ多くの更新が溜まっ ており、⼿動で確認が必要な部分が少なくなかった。

    もともとコンテナ移⾏プロジェクトを進めており、どうせ⼿動でアプリケーション全体を 確認するなら同時にやってしまいたかった
  12. カナリアリリースについて 並⾏稼働は⼀ヶ⽉ほど、以下のような形式で⾏いました。 通常のユーザーへ影響を出すこ と無く、社内ユーザーのリクエ スト(IPアドレス判定)から発生し た処理のみを検証の対象にした

  13. pumaのカナリアリリース Pumaへのリクエスト振り分けは、Application Load Balancerのリスナールールで⾏いました。 • 確認の最初期は、HTTPヘッダーに特定の⽂字列が含まれている場合のみ、 6.1環境へ振り分ける(開発者限定) • 2週間ほど、⾃社のオフィスのIPからきたリクエストのみ6.1環境へ振り分け る(社員限定)

  14. sidekiqのカナリアリリース ジョブの発⾏元となるpumaのリクエストが社内のユーザーである場合のみ、6.1環境で動くように • ジョブの受け渡しにredisを利⽤しており、6.1環境⽤のRedisを新規で⽤意する • 6.1環境では、ジョブを登録する側(Puma)とジョブを実⾏する側(sidekiq)も、新規 に設置したredisを参照する

  15. delayed_jobのカナリアリリース ジョブの発⾏元となるpumaのリクエストが社内のユーザーである場合のみ、新環境での動くように • delayed_jobはテーブルにJobが作成される • 6.1環境⽤のテーブルを新規で⽤意する • Delayed::Backend::ActiveRecord::Job.table_nameを置き換え、6.1環境と 5.1環境で別のテーブルをジョブキューとして使⽤する

  16. cronのカナリアリリース cronの処理は重複して実⾏することが出来ないものが多く、⼀つのジョブが処理する範囲がユーザー単位で はないため、完全な並⾏稼働は出来ませんでした。重複して実⾏しても問題ない⼀部の処理のみ、両環境で 並⾏稼働して挙動を確認しています。 • OSのcronから ECS Scheduled Tasks へ移⾏

    • いままで利⽤していたwhenever gemの設定ファイル を流⽤できる、elastic_wheneverを利⽤しています
  17. elastic_whenever gem について余談 • elastic_wheneverはCloudwatch EventsからECSのタスクを起動しますが、 ECSのCapacity ProviderにASGProviderを指定しているにもかかわらず、タス クがPendingにならず、無⾔で起動を諦めてしまうという問題に遭遇しました 。

    • こちらはAWSのサポートの⽅に相談しても原因がつかめず、Step Functions 経由でリトライしてみたらどうか、というアドバイスを頂いたため、Step Functionsを呼び出すように、elastic_wheneverを改造しています。 • Step Functions経由で呼び出すと、ちゃんとクラスタのオートスケールを待っ てタスクが起動するため、結局リトライ⾃体は⼊れませんでしたが、各タスク 起動前後に共通の処理を割り込ませたりもできるため、Step Functions経由に したのは正解だったと思います。
  18. 発⽣した課題

  19. カナリアリリース中のデプロイ運⽤ルール • 5.1環境に新コードがデプロイされた際は、その新コードを6.1環境にもマージし、テストし てからデプロイする必要があるため、並⾏稼動中の新環境に適⽤できるまでタイムラグが発 ⽣し、実⾏される処理に差が⽣まれ危険です。 • そのため、現⾏の5.1をリリースした場合はALBから新環境にリクエストを流すのを⾃動的 に停⽌し、新環境の6.1が現環境の5.1に追いついてから、リクエストの振り分けを再開する ようにしました。 •

    マージ作業をリリースの毎に実施するのは⾯倒なので、並⾏稼働期間中の⼣⽅以降はリリー スを禁⽌し、その間に6.1環境へのマージ作業とデプロイを⾏う運⽤としました。 ❌ 旧環境へのデプロイを トリガーに新環境への 振り分けを停止 弊社は普段デプロイを⽇に数回実施しており、カナリアリリース中もデプロイを実施したい
  20. Aurora MySQLのクエリキャッシュ MySQLのクエリキャッシュが有効な状態で、 Rails 5.1のアプリケーションと、Rails 6.1のア プリケーションからAurora MySQLへ全く同じ SQLを実⾏すると、クエリキャッシュが原因で エラーが発⽣します。

    mysql2 gemの右issueで報告されているうちの いくつかと同じ問題ですが、最終的には、カナ リアリリース中のみ、パフォーマンスに問題が 出ないのを確認した上で、Aurora MySQLの query_cache_sizeを0としました。 本番リリース後はquery_cache_sizeをもとに戻 しました。
  21. 新バージョンのrackのセッションの後⽅互換性がない • Rails5.1から6.1へのアップデートの際に、rack gem が 2.0.8 以上に変更されます • rack(2.0.8)でセッションハイジャック対策の変更が⼊り、セッションストアにsessionを持つ 際のkeyが変更されました

    • redis-rack では、新環境のrackで作成されたsessionから旧環境のバージョンの rack で⽣成し たセッションデータを取得することはできるフォールバックが提供されているが、逆はできな い。 • 本番リリース後に旧環境に切り戻しをする場合、新環境で⽣成されたセッションが無効になっ てしまう問題がある。 • カナリアリリース時にはrackのバージョンを固定 参考: https://qiita.com/daido1976/items/7a6f4a304d661d98a11b
  22. CSRFトークンの後⽅互換性が無い • Rails 6.1から、CSRFトークンのエンコードが変更 されました。 • Upgrade-safe URL-safe CSRF tokensによって、

    6.0以前のCSRFトークンを持ったユーザーが、6.1 環境へPOSTしてもエラーとはならないのですが、 6.1以降のCSRFトークンを持ったユーザーが6.0以 前の環境へPOSTすると、CSRF検証に失敗します 。 • 同じユーザーからのリクエストがバージョンの異 なる新・旧環境に分散するカナリアリリースでは ⼤きな問題となります。 • 今回は、同じユーザーであれば基本的に同じバー ジョンのサーバーでリクエストが処理されるため 、回避できました。(ただし切り戻しをした場合に 問題となる)
  23. まとめ • カナリアリリース期間中に発⾒されたアプ リケーションの問題はほとんどありません でした。 • ただ、カナリアリリースすることで、アプ リケーションのproduction環境での挙動や 、最終的な切り替えの⼿順、切り戻しの⼿ 順をはっきり把握でき、安⼼・安全のリリ

    ースが⾏えたのは良かったです。 • Rails7バージョンアップも安全にリリース するぞ🔥 • ちなみに今回の発表内容のブログも書いて います👉 ◦ https://tech.stmn.co.jp/entry/2021/11/08/144233
  24. 名古屋 + 鎌倉 + リモート さらなる規模拡⼤&エンジニア採⽤を⽬指し、鎌倉とリモートでの採⽤を開始。 ・名古屋オフィスは、2022年3⽉に移転予定 → コロナな時代であっても、出社する価値のあるオフィスや仲間たちを作る ・鎌倉オフィスは、鎌倉駅徒歩1分の好⽴地

    → ⾃然と⽂化を感じながら⽣産⾼を意識して働く場所を作りたい ・フルリモートでの採⽤ → エンジニアを居住地を限定せずに集めたい(現在ベルギーからリモートが1⼈)
  25. Railsエンジニア絶賛採⽤中です︕ Rails, React/Next.js, Swift/Kotlin, デザイナー, PdM、マネージャーを採⽤中。 エンジニア採⽤サイトにて、メンバーインタビュー、 カルチャーや技術について、エンジニアブログなどを紹介しています。