Agones Controller がダウンした状態で GameServer を落としたらどうなるか確認する

世の中には Kubernetes 上でゲームの状態を管理するステートフルなサーバ(以下 GameServer)をいい感じに管理する Agones という OSS が存在します。 GameServer を管理するために Agones は Controller というコンポーネントを必要とするのですが、今回はこの Controller がダウンした状態で GameServer を削除してみたらどうなるかというのを検証してみました。

Agones とは何か、雑に説明する

Agones とは UbisoftGoogle が共同で開発している、 Kubernetes 上で GameServer を管理するためのライブラリです。 オンラインでのマルチプレイを実現する方式として、ユーザの機器同士を直接 P2P で繋げる方式とサーバ(GameServer)を経由する方式が考えられます。

Agones はこのうち後者の方式で使用される GameServer のためのライブラリです。 このような GameServer は生存期間が比較的短い(ゲームの1プレイと対応することが多いため、数分〜数時間)ためにコンテナや Kubernetes との相性がいいと考えられます。 そのため、 GameServer の管理に Kubernetes を使いたいという欲求が発生しますが、そのまま Kubernetes を用いると問題があります。 たとえば、 Kubernetes は GameServer がマルチプレイを実行中か判別することができないので、マルチプレイ中の GameServer(が動く Pod)を唐突に落とす可能性があります。 この場合、プレイ中のゲームセッションが唐突に終了してしまうので大変困ったことになっていまいます。 Agones はマルチプレイ中の GameServer が落とされるのを防いでくれるなどの機能を持っています。

Agones 自体については↓の記事などが詳しく解説してくれているので、気になったら読んで頂くといいと思います。

medium.com

本題: Agones の Controller が落ちたときってどうなるの?

GameServer などを管理するため、 Agones は Controller というコンポーネントKubernetes 上に立てます。 Controller のおかげで GameServer が管理されているのですが、実際に Agones を使用するとなると Controller が落ちたときに GameServer はどんな挙動をするのだろうというのが気になってきます。 気になってきたので Controller を落とした状態で GameServer を操作しようとしたらどうなるかというのを検証していました。 その過程で GameServer を削除しようとしてみたときに面白い挙動が見えたので、この記事ではそれを解説しようと思います。

さっそくですが、検証方法と結果は GitHub に上げてあります。 やり方とかはこっちに書いてあるので、具体的な操作やソースコードが気になる人は見てください。 なんなら結果も書いてあります。

github.com

検証内容

どのような検証をしたかというと、

  • 検証環境は minikube で作成
  • 削除する方法は以下の2通りが考えられたので2つを検証
    • kubectl delete gs などの Delete API を呼ぶことで直接削除する
    • kubectl edit gs などで GameServer の STATE を Shutdown にすることで Controller に削除してもらう
  • GameServer の操作は kubectl と Go によるプログラムの2通りを試す
    • 削除する方法2通り × 操作方法2通り = 4通りの操作を検証

といった感じです。

検証結果

検証結果はこんな感じになりました。

シェル経由で直接削除した場合

Controller が動いているときは当然 GameServer は削除されるんですが、削除される GameServer の STATE は直前まで Ready のままでした。 消される GameServer に割り当てが発生したりしないか不安です。

Controller がダウンしているときは kubectl のプロンプトが返ってきません。 しょうがないので Controller を立ち上げ直すと削除されてプロンプトが返ってきました。

プログラム経由で直接削除した場合

Controller が動いているときは当然 GameServer は削除されて、シェル経由の場合と同様 STATE は Ready のままでした。

Controller がダウンしているときはシェル経由の場合と異なりプログラムがブロックされることはなく、何も起きずにプログラムが終了しました。 その後 Controller を立ち上げ直すとそのうち削除されました。

シェル経由で STATE を Shutdown にした場合

Controller が動いているときは GameServer が削除されます。 削除される前に STATE が Shutdown になるので(STATE を書き換えているのでそれはそう)、割り当てが発生しなさそうな雰囲気があります。

Controller がダウンしているときは STATE が Shutdown になるだけで、 GameServer が削除されたり下の Pod が落ちたりはしません。 Controller を立ち上げ直すとそのうち削除されます。

プログラム経由で STATE を Shutdown にした場合

シェル経由と同じ挙動でした。

感想・考察

どうにせよ Controller がダウンしてたら GameServer が落ちないのは変わらないんですが、削除する方法によって STATE が更新される・されないといった違いが生まれました。 STATE が更新された方が事故が起きにくそうで良さそうな気がします。 本当に事故が起きるか起きないかは検証したほうが良さそうな気がします。 そのうちやるかも。

また、シェル経由で削除するかプログラム経由で削除するかでも微妙な違いが生まれたり生まれなかったりしました。 ここらへんは作りの違いって感じがするのでふ〜んって感じですね。

まとめ

Agones の Controller を落としたときに GameServer を削除しようとしたらどうなるかを検証しました。 直接削除するか STATE を書き換えるかの2択があるんですが、後者のほうが治安が良さそうな気がします。 本当に治安がいいかは要検証ですが。