Agonesが担う専用ゲームサーバーのライフサイクル管理
リアルタイムのマルチプレイヤーゲームでは、ゲームの進行を正しく裁定する権威あるサーバー方式が広く使われます。この専用ゲームサーバーをKubernetes上でホスティングし、マッチメイキングからサーバー割当、セッション管理までを束ねるオープンソース基盤がAgonesです。Agonesは Amazon EKS 上にデプロイでき、ゲームサーバーのスケールや割当をKubernetesの流儀で扱えるようにします。本稿はAWS公式ブログの実践記事を一次情報として、その設計思想をゲーム基盤の運用者やSREの視点で読み解きます。
Agonesはいくつかのカスタムリソースでゲームサーバーの一生を表現します。中心となるのがGameServerで、これはプレイヤーが接続するゲームサーバープログラムが動作するPodに対応します。GameServerは待機中を表すReadyと、実際にプレイに使われているAllocatedという状態を持ちます。Readyは差し替えても影響が小さい一方、Allocatedは進行中の対戦が乗っているため、途中で止めてはいけないという強い制約が生まれます。
複数のGameServerをまとめて管理するのがFleetです。Fleetは起動しておく数を宣言でき、Fleet Autoscalerによって需要に応じた増減を制御できます。実際にプレイへ割り当てる操作はGameServerAllocationが担い、待機中のGameServerを選んでAllocatedへ引き上げます。セッションが終わればそのGameServerは回収され、Fleetは新しいReadyを補充します。この割当と回収の循環が、専用ゲームサーバー運用の背骨になります。
ここで押さえたい要点は、Agonesが守ろうとしているのは進行中のゲームセッションであるという一点です。ノードやPodの都合でAllocatedなGameServerを不用意に落とせば、対戦がそのまま切断されます。だからこそAgonesは、後述するようにゲームサーバーを中断から守る仕組みを標準で備えています。そしてこの保護の思想が、ノード管理を自動化するEKS Auto Modeと交差したときに設計上の論点が立ち上がります。
EKS Auto Modeの自動化がもたらす運用上の制約
Amazon EKS Auto Modeは2024年12月に一般提供が始まった機能で、ノードのプロビジョニングやスケーリング、入れ替えといった運用をマネージドで肩代わりします。内部ではKarpenterによるノード自動管理が動き、ノードのOSにはBottlerocketが使われます。クラスタの構築と運用の負担を大きく下げられる一方で、ノード管理を握るのはAuto Mode側になるため、利用者が細かく手を入れられる範囲は狭まります。この自動と制約の綱引きが、Agonesにとっての勘所になります。
Auto Modeがノードを中断する契機は大きく四つあります。ひとつ目は利用率の低いノードのPodを集約してノードを畳むConsolidationです。ふたつ目は設定変更やAMI更新に追従してノードを入れ替えるDriftです。三つ目はセキュリティ維持のために一定期間が過ぎたノードを強制的に入れ替えるExpirationです。四つ目はSpotインスタンスの中断通知やハードウェア障害に応じたInterruptionです。いずれの中断でも、対象ノード上のPodにはSIGTERMが送られ、猶予期間を過ぎるとノードごと削除されます。

とりわけ運用設計に効いてくるのがExpirationです。Auto Modeはセキュリティ上の理由から、ノードの最大生存期間に21日というハードな上限を設けています。ノードの生存期間を決めるexpireAfterはこの上限を超えて延ばせず、時間が来たノードは新しいノードへ置き換えられます。パッチ適用のために古いノードを長く生かし続けるという逃げ道は用意されていないわけです。Agonesのようにゲームを途中で止めたくないワークロードにとって、この強制入れ替えは正面から向き合うべき前提になります。
Auto ModeとAgonesの保護機構が衝突する理由
Agonesは進行中のゲームを守るため、GameServerに退避可否を指定するspec.eviction.safeという設定を持ちます。取り得る値はAlways、OnUpgrade、Neverで、既定値はNeverです。Neverはゲームを最後まで走らせることを優先し、Kubernetesの自発的な退避を実質的に全面ブロックします。仕組みとしてはGameServerに退避を拒むラベルを付け、対応するPodDisruptionBudgetで守るかたちで、効果としては退避不可を意味する保護がかかります。
この標準の守りが、Auto Modeの自動中断と真正面から衝突します。退避を拒むPDBは、KarpenterのConsolidationだけでなく、AMI更新に伴うDriftや期限切れのExpirationまで押し返してしまいます。結果として、セキュリティパッチの適用が滞る、ノードの入れ替えが失敗し続ける、そして起動時刻の近いノードが期限を迎えたときに中断が一斉に集中しやすくなる、といった副作用が生まれます。ゲームを守るための設定が、ノードのセキュリティ更新を止めてしまうという皮肉な構図です。
さらにConsolidationが効かないことでコスト効率も損なわれます。本来ならまとめられるはずのまばらなノードが畳まれず、余分な計算資源を抱え続けることになるためです。つまりデフォルトのままでは、可用性は守れても、セキュリティとコストの両面で自動化の恩恵を取り逃がします。ここで必要なのは保護をやめることではなく、ゲームの中断を避けつつ中断そのものは受け入れる、という設計の切り替えです。
制約を踏まえた段階的な設計方針と回避策
元記事は、この衝突を解くための設計方針を複数の観点で示しています。核になる考え方は、猶予期間の大小関係を意図して積み上げることです。すなわちノード側の猶予がPod側の猶予より長く、Pod側の猶予がゲームの最大持続時間より長い、という並びを崩さないよう設計します。この関係が保たれていれば、中断が始まってもゲームが終わるまでの時間を確保でき、そのうえでノードは順当に入れ替わっていきます。

