ウェルスナビにおけるコンテナ化の取り組み
はじめに
こんにちは、インフラエンジニアの和田です。
今回は資産運用サービス「WealthNavi」のコンテナ化の取り組みについてご紹介いたします。
インフラエンジニアの私が2023年の WealthNavi を一言で表すとすると「コンテナ化の年」と言えます。
本格的にコンテナ化に着手する前の2022年12月のコンテナ環境の割合は20%程度でしたが、2023年の6月頃には80%に達しました。
EC2の台数は150台から50台程度まで減少しています。
実行基盤推移
コンテナ化のデッドラインとして強く意識されていたのが、2016年のサービス開始時に実行基盤として採用されたEC2(Windows Server 2012 R2)のEOS(2023年10月)でした。
さらに、2024年からはじまる新NISAの開発に大半のリソースが投入される気配があったため、2023年の前半中(なるべく早期)にコンテナ化を終えることが望ましいと考えました。
残り20%のEC2については、2023年7-9月にかけてWindows Server 2019にインプレースアップグレードしています。
今回のタイミングでコンテナ化を見送ったサーバは、顧客に提供するサービスが稼働するサーバというよりは社内インフラ寄りのものが多いです。
- Windows専用のツール/サービスを使うためのサーバ(VDI)
- ActiveDirecotryサーバ
- ファイルサーバ
- Windows環境に強く依存しているバッチサーバ
コンテナ化で得られたこと
The Twelve-Factor App に沿ったアプリケーション開発・運用推進を行うハードルがぐんと下がりました。
例を挙げるとキリがないですが、わかりやすい例だと次のような項目に改善が見られました。
- 再起動/スケールアウト作業コストの削減
- Before: サーバ障害が発生した際は手動でインスタンスを再起動していた。S3のBucketPolicyがDenyルール(=インスタンスIDベースで許可)で管理されており、自動化の障壁があった
- After: ECSの標準機能でタスクが希望数になるよう自動調整。BucketPolicyにロールIDを許可するだけでよくなりオートスケール設定が簡単にできるようになった
- OS構成管理コストの削減
- Before: OSの設定がコード化されておらず、ステージと本番環境の構成差分がリスクだった
- After: コンテナ化されればDockerfileで強制的にコード管理できる
- 開発環境の管理権限を開発者に委譲
- Before: 開発者が環境変数やJavaの起動パラメータを気軽に変更できなかったため、DBの接続先などがアプリケーションリポジトリ内に埋め込まれていた
- After: ECSのタスク定義の管理を開発者に委ねることで開発効率改善
- 改善モチベーションの向上
- Before: ワークアラウンドに次ぐワークアラウンド。ワークアラウンドにより生じる制約が運用負荷に
- After: 一般的なプラクティスがそのまま適用でき、浮いた時間をさらなる改善に充てられるようになった
本記事を執筆中にとても綺麗に言語化された記事を見つけたのでリンクを貼っておきます。
「コード書きました、あとはよろしく」では優れたソフトウェアは生まれない コンテナのスペシャリストが語る、運用性を損なう8つの実装例
コンテナ化の取り組み
コンテナ化する上で具体的にどのような対応を行なったのか紹介いたします。
開発者の協力なしでは進められなかった内容が多いです。
顧客データ保管をEC2からS3へ移行
顧客がアップロードした本人確認書類や、顧客向けの運用報告書などを EC2 上で構成された DFS(分散ファイル システム) から S3 に移行しました。
保管先のパスをWindowsのものからS3キーに変換する処理を行う必要もありました。
C++で実装された暗号化モジュールをJavaへ移植
顧客がアップロードした本人確認書類は、C++で実装された暗号化モジュールによる暗号化後S3に保存されていました。
Linuxコンテナに移行するため暗号化モジュール相当の処理をJavaに移植しました。
静的コンテンツ配信をIISからS3へ移行
Webアプリケーションの静的コンテンツは、EC2にインストールされたIISから配信されていました。
性的コンテンツをS3に移行することで移行によりWebアプリケーションと静的コンテンツの配信ホストが分離され、WAFのトラフィックを削減できました。
Webサーバを経路から外す場合はアプリケーションのリダイレクトを考慮する必要がありますが、
当社で広く採用されているフレームワークは X-Forwarded-Proto
に対応していませんでした。
解決策として、タスク定義の環境変数経由でリダイレクト時のスキームやホスト名をアプリケーションサーバに伝えられるようにしました。
ログフォーマットの変更
Fargateでアプリケーションのログを扱うには一般的にログ出力先をローカルファイルから標準出力に変更することが望ましいです。
特に複数種類のログファイルを扱うようなアプリケーションの場合、どのログファイルに出力されていたログなのかを区別できなければいけません。
今回はログを情報をログに追加しフォーマットをJSONに変更することで対応しました。
パイプラインの整備
当社のJavaアプリケーションモジュールはビルドの最終工程でS3にアップロードされ、デプロイツールがそれを各EC2に配置する方式で運用していました。
コンテナ化に併せてパイプラインを一から作り直すコストは大きいため、S3のパスをCodeBuildのパラメータに渡すだけでことでコンテナイメージをビルドする仕組みを整備しました。
APMの全面導入
プロダクトの成長に伴いサービス間の依存関係の複雑化が課題となっており、その解決手段のひとつとしてAPMの全面有効化しました。
特にサービス間の依存関係を簡単に検索できるようになる TraceQuery という機能がおすすめです。
APMは便利ですが利用コストが高いという弱点があるため、サンプリングレートの標準設定値を 30% に定め、後述する jsonnet テンプレートに組み込みました。
Datadogの取り込みメカニズムの標準はヘッドベース+エラートレース+レアトレースであるため、サンプリングレートを絞ったとしてもある程度ほしいトレースは取り込むことが可能です。
タスク定義のテンプレート化
Fargate環境ではDatadogAgentをSideCarで動作させる必要があります。
さらにAPMで利用するトレースデータを取得するためには、アプリケーションコンテナ側にトレースエージェント導入も必要になります。
工夫点は、タスク定義の管理を開発者にスムーズに委譲できるようECSタスク定義を jsonnet でテンプレート化したことです。
詳細は過去のテックブログをご確認ください。
タスク数100超え!モノレポとエスプレスタックで支えるECS管理の仕組み(ecspresso/ecschedule)
開発環境管理の委譲
コンテナ化以前まではEC2インスタンスのスケールアップや起動停止スケジュールの管理は開発者からの依頼を受けたインフラエンジニアが行っていました。
しかし、新NISA対応などの大規模・並列開発のプロジェクトではその依頼量が増え、開発者とインフラ双方の負荷が高まる懸念がありました。
解決策として、コンテナ化を機にECSタスクの管理権限を開発者に委譲していた仕組みを拡張する形で、
開発環境のECS起動/停止やDB複製/削除をNotion経由で行えるようにしました。
詳細は過去のテックブログをご確認ください。
開発環境の稼働スケジュールをNotionとecspressoで管理してみた
こつこつ改善を続けよう
End of Lifeという言葉はあまり聞きたくないものですが、周囲の理解や協力があるとなんとかなるものです。
とは言え今回のようなビッグバン的な改善はあまり望ましいものではないため、今後はこまめに改善を行える仕組みを整えることで開発者や顧客に価値を届けたいです。
GitHub社のように毎週RubyとRailsをアップグレードするような成熟したエンジニアリングができるとかっこいいですが、
まずは地道に今の組織でできることから着手していこうと思います。
GitHubは200万行規模のRailsアプリケーションであり、毎週RailsとRubyを最新版にアップデートし続けている
さいごに
今回のコンテナ化でインフラの運用が身軽になり、ワークアラウンド的なタスクではなく根本的な改善タスクに割く時間が増えました。
APMの導入や開発者への管理権限委譲を進めることでアプリケーション改善の頻度も向上しました。
今後はマルチプロダクト化を見据えており、そこにはさらなるチャレンジが待っているはずです。
📣ウェルスナビは一緒に最高のプロダクトを作る仲間を募集中です📣
筆者プロフィール
和田 雄樹(わだ ゆうき)
2018年1月ウェルスナビにインフラエンジニアとして入社。
技術的負債を解消する記事を読むのが好きだから自分も書いてみたらしい。
やっぱり読む方が楽しいかも。
Discussion