見出し画像

Agones移行物語 - Kubernetes Meetup Tokyo 42 #k8sjp

前提

この発表では、2021年6月1日から提供していたBlack Game Streaming Engine v2についての内容になります。残念ながら発表の前日である23日をもって期間限定無料テストが終了しています。なので現時点では実際に触ってもらうことができません。

この資料は、当日の発表資料から不要なものを削り、時間の都合上話しきれなかった点を加筆して文字起こしをしたものです。おおまかな流れは当日と同じです。

発表

k8sjp_42_2_アートボード 1

それでは、Agones移行物語という発表をさせていただきます。

k8sjp_42_2_アートボード 3

始めに軽く自己紹介をしますと、うなすけといいます。フリーランスとして、いくつかの会社でWebアプリケーションを開発する仕事をしています。2019年から、BlackでOOPartsのクラウドインフラ周りを担当しています。

k8sjp_42_2_アートボード 4

さてAgonesの話をする前に、OOPartsがどういうサービスなのかをまず説明しておかないと内容が伝わらないと思うので、OOPartsについてどういうものなのかを話します。

k8sjp_42_2_アートボード 5

OOPartsは「クラウドゲーミングプラットフォーム」です。ユーザーさんがWebブラウザ上経由で、クラウド上にあるインスタンスで動いているゲームを操作し、ゲームサーバーでは操作の結果を映像として返す、というサービスを提供しています。この、ユーザーの操作ならびにゲーム画面については、WebRTCを使用して通信を行なっています。

k8sjp_42_2_アートボード 6

そして、これまでのOOPartsは、AWSとGCPの両方を使用するマルチクラウド構成となっていました。ゲームサーバーはEC2もしくはGCEのWindows Serverが起動しており、1人のユーザーのゲームプレイを1台のインスタンスで担当する、という仕組みになっています。
これについては昨年(2020年)にCEDECというイベントで話した資料がありますので、詳しくはそちらをご覧ください。

(CEDEC 2020での発表資料になります)

k8sjp_42_2_アートボード 7

そして、サービスを提供するために、インフラ側として「プレイ要求と待機中のインスタンスとのマッチング」「プレイ中ユーザー数に応じた待機台数調整」「プレイ中サーバーの保護」を自分達で実装していました。
これらについて、なぜそのような機能が必要なのかは後ほど詳しく説明します。

k8sjp_42_2_アートボード 8

さてある日のこと、メンバーの1人がゲームプロセスをDocker化することに成功しました。

k8sjp_42_2_アートボード 9

Docker化できたのは喜ばしいことですが、アーキテクチャががらっと変わってしまうため、今までに実装してきた各種の機能をもしかして実装しなおすことになるのでは?と不安になりました。

k8sjp_42_2_アートボード 10

しかしそんな時に現われたのがAgonesです。

k8sjp_42_2_アートボード 11

Agonesとは何でしょう。Agonesは、GoogleとUbisoftが協同で開発した、Kubernetes上にスケール可能なDedicated Game Serverを構築するためのライブラリです。Agonesを利用することで、オンラインゲームでのPvPマッチングシステムをKubernetes上に構築することが簡単にできるようになります。Google Cloudで "Game Server" というマネージドサービスが提供されています。軽く触ってみるのに良いかもしれません。

k8sjp_42_2_アートボード 12

さて、これまでのOOPartsで実装していた仕組みと、それが何故必要だったのかをおさらいします。

k8sjp_42_2_アートボード 13

まず「プレイ要求と待機中のインスタンスとのマッチング」ですが、OOPartsではあるコンテナにはある特定のユーザーを関連付けて、他のユーザーがそこに接続しに行くことがないようにしたいです。

k8sjp_42_2_アートボード 14

次に「プレイ中ユーザー数に応じた待機台数調整」ですが、コンテナ化したとはいえ、起動には少し時間がかかり、プレイ要求が来てからコンテナを起動していたのではユーザーを待たせてしまいます。なので、いくつかの余裕をもたせてコンテナを起動しておきたいです。

k8sjp_42_2_アートボード 15

最後に「プレイ中サーバーの保護」です。普通のWebアプリケーションが動くコンテナだと、短い間のリクエストを処理してしまえばすぐに終了することができます。OOPartsもといクラウドゲーミングでは、ユーザーがゲームをプレイしている間はコンテナ内に状態ができてしまい、ユーザーが明示的にゲームを終了するまではコンテナを落としたくありません。

k8sjp_42_2_アートボード 16

要件を軽くまとめると、クラウドゲーミングではステートフルで起動に時間がかかるプロセスをユーザーがプレイしている間は落とさずに、かつ、いくらかの余裕をもたせて運用する必要があります。

k8sjp_42_2_アートボード 17

そして、Agonesを利用することで、それらの課題を解決することができます。

k8sjp_42_2_アートボード 18

Agonesにあるいくつかの機能のうち、特にOOPartsで使用しているものがFleet、FleetAutoscaler、GameServerAllocationの3つになります。順に説明していきます。

k8sjp_42_2_アートボード 19

まずFleetです。これはGameServerというKubernetesにおけるPodのようなリソースを、指定した台数だけあらかじめ起動しておいてくれるCustom Resourceです。このGameServerは、待機中はReady、ユーザーが割り当てられるとAllocatedというstatusを持ちます。AllocatedになったGameServerは、例えば自動スケールを有効にしているクラスタにおいて、Nodeがスケールインの対象となった場合でもNode上にそのGameServerがある場合にはNodeが終了されないようになっています。

k8sjp_42_2_アートボード 20

次にFleetAutoscalerです、これは、プレイ中の人数に応じてどのくらいのGameServerを起動しておくかを制御する仕組みです。スライドにある定義だと、プレイ中のユーザーより2つ多く確保しておき、最低でも3つ、最高でも20だけ起動する、という指定になります。

k8sjp_42_2_アートボード 21

最後にGameServerAllocationです。これは、ReadyとなっているGameServerにユーザーを割り当てる仕組みです。様々な言語でSDKが提供されており、実際にゲームに組み込んで使うことが容易にできるようになっています。OOPartsでは、GoによるWeb APIを用意してWebブラウザからのリクエストをもとに割り当てを行うようにしています。

k8sjp_42_2_アートボード 22

さてそのような機能があるAgonesを導入してよかったことですが、まずscalabilityが向上しました。これまでの1プレイ1インスタンスの構成よりもはるかに高速にプレイ可能数を増減させられるようになりました。

そして、可観測性が向上しました。これまでマルチクラウドだったこともあり、CloudWatchやCloud Monitoringにメトリクスが分散していましたが、これをPrometheusによって一元化することができました。

もうひとつ、開発サイクルが高速に回せるようになりました。これまではAMIを作成して検証する、というフローであり、ここに大体1時間ほどかかっていましたが、これがdocker buildになることによって長くても数分という、かなり高速かつ容易にトライアンドエラーをくりかえすことが可能になりました。

k8sjp_42_2_アートボード 23

まとめます。Agonesはとても便利でした。出てきてから少し時間が経っているので、そろそろ国内でも採用事例がいくつか出てくるのではないかなと思います。そして、アーキテクチャのフルリニューアルはとても大変でした。もしAgonesが無かったらと考えると……

以上で発表を終わります、ありがとうございました。

当日の配信


投げ銭していただけるととても嬉しいです