具体的な設計は次の観点で整理できます。いずれも元記事が挙げる設定例であり、数値はそのまま鵜呑みにするものではなく、自環境のゲーム特性に合わせて調整する前提の目安として捉えてください。
設計観点 | ねらい | 元記事の設定例と勘所 |
|---|---|---|
ノードの寿命と猶予 | 21日以内の入れ替えを保ちつつ一斉中断を避ける |
|
Podの終了猶予 | SIGTERM後にゲームを完走させる |
|
シグナル処理 | 状態に応じた安全な停止 | Allocatedなら対戦の終了を待って |
退避の許可 | Drift/Expirationを機能させる |
|
退避を許可へ切り替える発想が、この設計の要になります。spec.eviction.safeをAlwaysにすると、退避を拒んでいたPDBが外れ、DriftやExpirationが本来の役目を果たせるようになります。ゲームの保護は、Podの終了猶予とサーバー側のシグナル処理へと移譲されるわけです。あわせてconsolidationPolicyを空のノードだけ畳む方針にし、Disruption Budgetsで同時中断を抑えれば、中断は受け入れつつも一気に走らないよう手綱を握れます。
さらに元記事は、役割ごとにNodePoolを分けることを勧めています。Agonesのコントローラ系を載せるNodePoolと、GameServerを載せるNodePoolを分離し、それぞれに見合った猶予を与える設計です。コントローラ系は短時間の再起動が許されるため猶予を短めに、GameServerはゲームの長さに合わせて猶予を長めに取ります。配置はnodeSelectorで振り分け、コントローラやアロケータ、pingはコントローラ用ノードへ、GameServerはゲームサーバー用ノードへ寄せます。加えて、既定ではPDBが無効なアロケータとpingにも最小可用数を保つPDBを与えておくと、ノード中断のさなかでも割当リクエストの受け口を絶やさずに済みます。
導入手順とまとめ
実際の導入は、いきなり本番のFleetへ適用するのではなく、段階を踏むと安全です。まずは検証用クラスタでAuto Modeを有効にし、Agonesを既定設定のまま載せて、DriftやExpirationがPDBに押し返される様子を観察します。次にサーバーアプリへSIGTERMのハンドリングを実装し、Allocatedとreadyで停止の振る舞いを分けます。この土台ができて初めて、terminationGracePeriodSecondsやノード側の猶予を、ゲームの最大長を基準に決めていきます。
猶予の設計が固まったら、spec.eviction.safeをAlwaysへ切り替え、退避を許可します。ここで役割別のNodePool分離とDisruption Budgetsを併せて入れ、コントローラ系とGameServerで中断の当たり方を分けます。最後にアロケータとpingへPDBを付与し、割当経路の可用性を確保します。各段階で、進行中のゲームが中断されないか、ノードが21日以内に順当に入れ替わるか、パッチが遅延なく行き渡るかを確認しながら前へ進めるのが要点です。ロールバックしやすいよう、一度に一つの変更へ絞ることをおすすめします。
まとめると、EKS Auto ModeとAgonesの両立は、ゲームを守る保護をやめることではなく、守る責務を退避拒否から猶予期間とシグナル処理へ移し替えることで実現します。ノードの自動更新やコスト最適化という自動化の恩恵を受けながら、進行中の対戦は最後まで走らせる。この二律背反を、猶予の大小関係とNodePoolの分離という具体で解くのが本稿で紹介した設計の骨子です。実装にあたっては、本稿が一次情報として参照したAWS公式ブログ「Amazon EKS Auto Mode 上での Agones 実践」(https://aws.amazon.com/jp/blogs/news/agones-on-eks-automode-practice/)の設定例と、自環境のゲーム特性を突き合わせて調整することをおすすめします。








.webp?q=65&fm=webp&w=400&h=260&fit=crop)








