モンスターストライク スタジアムをAmazon EC2からAmazon ECS Fargateに移行しました
MIXI でモンストサーバチームとセキュリティ室を兼務している、atponsです。
モンストサーバチームでは、モンスターストライクとは別に、モンスターストライク スタジアムというスマートフォンのアプリゲームのサーバ開発・運用を行っています。
モンスターストライク スタジアムは、モンスターストライクとプレイスタイルは同じながら、4vs4の最大8人まで同時対戦や練習モードなどを備えたアプリになっており、モンストのeスポーツ大会「モンストグランプリ」を開催する際にも利用されています。
開発体制の現状
モンスターストライク スタジアムは、初期の段階でモンスターストライクのコードから分岐する形で開発されているため、アップストリームの変更を順次取り込んでいくという仕組みで運用されています。そのため、サーバコードなどは別にあり、適宜新機能を取り込んでいきアップストリームと合わせていくという開発・運用フローを取っていました。
インフラ面では、モンスターストライクのサーバ構成と同じ仕組みがベースになっていて、Amazon Web Services (AWS) 上に EC2 インスタンスを複数台、ELB、マスターデータの配信には S3 や CloudFront、データベースには RDS を採用するといった一般的な Web サービスの構成でした。
しかしながら、ミドルウェアやデプロイ周りのフローがアップストリームとの差分が大きくなっていました。作業によってはアップストリームで変更した差分が取り込まれないこともあり、加えて、モンスターストライクはオンプレミスやクラウドを組み合わせた構成になっており、プロビジョニングフローなどにかなり差分があったまま、数年間経ってしまいました。
なぜ ECS、そして Fargate か
EC2 インスタンスでの運用は成熟していましたが、プロビジョニングフローの差分以外にもいくつか問題を抱えていました。
- 分岐された時点のモンスターストライクのコードベースに修正を加えていたため、アップストリームのインフラ構成やデプロイフローの状況が分からないメンバーが増えてきたことで、より運用が困難になった
- アップストリームのミドルウェア、ライブラリバージョンの差分の取り込みで毎回 EC2 をプロビジョニングするのが難しい
- チームがアップストリームの開発・改善・運用フローに集中し、デリバリー速度を上げることに注力しつつ、モンスターストライク スタジアムを安定運用していきたい
今の EC2 インスタンスによる運用から変えるために、コンテナ化によるインフラのモダナイゼーションを選択しました。
コンテナ化によるモダナイゼーションを AWS で行うためには、いくつか方法があります。コントロールプレーン、データプレーンの観点から移行について検討しました。
コントロールプレーン
- ECS
- AWS 上で動作させるためのツールがそろっており、運用コストが低い
- モンスターストライクでは知見がない
- EKS
- モンスターストライクでは Kubernetes クラスタの運用を行っており、知見がある
- Kubernetes 自体のバージョンアップなどの運用コストについて鑑みる必要がある
データプレーン
- EC2
- AMI の作成、管理をある程度自動化することで EC2 のみの運用よりもメリットを得やすい
- 柔軟なマシンリソースの変更が可能
- Fargate
- マシンリソースはいくつかの選択肢から検討する必要がある
- コストパフォーマンスにおいて、EC2 の方が有利になることがある
ECS Fargate を選択した理由
モンスターストライク スタジアムについては、これらの組み合わせの中から ECS Fargate を選択しました。
- EC2 を選択した場合、モンストサーバチームが AMI の管理などを行う必要があり、管理コストを下げたいという意図とマッチしない可能性がある
- 一般的な Web サーバのみしか存在せず、EKS (Kubernetes) で動作させたいようなツールが存在しない
- 管理対象の Kubernetes クラスタが増えることで、Kubernetes クラスタの運用コストが上がるのを避ける
様々な選択肢がある中で、今回は管理、運用コストを極限まで下げるという目的にマッチした ECS Fargate を選択しました。
文化を変えるためにやったこと
ECS Fargate の導入検証と同時期に、ECS Fargate はどのようなものなのか、Kubernetes と比べて何が違うのかという資料を作成し、以下のような事柄について理解を深めてもらうことにしました。
- ECS 固有の用語集
- ECS と Kubernetes の違い(比較)
- ストレージ
- ECS における IAM ロールとその利用方法
- デプロイについて
- コストについて
EC2 時代のアプリケーションをコンテナ化するためにやったこと
モンスターストライク スタジアムは、モンスターストライクと同様 Ruby で開発されており、Padrino を使った Web アプリケーションとなっています。ミドルウェアとしては Nginx, MariaDB を利用しています。
設定を環境変数から注入できるようにする
これまでデータベースへの接続情報などはファイルをベースにしていましたが、これらは環境変数から注入できるようにしました。
ecspresso によるデプロイフローの構築
ECS のデプロイには Terraform 含め様々な選択肢がありますが、今回は kayac/ecspresso を用いたデプロイを行うようにしています。
ecspresso は Run Task API のサポートや ECS Exec のサポートがあり、以下で述べるようなマスターデータのインポートや Padrino のコンソールの利用が非常に便利なので、デプロイ以外でも利用することにしています。
ALB など、他の AWS リソースについては Terraform 上で管理しています。
マスターデータのインポートを GitHub Actions 経由で行うように変更
モンスターストライク スタジアムを動作させるのに必要なマスターデータについては、プランナーが作成した CSV ファイルやアセットをデータベースや S3 へアップロードする必要があります。
これらは ecspresso を GitHub Actions 上で起動させて、マスターデータをインポートするためのスクリプトを ECS Run Task で実行するようにしています。アプリケーション上でローカルにキャッシュを持っているので、自身をタスク定義の更新なしにデプロイしなおすことでキャッシュを飛ばしながら、新しいタスクに入れ替えるような仕組みも作っています。
Firelens による ECS ログ収集フローの構築
モンスターストライク スタジアムは元々、EC2 上で Fluentd を動かしてアプリケーションのログや Nginx のログを S3 へアップロードしていました。
今回は Firelens を用いて Fluent Bit を経由して S3 と CloudWatch Logs へログを転送するようにしました。長期保存や分析には S3 上のデータを利用し、障害対応やログベースのメトリクスを CloudWatch Logs で行える仕組みを整えることができ、このフローは普段の運用に貢献しています。
無停止で移行するためにやったこと
開発環境をまず ECS へ移行し、様子を見ました。その後実際の移行を考えるうえで、ELB を ALB へ移行する必要があるため、ステージング環境で ALB を新規作成し、ALB 側に EC2 と ECS のトラフィックを受けられるようにしつつ、ECS へ寄せる処理を行い、無停止での移行が問題ないことを確認しました。
この後、本番でも同じ作業を行うことで、ELB から ALB への移行、そして無停止による段階的な EC2 から ECS への移行を実施することができました。
まとめ
今回はモンスターストライク スタジアムとよばれるアプリゲームを EC2 から ECS へ移行した理由とその方法についてまとめました。ECS 化移行、ミドルウェアのアップデートやアップストリームへの追従がしやすくなり、管理、運用コストの削減ができた実感をしています。
また、アプリゲームのようなマスターデータのインポートというフローがある場合でも ECS で問題なく移行ができました。参考になれば幸いです。
Discussion
これを教えて欲しいです!