ゲーム - TECH PLAY - TECH PLAY

TECH PLAY

ゲーム

イベント

マガジン

技術ブログ

はじめに リアルタイム性の高いマルチプレイヤーゲームは、複数のプレイヤーの入力を集約し、ゲームの状態を一貫させて全員へ配信する仕組みを必要とします。この仕組みの一つに、権威あるサーバーがゲームの状態を管理する専用ゲームサーバー (Dedicated Game Server) 方式があります。対戦の公平性やチート対策、多人数の同時接続が求められるタイトルでは、専用ゲームサーバー方式が広く採られています。この方式では、マッチメイキング、ゲームサーバーの割り当て、セッション終了後のサーバー回収といったライフサイクル管理が必要になり、そのオーケストレーション基盤をどう構築・運用するかが設計上の大きなテーマとなります。 AWS で専用ゲームサーバーをホストする主な選択肢は、マネージドサービスの Amazon GameLift Servers を利用するか、 Amazon Elastic Compute Cloud (EC2) や Amazon Elastic Container Service (ECS) 、 Amazon Elastic Kubernetes Service (EKS) 上でセルフホストするかの 2 つです。GameLift Servers はインフラ構築・運用の大部分を担いますが、要件によってはより柔軟な制御が必要な場合があり、 Agones の利用が選択肢の一つとなります。Agones はオープンソースの専用ゲームサーバーホスティング向け製品で、Amazon EKS 上にデプロイでき、柔軟性を享受しつつ専用ゲームサーバーの構成を簡素化できます。しかし Kubernetes 基盤の運用は避けられず、Agones の運用には一定の負荷が存在しました。 2024 年 12 月に一般提供が始まった Amazon EKS Auto Mode は、Kubernetes の構築・運用負担を低減する機能です。Agones の基盤となる EKS クラスタで EKS Auto Mode を利用できれば、専用ゲームサーバーを柔軟かつ簡素に構築・運用できます。ただし EKS Auto Mode にはいくつかの制約もあります。 本記事では、EKS Auto Mode の制約が Agones の特性を阻害しないようにするための設計方針を紹介します。 Agones リソースの概要 本記事の内容に関連する Agones カスタムリソースについて説明します。 GameServer: プレイヤーが接続するゲームサーバープログラムが動作する Pod にあたるリソースです。状態を持ち、Ready 状態はゲーム開始可能で待機している状態、Allocated 状態はゲームプレイのためにリソースが確保された状態を表します。 Fleet: GameServer のまとまりを管理するためのリソースです。常に起動しておくべき GameServer リソースの数を指定でき、Fleet Autoscaler リソースによるスケーリング制御も可能です。 GameServer Allocation: ゲームプレイのために GameServer リソースを選択し確保する操作を行うリソースです。この操作により選択された GameServer リソースは Ready 状態から Allocated 状態となります。 コントローラ系リソース: Agones の機能を実現・制御するためのリソース群です。 EKS Auto Mode と Agones の共存における課題 EKS Auto Mode は、クラスタのノード管理を AWS の責任範囲で自動化します。例えば Karpenter をベースとしたノードのプロビジョニング・スケーリング・入れ替え、Bottlerocket による最適化された OS、各種アドオンのマネージド管理といった機能により、Kubernetes の運用を大幅に簡素化できます。 一方、ユーザー側で設定できる範囲が狭まるというトレードオフがあります。Agones の基盤として特に考慮が必要なのは、EKS Auto Mode が以下の目的のために自動で行うノードの中断です。 Consolidation: 稼働中の Pod が少ないノードを終了し、利用率の高いノードへ Pod を集約してコストを最適化する。 Drift: NodePool や NodeClass の設定変更、AMI の更新などに追従してノードを入れ替える。 Expiration: セキュリティ維持のため、一定期間が経過したノードを強制的に入れ替える。 Interruption: Spot Instance の中断通知やハードウェア障害などに応じてノードを終了する。 ※EKS Auto Mode の長期実行ワークロードでの扱いについては、builders.flash 記事「 Amazon EKS Auto Mode のノード自動更新を Deep Dive する 」もあわせて参照ください。 いずれの中断でも、対象ノード上の Pod へ SIGTERM が発行されます。Agones上で動かすような専用ゲームサーバーには「プレイ中のゲームセッションを中断させない」という強い制約があるため、対策をしないとプレイ中のゲームサーバーが強制終了されるリスクがあります。 EKS Auto Mode と Agones を共存させる設定のポイント そこで、Agones のコントローラ系とゲームプレイ中のサーバープログラムをノードの中断から保護する仕組みを、次の 6 つのポイントで構成します。以降、それぞれのポイントについて、実際の設定ファイル ( nodepools.yaml / fleet.yaml / agones-values.yaml ) を引用しながら、具体的な実装方法を説明します。 Point # 対象 内容 Point 1 共通 NodePool の expireAfter 、 terminationGracePeriod を適切に設定する Point 2 GameServer GameServer の Pod の terminationGracePeriodSeconds をゲームの最大持続時間より長い値に設定する Point 3 GameServer GameServer 上で動くサーバーアプリで、適切なシグナルハンドリングを実装する Point 4 GameServer Eviction を許可してノードの自動最適化を機能させる ( spec.eviction.safe: Always ) Point 5 コントローラ系 Agones コントローラ系と GameServer が配置される NodePool を分ける Point 6 コントローラ系 agones-allocator と agones-ping の PDB を有効にする Point 1 (共通) :NodePool の expireAfter / terminationGracePeriod を適切に設定する EKS Auto Mode では、ノードは必ずいつか中断されます。特に Expiration はノード生存期間最大21日の制約があり、必ず発生します。この expireAfter の値と、ノードが強制的に中断されるまでの猶予期間である terminationGracePeriod を、ワークロード特性に合わせて NodePool に設定することが起点になります。 NodePool とは、Karpenter ベースのノード管理機能で、Pod の要求に応じてインスタンスを自動的にプロビジョニング・スケーリングし、クラスターのコンピュートリソースを柔軟に管理するための仕組みです。 設定にあたっては、次の関係を守るようにしてください。 terminationGracePeriod は、後述する Pod の terminationGracePeriodSeconds より長く設定する (ノードが強制削除される前に、Pod が Graceful に終了しきるようにするため) 。 expireAfter + terminationGracePeriod の合計は最大 21 日に収める (EKS Auto Mode の制約) 。 また disruption.budgets の nodes: "10%" (NodePool Disruption Budgets: NDB)により、同時に中断処理へ入るノード数を全体の 10 % に制限し、一斉中断の影響を抑えます。 consolidationPolicy: WhenEmpty については Point 4 で触れます。 Point 1 を踏まえた NodePool の設定例は次の通りです( nodepools.yaml )。 # GameServer 用 NodePool apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: agones-worker spec: template: spec: # Point 1: ゲームセッション時間を考慮して設定 # terminationGracePeriod は Pod の terminationGracePeriodSeconds より長くすること expireAfter: 336h # 14日 terminationGracePeriod: 4h # expireAfter + terminationGracePeriod が21日(504h)に収まるように disruption: consolidationPolicy: WhenEmpty consolidateAfter: 30s budgets: - nodes: "10%" Point 2(GameServer):Pod の terminationGracePeriodSeconds をゲーム最大持続時間より長く設定する ノードが中断され Pod に SIGTERM が発行されてから、Pod が強制終了(SIGKILL)されるまでの猶予が terminationGracePeriodSeconds です。この値をゲームの最大持続時間より長く設定することで、進行中のゲームが途中で強制終了されることを防ぎます。 terminationGracePeriodSeconds は Pod リソースの設定値ですが、Agones では GameServer リソース定義内で設定することになります。また GameServer の制御は Fleet で行うことが一般的なため、ここでは Fleet の設定例を次の通り示します ( fleet.yaml ) apiVersion: "agones.dev/v1" kind: Fleet metadata: name: simple-game-server-fleet spec: replicas: 3 template: spec: # ... (省略) template: spec: # Point 2: ゲームセッション最大持続時間 + バッファより長い値を設定 # 例: ゲーム最大30min + クリーンアップ5min = 35min = 2100sec terminationGracePeriodSeconds: 2100 ゲームセッション 1 つの最大持続時間に、クリーンアップ処理のバッファを加えた値を設定します。Point 1 の terminationGracePeriod (ノード側の猶予) を、この terminationGracePeriodSeconds (Pod 側の猶予) より長く設定することで、 terminationGracePeriod > terminationGracePeriodSeconds > ゲーム最大持続時間 の関係が成立し、プレイ中のゲームを保護できます。 まとめると、 以下を満たすように各パラメータを設定すればよいことになります。 NodePool の terminationGracePeriod > Pod の terminationGracePeriodSeconds > ゲームの最大持続時間 NodePool の expireAfter は自由 ( terminationGracePeriod との合計は 21 日以下) Point 3 (GameServer) :適切なシグナルハンドリングを実装する Point 1・2 で猶予期間を確保しても、SIGTERM を受け取ったサーバープログラムが適切に振る舞わなければ、ゲームサーバーは安全に終了できません。GameServer 上で動くサーバープログラムでは、SIGTERM を受信したときに次の動作を実装します。 Allocated 状態 (ゲーム進行中) :進行中のゲームの終了を待ち、クリーンアップ処理を行った後に Agones SDK の sdk.Shutdown() を呼び出す。 Ready 状態 (待機中) :新規 Allocation を防ぐため、即時 sdk.Shutdown() を呼び出す。 この実装により、ノード中断のシグナルを受けても、進行中のゲームを守りつつ、待機中のサーバーは速やかに退去できます。 Point 4 (GameServer) :Eviction を許可してノードの自動最適化を機能させる ( spec.eviction.safe: Always ) Point 1〜3 でプレイ中のゲームを保護できたら、次に Agones の spec.eviction.safe を Always に設定し、EKS Auto Mode によるノードの自動最適化を機能させます ( fleet.yaml ) 。 spec: template: spec: # Point 4: eviction.safe を Always に設定 # Karpenter の Drift/Consolidation/Expiration 時に Graceful な Eviction を許可する eviction: safe: Always spec.eviction.safe は、各 GameServer の Pod に対して Agones が内部的に作成する PDB ( maxUnavailable: 0% ) を有効化するかどうかを制御します。デフォルトの Never の場合、常に eviction をブロックする動きとなります。 (表は https://agones.dev/site/docs/advanced/controlling-disruption/ より) Never のままでは、この PDB がすべての Eviction をブロックし、EKS Auto Mode 環境で次の問題が発生します。 Karpenter が Consolidation / Drift を試みても Pod に SIGTERM が発行されず退去しないため、Cordon 状態のノードが既存 Pod ごと残り続け、コスト効率が悪化する。 Drift (AMI 更新) が PDB にブロックされ、セキュリティパッチの適用が遅延する。 上記の動作の結果、近い時間帯に起動した全ノード上の Pod が Expiration まで生存し続け、それらの Pod が近い時間帯に一斉に SIGKILL されるリスクが生じる。 Always を設定すると Agones のネイティブ PDB が無効化され、Eviction が許可されます。Pod が稼働中のノードでも Drift による AMI 自動更新と、Expiration 時の Graceful なノード入れ替えが機能するようになります (Never ではこれらが PDB にブロックされます) 。プレイ中のゲームの保護は Point 1〜3 で確保した猶予期間とシグナルハンドリングが担保するため、Always にしても進行中のゲームが即座に切断されることはありません。 Always の設定でも安全に運用する目的で、Point 1 で設定した consolidationPolicy: WhenEmpty (Pod が残っているノードでは Consolidation を発動させない) と NDB ( nodes: "10%" 、同時中断ノード数の制限) を補完策として組み合わせます。Always は Drift / Expiration を有効に機能させる一方、Consolidation まで WhenEmptyOrUnderutilized にすると稼働中 Pod のあるノードも集約対象となりゲームサーバーが頻繁に Evict され得るため、Consolidation は WhenEmpty に絞り、空ノードの回収のみに留めます。Agones の Fleet 設定 spec.scheduling の値はデフォルトで Packed となっており、できるだけ既に GameServer が動作しているノードに新規 GameServer を起動するようにスケジュールするため、 WhenEmpty の設定でも十分なコスト最適化効果が見込めます。 Point 5 (コントローラ系) :Agones コントローラ系と GameServer の NodePool を分ける Point 1 で設定した expireAfter / terminationGracePeriod は NodePool 単位の設定です。Agones のコントローラ系 (controller / extensions / allocator / ping) と GameServer では、必要な猶予期間が異なります。 コントローラ系: 短時間の再起動が許容されるため、長期安定稼働を優先しつつ猶予は比較的短くてよい。 GameServer: ゲーム最大持続時間に対応した長い猶予 ( terminationGracePeriod ) が必要。 そこで、コントローラ系用と GameServer 用で NodePool を分離します ( nodepools.yaml ) 。 # コントローラ用 NodePool apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: agones-controller spec: template: metadata: labels: agones-role: controller # ラベルで役割を区別 spec: # コントローラは長期安定稼働を優先 expireAfter: 336h # 14日 terminationGracePeriod: 72h # 3日 --- # GameServer 用 NodePool (Point 1 で前掲) # labels: agones-role: gameserver / terminationGracePeriod: 4h そのうえで、GameServer 側は Fleet の nodeSelector で GameServer 用 NodePool を指定します ( fleet.yaml ) 。 template: spec: # Point 5: GameServer 用 NodePool にスケジュール nodeSelector: agones-role: gameserver コントローラ系は、Agones の Helm Values で nodeSelector を指定し、コントローラ用 NodePool に配置します ( agones-values.yaml ) 。 agones: controller: # Point 5: コントローラ用 NodePool にスケジュール nodeSelector: agones-role: controller extensions: nodeSelector: agones-role: controller allocator: nodeSelector: agones-role: controller ping: nodeSelector: agones-role: controller これにより、それぞれのワークロード特性に合った猶予期間を両立できます。 Point 6 (コントローラ系) :agones-allocator と agones-ping の PDB を有効にする 前述の通り EKS Auto Mode ではいつか必ずノードの中断が発生するため、Agones のコントローラ系サービスでも可用性維持のための設定が重要です。agones-allocator (ゲームサーバーの割り当てリクエストを受け付けるサービス) と agones-ping (レイテンシー計測用サービス) はデフォルトで PDB が無効のため、ノードが中断されてもこれらが全停止しないよう、PDB を有効化します ( agones-values.yaml ) 。 agones: allocator: replicas: 3 # Point 6: allocator の PDB を有効化 pdb: enabled: true minAvailable: 1 ping: replicas: 2 # Point 6: ping の PDB を有効化 pdb: enabled: true minAvailable: 1 minAvailable: 1 により、ノード中断時にも最低 1 レプリカが稼働し続けることを保証し、コントロールプレーンの可用性を維持します。 なお、agones-controller, agones-extensions はデフォルトで PDB が有効となっています。 さらに安定した運用のための補足 (レアケースへの対処) Point 1〜6 の設計により、通常のノード中断からのゲームサーバー保護を実現できます。さらに安定した運用のためには、次のレアケースへの対処も検討ポイントになります。いずれも各実装に依存するため、必要に応じて検討してください。 GameServerAllocation のレースコンディション Ready 状態の GameServer が SIGTERM を受信した直後から Shutdown 完了までの間に、GameServerAllocation によって Allocate される可能性がゼロではありません。これが起こると、プレイヤーが接続するころには Allocate された GameServer が既に停止しておりエラーとなるリスクがあります。以下はこれを防ぐ方法の例です。 GameServer にあらかじめラベル ( allocationblock=false 等) を付与し、GameServerAllocation 側でそのラベルを持つ Pod のみを対象とする設定を行う。SIGTERM 受信時には即座にラベルを外す。ラベル削除後も一定時間待機し、その間に Allocate された場合はゲームを継続し、終了後に Shutdown する。 起動中 Pod への SIGTERM 発行時のハンドリング不可 コンテナ起動中 (Starting / ContainerCreating) に SIGTERM が発行されると、アプリケーション側でハンドリングできず、GameServer は正常に起動し Ready 状態となる一方、 Pod は terminationGracePeriodSeconds 経過後に停止してしまう動作となり、ゲームを保護できません。これを防ぐには以下の方法が例として挙げられます。 対策例 1: GameServer にあらかじめラベル (allocationblock=false 等) を付与し、GameServerAllocation 側でそのラベルを持つ Pod のみを対象とする設定を行う。外部コントローラで Pod の deletionTimestamp を監視し、非 null、つまり削除予定がある状態なら、前述の Allocation 用ラベルを外し、新規 Allocation を防ぐ。 対策例 2: イメージサイズの削減・DaemonSet 等による事前 pullといった方法で起動時間短縮を図り、発生確率を最小化する。 まとめ 本記事では、Agones の基盤に EKS Auto Mode を採用する際、ノードの自動中断からゲームサーバーを保護する設計を 6 つのポイントで紹介しました。専用ゲームサーバーのセルフホストで、Agones の柔軟性を活かしつつ EKS Auto Mode で運用管理をシンプルにするには、EKS Auto Mode のノード中断と Agones のゲームサーバーライフサイクルの競合を解消する設計が鍵になります。 本記事で紹介した Point 1〜6 の設計パターンと実装例 ( nodepools.yaml / fleet.yaml / agones-values.yaml ) が、EKS Auto Mode 上での Agones 導入を検討する方の参考になれば幸いです。
1. はじめに これまで、AWS AI League Community Editionについて、以下の記事で全体像とデプロイ方法を紹介しました。 AWS AI Leagueを自身のAWS環境で試す ─ Community Editionの全体像 AWS AI Leagueを自身のAWS環境で試す ─ Community Editionのデプロイ 前回の記事では、Community Editionを自身のAWSアカウントへデプロイし、ブラウザからログインできるところまで確認しました。今回は、実際に Game Play を実行してみます。 Community Editionでは、用
大阪開催の経緯 みなさん、こんにちは。AWS アカウントマネージャーの岩上です。 2026年7月2日、AWS 大阪オフィスにて 「Claude , Kiro実践ワークショップ」 を開催しました。参加者35社62名、満足以上の回答率98% という結果を頂きました。 本ワークショップの基本的なプログラム構成や背景については、先行して公開している 麻布台オフィス開催のブログ記事 をご参照ください。本記事では大阪開催の特徴であるOSPホールディングス様のユーザー登壇にフォーカスしてお伝えします。 OSPホールディングス様のユーザー事例登壇 大阪開催では新たな試みとして、ワークショップ参加企業である OSPホールディングス様 に事例登壇いただきました。IT企画課の桒原様が15分間、自社での取り組みと成果を共有してくださいました。 登壇の背景 OSPホールディングス様は、4月にアカウントチームで実施したAIコーディングワークショップをきっかけに、Kiroの全社活用に向けた取り組みを開始されました。わずか 3ヶ月で30名規模の利用体制を構築 されています。 特筆すべきは、IT企画課の桒原様が 自ら社内勉強会を企画・実施し、継続的にアクティブユーザーを増やしていく動き をされている点です。ワークショップをきっかけにお客様自身が推進役となり、組織を動かしていく — まさに理想的な展開です。 登壇内容のハイライト    生産性向上の実績 (Before→After/効率化倍率)  ・メールアーカイブ作業(514時間→3時間/171倍)  ・会計データの見える化(半年→3日/60倍)  ・受注分析(1週間→3時間/57倍)  推進のポイント  ・ワークショップ参加(10名)→ 社内勉強会(30名)→ 実務伴走と段階的にスケール  ・ゲーム開発を題材に若手〜ベテランまで楽しく体験  ・4テーマ×計8回の推進リーダーによる伴走支援で実務定着 なぜユーザー登壇が効果的だったのか アンケートでも好評だったように、 実際に推進されたお客様の生の声は説得力が違います。 参加者にとって「自社でもできるかもしれない」という実感につながり、ワークショップ本編のハンズオンに対するモチベーションも高まりました。 OSPホールディングス様は今後、一般業務部門展開 → PoC拡大 → 全社展開へと進んでいかれます。 アプリ発表事例 大阪開催でもハンズオン後に参加者がアプリ発表を行いました。代表的な発表を紹介します。 在宅勤務管理アプリ :在宅している人が分かりにくいという課題を解決。上司向けにカレンダーや上限チェックのタブを設置 市場・技術動向ニュース配信アプリ :丸一日かかりそうな調査が5分程度で完了する所感。リンクもクリックして遷移可能 交通費経費精算自動化アプリ :モバイルICOCAの履歴データをアップロード → 文字読み取り → 精算書PDF保存 マラソン練習メニュー提案アプリ :レースの種類・目標タイム等を入力するとランニングコースを提案。Google Map連携やシューズDBへの接続まで実装 旅行ルート比較アプリ :距離やマイルなどかなり正確な結果。指示していないプレミアポイント表示もKiroが自動実装 サカイ引越センター 経営企画部 森田様の旅行ルート比較アプリの発表 大阪開催ならではの工夫 大阪開催ではワークショップ終了後に ピザ懇親会 を実施しました。 Amazonには「2 Pizza Rule(2枚のピザで足りる人数=6〜8名がチームの理想サイズ)」という考え方があります。小さなチームだからこそ迅速に意思決定でき、オーナーシップを持って動ける — この考え方はAIコーディングツールの社内展開にもそのまま当てはまります。 懇親会ではまさに2枚のピザを囲む規模感のテーブルで、参加者同士が「うちの会社ではこう使い始めた」「こういう課題にぶつかった」という率直な会話を交わしていました。ワークショップ本編では聞けなかった各社の生の悩みや工夫が共有され、 企業の垣根を超えた横のつながりが生まれる場 となりました。 OSPホールディングスの桒原様も「登壇資料を見せてほしい」と声をかけられる場面があり、ユーザー事例登壇と懇親会のセットが参加者間のナレッジシェアを加速させる効果を実感しました。 まとめ 大阪開催では、ユ ーザー事例登壇 という新しい要素を加えることで、単なるツール体験に留まらない 「自社での展開イメージ」 を参加者に提供できました。 OSPホールディングス様のように、ワークショップをきっかけにお客様自身がチャンピオンとなり組織を動かしていく流れは、AIコーディングツールの導入における理想的なモデルです。ツールを配るだけでは組織は変わりません。現場の担当者が「自分ごと」として推進し、成功体験を社内に広げていくことが、継続的な業務変革につながります。 本ワークショップの基本的な設計思想やプログラム構成の詳細については、 麻布台オフィスでの開催記録 をご覧ください。 ワークショップ後の支援 AWS では、ワークショップで「自分でも作れる」と実感いただいた後も、お客様の状況に応じた継続支援をご用意しています。活用方法の共有会、業務課題の深掘り、セキュリティ面の技術説明など、次のステップについては担当のアカウントマネージャーまでお気軽にご相談ください。 本記事公開時点では、当該ワークショップは招待制のイベントとなります。AWS側の担当者がお客様の状況を鑑みてご案内差し上げておりますので、予めご了承ください 。 関連リンク Claude Desktop セットアップガイド(Zenn) Kiro IDE セットアップガイド(Zenn)

動画

書籍