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

CNDT2023: noteのEKS移設、ゼンブ見せます

varu3
December 11, 2023

CNDT2023: noteのEKS移設、ゼンブ見せます

本資料は CNDT2023 の登壇資料です

- CFP
- Google Docs版

noteでは2023年9月に本番環境の全アプリケーションがKubernetes(EKS)で稼働させることができました。私たちはただKubernetesへの移行だけではなく、長年運用されてきたレガシーインフラの課題を解決するための多くの改善を併せて実施しました。特に、アプリケーションのパフォーマンスを維持するためのロードテスト、オブザーバビリティの強化、コンテナをデプロイするためにオートスケールするGithubActionsランナーを構築した事例、Kubernetesの仕組みをフルに活用し開発環境の即時展開を可能にしたシステムの事例など、このプロジェクトを通じて遭遇した課題やそれを乗り越えるための施策を実例を交えて詳細に解説します

varu3

December 11, 2023
Tweet

More Decks by varu3

Other Decks in Programming

Transcript

  1. 事業概要 だれもがインターネット上で自由にコンテンツを投稿・販売できるC2Cメディアプラットフォーム「note」と、 noteを基盤に企業の情報発信を簡単かつ効果的に行うためのメディアSaaS「note pro」を中心に事業を展開。 3 だれもが文章やマンガ、音声等さまざま なコンテンツを自由に投稿・販売するこ とを可能にするメディアプラットフォー ム。 インターネット上での継続的な創作活動

    を可能にすることにより、クリエイター エコノミーを促進。 企業のオウンドメディア運営、ホーム ページ構築など、情報発信を簡単に行う ことを可能にするメディアSaaS。note の標準機能に加え自社サイト構築に必要 な機能を提供し、noteを基盤とする情報 発信を支援。 法人向けサービス
 ・noteコンテスト 企業とコラボレーションし、note上でクリ エイターから作品を募集する企画を開催 ・イベント note連動イベント等のため、イベントス ペース”note place”を貸出
  2. noteの概要 クリエイターが文章やマンガ、音声等さまざまなコンテンツを自由に投稿・販売することができ、読者がコンテン ツを楽しみ、クリエイターを支援・購買することができるメディアプラットフォーム。 4 コンテンツを投稿する クリエイター 個人 法人 読 者

    読者 つぶやき 画像 テキスト 動画 音声 コンテンツを販売する 読者とつながる コンテンツを楽しむ コンテンツを購入する クリエイターを応援する クリエイター クリエイター 読者
  3. 10 こんな課題を抱えていました noteは2014年4月からAWS上で動いているコンテンツプラットフォーム。 Kubernetesへの移行に取り組む前の2020年時点で次のような問題がありました。 メンテナンス性 技術継承 セキュリティ • IaC化されていないリソース •

    手作業での運用が多くある状態 • モニタリング用のダッシュボードが分散 していてどこを見たらいいのかわからな い • アラートが割れ窓化 • 誰がどう管理しているか不明なAWSリ ソース • ベストプラクティスではないネットワー ク構成 • AWSアカウントのセキュリティ体制が 整っていない • 過剰に付与されたIAM権限
  4. 「ソフトウェア式年遷宮」という考え⽅ 11 レガシーなインフラ構成全般を見直して脱却するため、中長期的なプロジェクトとした。 単にアプリケーションを移設するだけでなく長年の課題を解決しつつ、 技術継承しながらプロジェクトを進めていくことに注力した。 取り組む 課題 • アプリケーションのメンテナ ンス性

    • スケーラビリティ • インフラ構築当初のエンジニアは いない • 設計意図が不明な設定 • 必要か不要か判断ができない設定 • 現在のベストプラクティス ではない状態 • 過剰なIAM権限 • ネットワーク構成 • 運用の自動化 • 耐障害性の向上 • モニタリング・アラートの再 設計 • DX(開発体験)の向上 • IaCの推進 • インフラの設定の見直し • 複雑なデプロイフローをシン プルに • ネットワークを再構築 • アタッチするIAMロール等の権限 を見直し • バージョンアップ方針の設計 EKSへの移設 メンテナンス性 技術の継承 セキュリティ
  5. 拡張性 インテグレーションや エコシステム 開発経験 ECS • ECSクラスタ内に機能を増やして いくのではなく、SFn や EventBridgeなどを利用して、

    AWSの各種サービスと連携させ る使い方 • CFn がAWSから提供されていて 簡単にサービスをセットアップ 可能 • IAM TaskRole, SecuityGroup, サービス 間通信 (Service Connect) などの機能 が充実 • CodeBuild, CodePipeline, CodeDeploy などと組み合わせてデプロイが可能 • aws ecs系のコマンド • Fargate / Fargate Spotが利用できる • 小規模なアプリケーションでは利 用経験があったもの、本番では経 験がなかった なぜ EKS (Kubernetes) にしたのか Kubernetes • Kubernetesクラスタ内に各種機 能を増やしていくという使い方 • Helmを利用することでOSSツー ルやSaaSとのインテグレーショ ン機能を簡単にインストールす ることが可能 • VPCの Secondary CIDR や IAM Roles for Service Accounts (EKS Pod Identity) , Pod Security Group, Managed Nodegroup, Karpenterなど AWSのサービスが k8sで利用できる ツールが充実してきた • デプロイパイプラインは自前で実装す る必要がある • Fargate のみしか利用できない • SREメンバーのほぼ全員が本番環 境でのKubernetesでの開発経験を 持っていた
  6. 14 移設計画 • 2019年から2020年ごろまで検証プロジェクト • 2020年 cakes を検証のためEKSクラスタへ移設 • 2021年9月に移設プロジェクトのキックオフを実施・本プロジェクトが開始

    2019 年 ~ 2020年頃まで 検証プロジェクト cakes 2020年 ~ 2021年9月 ~ • アプリケーションを Kubernetesで動作させる ための技術検証 • 弊社の別サービスだった cakesをEKSへ移設 • noteの運用に向けたノウ ハウを蓄積させた • 運用ノウハウを活かして noteのアプリケーション を全面移設
  7. noteを構成するアプリケーションは主に5つ存在している。 batch → worker → cert-proxy(独自ドメイン機能) → frontendおよびapi の順番で移設していくよう計画した。 移設計画

    15 15 frontend api worker batch SSRとCSRが組み合わせれたフロントエンドアプリケーション APIバックエンド バックエンドから呼び出される非同期処理用サーバ EC2サーバの crontab で管理、主にrakeタスクで動く cert-proxy note proの機能である独自ドメイン機能を提供する
  8. EKSクラスタの構築 • EKSクラスタ用に既存のVPCとは別に新たにVPCを作成した • AWSの関連リソースはterraformで管理、KubernetesリソースはmanifestのYAMLで管理する • Amazon EKSアドオンから各種アドオンを有効化する • 管理系Podは一つのNodeGroupに集約させて、耐障害性を上げる

    • CoreDNS と Node Local DNS Cache を有効化し、DNSのパフォーマンスを向上 • Amazon VPC CNI ◦ サブネットのセカンダリCIDRブロックを有効化し、100.64.0.0/10  の広いネット ワーク範囲を利用することでIPが枯渇しないようにする ◦ Podごとにセキュリティグループをアタッチする • OIDCプロパイダーを利用してサービスアカウントとIAMロールを紐付ける ◦ サービスアカウントをPodにアタッチすることで、PodごとにIAMポリシーを 制 御することができる 16 EKSクラスタを構築する 以前までのEKSクラスタは、手動で追加インストールする項目が多くあったが、 現在ではEKSアドオンや周辺ツールが充実し、terraform などのIaCを利用して簡単にEKSクラスタを構築することが 可能になった。
  9. 運⽤系ツールの開発 17 Kubernetes になれていないエンジニアにも、様々な方法で操作できるように運用系ツールを開発した。 Kubernetes の操作を Makefile や Slack 経由で実行できるようにして、利便性を向上させた。

    • SREメンバーの運用操作 • 本番環境の構築作業など Makefile kubectl Slack • SRE以外のエンジニアが行う 運用操作 • 必要なツールをローカルに一 括セットアップ • ログの閲覧 • staging環境のシェルに入って の操作 • 特定のコマンドを実行する • コンテナのビルド・デプロイ • ログの閲覧
  10. GitHub Actionsをオートスケールする仕組み: tornade CI/CD にはGithub Actions を採用。安価でスケーラブルなCI/CD 環境にするために、Github Actions のセルフホス

    トランナーをオートスケールする仕組み tornade : トルネード を開発し運用している。 • 既存のOSSではFargate Spotが利用できるECS上でセルフホストラン ナーがスケールアウトする仕組みがなかったため自作
 • ECS,CodeBuild 上にセルフホストランナーがワークフローの実行ごと に立ち上がる
 ◦ x86 / arm64 ビルドに対応
 ◦ Fargate / Fargate Spot / CodeBuild の実行するランナーを 選択可能
 ◦ CPU, memory のスペックを選択可能
 • IAMロールをランナーにアタッチすることでAWS操作に必要なポリシー を制限することができる
 18 tornade noteにもまとめてます  https://note.varu3.me/n/n95cd97ee07e9
  11. モニタリング環境 19 ログの集約にはDatadogとfluentbit、モニタリングにはDatadogとPrometheusを採用し observability を強化した。 19 Prometheus + Grafana fluentbit

    • daemonsetとして各Nodeに配置する • 各Podの標準出力に出力されたログをS3と Cloudwatch Logsに転送する • 各種Kubernetesリソース, Node のメトリクス の収集 • Cloudwatchに保存した各種Podのログを表示 • 統合的なダッシュボード(Service Metrics Overview)を作成した Datadog • 外形死活監視(URLへの定期的なヘルス チェック) • 各種Kubernetesのアラートイベント • nginxのログ分析 • アプリケーションのAPM • データベースモニタリング
  12. 22 定時バッチ処理のモニタリング環境 バッチ処理が失敗した原因がPodレベルだった場合にはDatadog、アプリケーションレベルだった場合にはSentryを 利用することで、どのレベルのエラーでも検知可能にしてアラートを改善した。 • Podレベルのアラートは Datadog のイベント で検知してSlackへ 通知


    • アプリケーションレベルのアラートは Sentryで検知して 通知
 • バッチが失敗を検知した場合 
 Kubernetesのbackofflimitを利用して自動再実行するか、 
 もしくは手動で再実行するか、 
 失敗した際のレカバリー用のバッチを実行する、などをあらかじ め決めておく Sentry + Datadogを利用したモニタリング環境の改善 Sentryへ飛ばされたエラーはSlackの特定のチャンネルへ通知 し、全員が検知できる状態にした
  13. バッチ処理のテスト実⾏‧動作確認のサイクル 23 staging環境で一時実行 ログを確認 ソースコードを確認 エラーチェック 実行時間などの確認 staging環境にデプロイ 本番環境にデプロイ ある程度たまったら

    バッチ処理の数は およそ250つ 1つずつこのサイクルを繰り返して 検証・テストする ・ファイルに書き出す処理があれば修正 ・エラー時にSentryへアラートする処理を追加 ・バッチの重要度をlow, middle, high に分類する Kubernetes上で問題なく実行できるか、処理速度に問 題がないかを確認する。 パフォーマンス改善 必要であれば、Fargateを利用してスペックを上げたり DBモニタリングを利用してクエリ改善などを実施
  14. 定時バッチ処理のデプロイ 24 複数のCronjobをまとめて設定するために独自のカスタムリソースコントローラー(CronjobManager)を作成すること で、バッチを簡単に移設できるようにした。 • Cronjobを管理するための カスタムリソースコントローラーを 自作 • 通常だと、およそ250つのCronjobのmanifestを作成することにな

    る • CronjobManagerを利 用してシンプルなYAMLファイルの記 述で cronjobを管理することができるようにした ◦ name, command, schedule を追記するだけでバッチ処理 の追加・削除が可能になった • テスト段階で定義した priorityの low → middle → high の順番で 移行を進めた CronjobManager
  15. Argo Workflows を利⽤した記事のインポート‧エクスポート機能 26 2023年3月にリリースしたnote の記事のインポート・エクスポート機能では、Argo Workflows を利用してワークフ ローを実装することでスケーラビリティを担保しつつ、大規模な並列処理を実現した。 •

    Kubernetes Nativeなワークフローエンジン。Argo CD / Rolllouts / Events などの兄弟プロダクト。 • インポート・エクスポートを実行すると、記事数に応じて Podが立ち上がりそれぞれの処理を実行する • 記事数によっては大量のINSERTが同時に走ることになるが ワークフロー内で同時に立ち上がるPod数を制御すること で、発行されるクエリ数を制御することができる • Karpenter (後述) を利用することで処理がない時には Nodeが 存在しないため効率的にワーカーの数を制御をすることがで きる Argo Workflows
  16. cert-manager を利⽤した note proの独⾃ドメイン機能 27 note proが提供している独自ドメイン機能には cert-managerを利用して証明書発行を自動で行う仕組みを構築した。 これによって証明書を管理する手間がほぼなくなり、運用の省力化を達成した。 cert-manager

    • 証明書の発行・管理を自動で行ってくれるOSSツールセット • Kubernetes内で動作して、自動で証明書の終端まで行ってく れる • DynamoDBに入れた証明書の情報を DynamoDB Streams -> Lambda Functionと経由して cert-managerリソースを作成す るようにした • 簡単に証明書を発行、管理する仕組みを構築した
  17. 負荷試験の計画と実施 29 負荷試験には Distributed Load Testing on AWS というAWSソリューションを利用し、負荷リクエストから解析レ ポートの出力までを効率よく実行することができ、負荷試験サイクルを迅速に回すことができた。

    Distributed Load Testing on AWS • エンドポイントに対して負荷リクエストを実行して解析レ ポートを出力してくれる CloudFormation テンプレート • Fargate on ECS を利用しているため、リクエストの並列数に 応じてスケールアウト可能 • InfluxDBにレスポンスタイムやエラーレートなどの様々なメ トリクスを集約し、Grafanaから参照して結果を分析 https://aws.amazon.com/blogs/architecture/ensure-optimal-application-performance-with-distributed-load-test ing-on-aws/ より引用
  18. 負荷試験の⽬標と実施 小さく始める ボトルネックがどのように 推移するかを計測する 細かなパラメータを追いすぎない 目標: EC2環境と同等の性能を出すにはどのような設定の Podがいくつ必要かを算出する 負荷試験のサイクル 本番環境のログから

    負荷試験のシナリオを作成 負荷試験の心得 負荷試験の実施 結果を測定 目標値と比較 パラメータを変更 負荷条件を変更 Grafana Datadog influxDB で結果を確認 割り当てるCPU、メモリ 量、起動するプロセス数、 Pod数など より本番に近い負荷量に 近づけていく 目標値をクリア 目標値に満たない
  19. CloudFront ContinuousDeployment を利⽤した切替作業 • Staging Distribution としてEKS環境を設定 ◦ リクエスト総数の一定の割合を振り分ける ことができる

    ◦ 最大15%まで段階的にリクエスト量を増や すことが可能 ◦ エラーが発生していた場合は、0%にするこ とですぐに切り戻す • 1週間ほど並行期間を設けて、Kubernetes環境固有 のエラーがないかを確認 31 Kubernetes環境への切り替えは CloudFront Continuous Deployment機能を利用して実施した。 ContinuosDeployment
  20. Karpenter (EKS⽤クラスターオートスケーラー)の導⼊ 33 Node の管理に Karpenter を導入し、より柔軟にNodeのオートスケールが可能になった。 当初はManaged NodeGroupを利用していたが、リリース後にKarpenterを導入。 NodeClass

    (Provisoner) • 利用するAMIやサブネット、セキュリティグループを定義する • インスタンスタイプ、CPUアーキテクチャ、キャパシティタイプを定義する • ラベルにNodePoolを入力するだけでNodePoolで定義した構成の Nodeが立ち上がる • インスタンスサイズを固定しresources.requests の定義を調整すれば、 1 Node = 1 Pod で立ち上げることが可能 • Spotインスタンスを利用して、コマンドを実行し終了したらNodeを消すとい うようなことが可能 NodePool (AWSNodeTem plate) Deployment
  21. EKSのバージョンアップ戦略 35 Managed NodeGroupを利用していた際には、バージョンアップ作業にとても時間がかかっていた。 Karpenterを導入したことで、Nodeのバージョン管理が不要になったため方針と手順を見直した。 • アドオンのバージョンアップ 後に新しいNodeGroupから起 動する •

    Nodeのバージョン管理が不要 • Podを入れ替えれば自動で最新の AMIからNodeが起動する • in-placeでのアップデートへ変 更 ControlPlane NodeGroup 関連リソース Managed NodeGroup • Blue / Greenデプロイメント方式 を採用し、別のクラスタを作り 直してリクエストを切り替える • NodeGroupごとにバージョン アップを実施 Karpenter • アドオンのバージョンアップ 後にPodを新しいNodeで起動 する
  22. DX(開発者体験)の向上: prehubの開発 • アプリケーションごとにブランチを指 定し、実 行 することでエンドポイントが作られる • どの環境のDBを利用するかを選択できる •

    およそ30分でリモート開発環境を構築できる • Karpenter導入後にはNode数の管理も不要 ◦ 制限なく開発環境を増やす・減らすことが できる 36 ステージング開発環境を即時に構築するシステム prehub:プレハブ を開発。 今まで開発環境の用意に時間がかかっていたのを大幅に削減することができた。 prehubによるステージング環境の作成
  23. 移⾏後の展望と次のステップ 38 noteはようやくクラウドネイティブのスタートラインに立った状態。 これからも様々な改善や利便性向上のための施策を行っていく。 SLI / SLO の策定 開発体験の向上 カナリアデプロイの導入

    スケーラビリティのさらなる向上 各サービス、APIごとのSLI / SLOを設定しよりサービ スの状況を詳しく把握できるようにする prehubで作ったステージング環境とローカル開発環境 をtelepresenseを利用して相互接続することで、デプ ロイをすることなく開発環境を作れるようにする デプロイ後にエラーを検知した場合に自動で切り戻せ るようにし、MTTRを短縮する KEDAを導入して、HPAよりも詳細なメトリクスに応 じたスケールアウト / スケールインする構成を目指す
  24. まとめ • レガシーなインフラ構成だったnoteを「ソフトウェア式年遷宮」することで、それを脱却し自分たちが完全 に管理できる構成にすることができた。 • AWSのマネージドサービスを駆使することで、大きな事故なく EC2 -> EKSへの切り替えを行うことができ た。

    • Karpenterの導入のおかげで、WorkerNodeの管理から解放されアップデート作業などの運用負荷を大幅に下 げることができた。 • 「Kubernetesは難しい」 と言われていたが、近年のマネージドサービスの機能の充実によって運用の負担 は他のECS等のマネージドサービスと比べてもそこまで高くない。 • ここまで長期間のプロジェクトをやりきったSREメンバーと、 それを支えてくれたnote株式会社の開発チームの皆さんにお礼を申し上げます。 39