noteがEKSへの完全移行までにやったこと
noteのEKS移行が完了しました。EKSへ移行するにあたって、サービスのアーキテクチャからデプロイ環境、監視体制、運用までを全て見直しインフラをモダンな環境にすることができました。
EKSへ移行するにあたり、様々な問題や課題がありました。
活用できていないログや破れ窓化したアラートをどう整備するか
どのようにアプリケーションの負荷試験を実施し、ボトルネックを探るか
CloudFrontを利用したゼロダウンタイムでEKSへの切り替え
大量に存在しているバッチをどのように移行していくか
今回はEKS移行の際に起きたトラブルやそれらを解決したときのTipsなどを、SREチームの2人にお聞きしました。
インタビュイー
中村 昴:
株式会社ドリコムにて、ソーシャルゲームタイトルのAWSインフラを担当。2020年9月よりnote株式会社に入社し、現在はSREとしてnoteのインフラ周りの改善を行っている。
君島 航平:
toB向けのサービス開発にて、フロントエンド、バックエンド、インフラを担当するフルスタックエンジニアとしての経験を積み、2021年9月にnoteに入社。現在はSREチームに所属。創作活動として、音楽、イラスト、ゲームなどを制作するクリエイターの一面も持つ。
EKS移行だけが目的じゃない。インフラを全面的に刷新
— まずは、EKSに移行した理由を教えてください
中村:
実は、4年ほど前からEKSへの移行検討は始まっていました。noteはEC2上でRuby on Railsを実行するモノリシックなアプリケーションで、コンテナへ移行することは前々から議論には上がっていました。
実際に移行作業を始めたのは2年ほど前からです。社内サービスをEKSに移行するテストを実施→検証環境の用意→一部機能を本番に移して……と徐々にステップを踏んでいきました。
▲移行のさらに詳しい理由はこちらの記事をご覧ください
君島:
今回はEKS移行が主軸ではあるのですが、監視やログ、デプロイワークフローなどのインフラの全体的な改善も行いました。noteの稼働環境をコンテナ化するだけではなく、レガシーなインフラ環境を一新することが目的です。様々な負債が解消される見通しがあったのも、EKS移行に至った理由の1つですね。
中村:
移行前にインフラ構成を1つ1つ見直していく段階で、「そもそもEKS移行する前にやるべきことがたくさんあるよね」という結論になりました。今回の移行に2年ほどかかってしまったのは、環境整備を同時並行で進めていたからですね。
— EKSに移行したメリットだけではなく、EKSを含めてインフラを全体的に刷新したメリットが大きい?
中村:
そうですね、インフラ全体を見直して改善したことで運用はかなりしやすくなりました。
— 他にも移行するに至った理由はなにかありますか?
君島:
EKS移行に踏み込めた大きな理由として、SREチームにEKSの運用経験者が複数いたこともあげられます。経験者の知見でメリット・デメリットが明確だったので、運用フェーズの準備もしやすい状態でした。
— EKS環境での設計はどのような意図で行なったのでしょうか?
君島:
もともとあったfrontendとbackendに加えて、非同期処理などの環境を分けるだけのシンプルな構成にしました。まずはEC2の構成を素直にEKSのnamespaceにマッピングし、既存のエンジニアでも理解がしやすいように設計しました。
中村:
大きく変わっている部分としてはネットワーク構成ですね。適正でなかった部分を見直しました。
— 負債解消に関して特に力を入れた点はありますか?
君島:
ログや監視の改善には注力しました。Datadogなどのアラートの整備も取り組み、SREチームで管理や対応がしやすい状態になっています。
中村:
アラート周りはだいぶ改善しましたね、トラブルが起きたときにすぐに対応できるようになりました。
— 具体的にはどのように改善したのでしょうか?
中村:
今はアラートをcritical / warn / infoの3つに分けて運用しています。見るべき監視項目を精査して、criticalは即対応、warnは時間帯によって翌営業日に確認して、infoは無視してOKというような運用にしています。アラートは適切に運用しないとすぐ荒れてしまいがちなので、整備したことで何か問題があった時の対応がしやすくなりました。
移行で苦労したポイント〜負荷試験 / 放流試験 / バッチ移設
■負荷試験:アプリケーションのボトルネックの洗い出し
– では、具体的な移行方法についてお聞きしていきたいと思います。まずは、全体的な移行の手順について教えてください
中村:
検証→一部機能の移行→負荷試験→放流試験→本番というのが基本的な手順です。社内サービスで試しにEKSへの移行検証をしたあとに、本番のバッチや非同期処理(Sidekiq)環境から少しずつ移行していきました。
– 負荷試験はどのように行なわれたのでしょうか?
君島:
本番データベースのクローンを用意して検証用のEC2とEKSを繋ぎ、本番と同等のリクエストを流してレスポンスタイムなどが適正であるかを確認しました。今回は主にRailsのAPIテストを中心に負荷試験を行いました。
中村:
負荷試験環境はDistributed Load TestingというAWSのソリューション(CloudFormationテンプレート)を利用して作成しました。Webインターフェースまで含めて負荷試験環境を簡単に作成することができました。
負荷試験は実行自体が簡単でも、検証するためにはコツや勘所が必要です。なにをもって現在の本番環境と同等と見るべきなのかを決めたり、パフォーマンス劣化が見られたときのボトルネックを探ったりするのが負荷試験の難しいところです。
— 実際に検証で工夫した点はありますか?
中村:
まずは本番環境で実際に受けているリクエストを採取して、それを元にテストケースを作成しました。それを最小構成ののEC2に対してリクエストを送り、そのレスポンスやエラーログを取得して、新たに立ち上げたEKS環境と比較していきました。いきなり大規模な環境で試験するのではなく、最小構成から負荷をかけて、どのような箇所にボトルネックが現れるかを確認していきます。1 NodeあたりのPodの数は、実際に負荷試験をしながら調整していくことになります。
その後に、被負荷試験環境をスケールアウトさせて、与負荷試験環境側の並列数をあげて本番同等のリクエスト数を流します。その時点でアプリケーションのパフォーマンスやレスポンスタイムを確認して現時点での環境と比べて差分がないかをみます。そのほかにもDBなどの関連リソースにボトルネックがないかをみたり、エイジングとして長時間リクエストを受けて問題ないかをみたり、アプリケーション側にエラーが出ていないかを確認したりします。
— その結果としてパフォーマンスが安定した?
中村:移行後にパフォーマンスの懸念が出なかったのはこの時にしっかり検証を行えたことが一番の要因だったと思います
■放流試験:Continuous Deploymentの利用
— 続いて、放流試験はどのように行ったのか教えてください
君島:
放流試験にはCloudFrontの機能であるContinuous Deploymentを利用しました。Continuous Deploymentを利用すると、指定した割合で2つのCloudFrontにリクエストを分配することができます。
君島:
noteのリクエストのうち10%をEKSに流して、パフォーマンスの問題やエラーがないかを確認していました。初回の放流試験で大規模な問題が見つからなかったため、1週間ほど設定を維持して放流試験を続けました。
中村:
Continuous Deploymentを利用したことで、放流試験は相当楽になりました。もともとはCloudFrontを2つ作ってDNSを切り替える形で放流試験と切り替えを行う予定でしたが、Continuous Deploymentを利用することでDNSの設定変更が不要になりましたし、すぐに切り戻すことができるようになりました。
君島:
放流試験は無事に終えることができましたが、Continuous deploymentの挙動に関して想定外の点がありましたね。
中村:
ああ、ありましたね。EKSに全リクエストの10%を振り分けるように設定していたのですが、毎日夕方〜夜間にかけてリクエストが0.1%しか振り分けられない挙動が見られました。
君島:
AWSのドキュメントでは以下に記載がある通り、状況次第ではContinuous deploymentの設定を無視してプライマリのCloudFrontに多くリクエストを流してしまう場合があるそうでした。
君島:
今後Continuous deploymentを利用する機会があれば、この点を考慮して作業したいと思います。
■バッチ移行:EKS移行の大きな課題
— 移行における最大のボトルネックは何だったのでしょうか?
中村:
バッチ処理のEKS移行には時間がかかりました。理由は以下のような課題があったからです。
1台のEC2上でバッチ処理が稼働していて、EC2障害時の耐性が低かった
定期実行の定義がwhenever gemで定義されていて、Rubyへの依存度が高かった
バッチ処理の運用ルールが整備されていなかった
バッチ処理ごとに担当チームや実装方法が様々で、全体を把握できている人が少ない状態だった
このようなバッチが250つほど存在している状態だった
君島:
EKS移行にあわせてこれらの課題の解決を試みました。
まず、バッチの実行環境をKubernetesのCronJobに移行しました。これによりwhenever gemの利用が不要になったほか、CronJobの機能でリトライや各バッチ処理ごとにリソース割り当ての変更ができるようになりました。バッチによっては、Fargateを利用することでEC2への依存度をさらに下げることもできています。
また、移行の過程で現在のバッチ処理の一覧化やバッチ処理の中身の読み込みも行いました。noteのバッチ処理についてはかなり詳しくなりました(笑)
中村:
バッチ移行の作業は君島さんにほとんど行なってもらいました。note社内でバッチを全部理解しているのは君島さんくらいじゃないかな(笑)
君島:
この知見を社内に広げるために、ドキュメントに落として共有できればいいなと思っています。
— 他に改善できた点はありますか?
君島:
バッチ処理に限らず、コンテナのログについてはfluentbitを利用してS3やCloudwatch Logsなどに同期するように改善しました。これまでは一部バッチのログがS3などに同期されていないことがありましたが、この改善によってログが失われる可能性は下がったと思います。
— 様々な種類のバッチ処理があるので、移行には苦労がありそうですね
君島:
TwitterやFacebookなど、note外のサービスと連携しているバッチ処理の検証に関しては考慮事項が多く難しかったです。外部サービスに検証環境があるか、検証環境を利用してもコストや不整合が発生しないか...などを考慮しながら注意深く進めました。
中村:
検証に関して言えば、Slackからバッチ処理のJobを実行できる仕組みを早めに作って運用に乗せられたのはよかったかなと思います。今まではEC2にsshして処理を手動で実行して検証する運用がありましたが、EKSの採用と仕組みの改善によってssで接続せずに処理の検証ができるようになりました。検証の仕組みを先に構築したことで、EKS移行が効率的に進んだ面はあると思います。
— 仕組みから取り組むのはいいですね。他にもバッチ移行で工夫した部分はありますか?
中村:
EKSのCronJobの定義を一元管理するCRD(Custom Resource Definitions)として、cronjob-manager-controllerという機能を内製で開発して運用しています。すべてのバッチに対してCronJobの形式でyamlを作成するのは大変なので、cronjob-manager-controllerによってバッチを追加する場合に実装する範囲が少なくなるようにしました。
— なるほど、これによって管理が楽になったんですね
中村:
確かにcronjobを管理するためのリソースとして楽になった部分もありますが、今となっては逆にこれは失敗だった部分もあります(笑)
バッチによって求められる要件や実行条件が異なるため、「このJobはリソースを変えたい」「Jobの挙動をちょっと変更したい」などの細かい修正が入ることがあります。このような個別のバッチ単位の修正はcronjob-manager-controllerの設計方針とは合わなかった点があり、定義ファイルの編集に負荷がかかるようになってきました。
今はOSSなど既存の仕組みに置き換えることを考えていて、移行先としてArgo WorkflowsのCron機能に移行するなどを検討しています。
noteのインフラはスタートラインに立ったばかり
— 実際に移行して運用を行ってみて、メリットに感じる部分はありますか?
君島:
インフラを全面的に見直したことで、監視やログ収集がしやすくなりました。noteに問題が起きてもすぐに気づけますし、ログはS3に同期されているので安心感があります。あとは、独自ドメイン周りなど特殊な処理を実装したいときも切り分けがしやすくなりましたね。
中村:
CRDで独自にリソースを定義すればEKS内に様々な機能を実装できるので、複雑な要件に対してもより柔軟に対応することができるようになりました。
直近ではElasticSearch(ECK)やArgo WorkflowsをEKS内にホストして運用しているほか、Node.jsのアプリを稼働させていたりもします。
君島:
他にも、kustomizeを利用して開発環境を簡単に増やせるようになるなどの利点もありました。
— これから運用で気をつけるべきことなどはありますか?
君島:
EKSクラスターのバージョンアップ対応の工数を確保することです。移行作業中にも一度バージョンアップが必要となったため、その作業によって移行作業の進捗が止まってしまうことがありました。これから移行を考えている方は、バージョンアップ対応の工数を織り込んで検討した方がいいと思います。
— 最後に、今後やっていきたいことあれば教えてください
中村:
EKS移行が完了して、モダンなインフラ環境に近づけました。ようやくスタートラインに立った感覚です。今後はEKSを利用して、開発環境を即座に作れるようにしたり、デプロイを早くしたり、モノリシックなサービスから徐々に切り分けたりなど、やりたいことややるべきことがたくさんあります。堅実に改善をつづけながら、少しずつ活用の幅を広げられればいいなと思っています。
▼noteの技術記事がさらに読みたい方はこちら