マルチ向けゲームサーバのCDツールをSpinnakerからArgoに置き換えたお話
はじめに
この記事は Colorful Palette アドベントカレンダー 12/15 の記事です。
株式会社Colorful Paletteでサーバサイドエンジニアをしている、あくびです。普段はサーバサイドアプリケーションやマルチプレイ向けゲームサーバの開発、インフラ構築・運用などを行っています。
本記事では、昨年実施したアドベントカレンダーに掲載した記事「ゲーム内イベントの予定に合わせたサーバのスケールアウト・インの自動化について」で紹介したスケール自動化システムについて、一部使用技術の移行を行ったので、簡単にですが紹介したいと思います。
既存のシステムについておさらい
過去の記事より、なぜ自動化が必要だったのかと、移行前の構成を軽くおさらいします。
まずなぜ自動化が必要だったのかについてです。
「プロジェクトセカイ カラフルステージ! feat. 初音ミク」(以下、「プロセカ」)では、バーチャルライブやコネクトライブの開催時、イベントの開始・終了時など、アクセスが急増するタイミングがいくつか存在します。
そういったタイミングでは、オートスケールを設定している場合でも、アクセスの増加に対してサーバのスケールアウトが間に合わず過負荷になってしまいアクセス障害に繋がってしまいます。
この理由からプロセカでは「アクセスが増加するタイミングに合わせて事前にサーバをスケールアウトしておく」という運用を行っています。
以前は担当者がゲーム内のイベントやライブの情報を確認し、手動でサーバのスケールイン・アウトの日時、台数を設定するという運用をしていました。しかし、設定ミスが多く障害に繋がってしまうこともしばしば…。そのため、スケールする日時やサーバ台数の設定、スケール時刻にサーバ台数を変更するといった処理を自動化するシステムを構築しました。
当時利用していたシステムの構成は以下の通りです。
CI/CDツールの選定について
当時のシステム構成では、Kubernetesクラスタ内のポッド数の変更についてSpinnakerを利用していました。通常のリリース作業も同様で、Spinnaker Pipelinesを用いてサーバのデプロイを行っていました。
運用を続けていく中で、利用していたKubernetesクラスタのバージョンがかなり古くなってしまっており、大きくバージョンを上げる必要が出てきました。
その際に、以下の理由から、どうせならSpinnaker以外のツールも検討してみようという事になりました。
自前で構築したものではなかったため、管理が煩雑だった
サーバデプロイを走らせたときにTimeoutまで終了しないことが時々起こった
CI/CDツールを選定するに当たって、いくつかのツール実際に軽く触ってみたところ、既存システムと同等の機能を実現でき、かつクラスタの構成やデプロイ時の差分などが確認しやすくなることから、Argo CD、Argo Workflowsを利用する形になりました。
Argo CDはKubernetes向けのCDツールです。GitOpsを実現でき、Gitリポジトリで管理されているKubernetesマニフェストをクラスタに反映する形でCDを実現します。
Argo WorkflowsはKubernetesネイティブなワークフローエンジンです。各種ワークフローをKubernetesのカスタムリソースで定義することができます。
他のツールとして、Tektonやflux、Google Cloud内の各種サービスを連携させてみる…などを検討しましたが、既存システムの要件を満たす場合に構成が複雑になってしまう点から選定しませんでした。
設計・構築
SpinnakerからArgoへの移行に伴って、通常のリリースのフローも少し変更となりました。
以下の図のようになります。
Spinnaker Pipelinesを使っていたところを、Argo CDのApplicationに移行しました。
Spinnaker PipelinesではGitHubで管理されているマニフェストをそのままデプロイしていたため、各種ポッドの台数がマニフェストで設定されている台数に変更されていました。
Argo CDに変更した際に、特定の差分を無視する設定を入れることでポッド台数を変更せずにデプロイを実施できるようになりました。
スケールスケジュールの設定を自動化したツールの方も構成が変更となっています。
Spinnaker PipelinesのAutomated Triggersを利用していた箇所をArgo WorkflowsのCron Workflowsに移行しました。ただし、Argo WorkflowsのCron WorkflowsにはSpinnaker Pipelinesのステージにあったようなスケール機能はないため、別途実装したAPIを経由する方法で実現しました。
Cloud Runに、Kubernetesクラスタの特定のポッドに対して台数を変更するAPIを実装し、Cron WorkflowsからAPIを呼び出すことでスケールを実行しています。 図に記載はありませんが、スケール実行後はSlackに結果を通知しています。
台数の変更のみをターゲットとしたArgo CDのApplicationを作成する方法も試してみたのですが、指定台数と実際に適用される台数に差異が生まれる現象が起きていたため断念しました。原因調査をする時間があまり取れなかったことが悔やまれる…!解消できればこの方法でも実現できたかもしれません。
また、Argo WorkflowsのWorkflow Templateとして、手動で実行できるスケール用のワークフローも作成してあり、任意のタイミングでポッドの台数を変更できるようになっています。
移行後に感じるメリットとデメリット
SpinnakerからArgoに移行を行い2ヶ月ほど運用していますが、Argoに変更したことで感じるメリットとデメリットをいくつか挙げてみます。
メリット
デプロイ時に更新差分を見ることができるので、意図しない差分が出ていないかを確認できる
デプロイ先のクラスタの構成がわかりやすい
クラスタの構成がArgo CDのダッシュボードに表示される
管理がしやすくなった(自前で構築できたことが大きな要因になっているが…)
ArgoのApplication定義、Workflowの定義などをすべてマニフェストとして管理し、適用できるため構成をリポジトリで管理できた
デメリット
スケールのみに関連する処理をArgo CDのみで完結させることが難しい
GitOptsを実現するためのツールなので、今回の用途では仕方がない…
1ツールで完結できない
Argo CD、Argo Workflowsに分かれて構築しているため、ダッシュボードなども別で管理される
おわりに
運用に関連するツールや自動化などの仕組みは、実際のアプリからは目に触れることのないものですが、運用するに当たって欠かせないものでもあります。
ただし、本質的なものづくりに集中できるよう、ツールの運用にはあまり手をかけずにやっていきたいものです…。
今後も、安定したゲームプレイを支えるためにできる工夫や改善を続けていければと思います!