【入門編】Kruise Gameで実現するゲームサーバーのKubernetes運用:スケールダウン保護とプレイヤーセッション維持の裏技 – インフラ構成管理(IaC)活用バイブル

こんにちは!インフラエンジニアの先輩です。

今日は、Kubernetesの世界で多くのインフラエンジニアが頭を悩ませる「ゲームサーバーの運用」について、ちょっとワクワクする話をしようと思います。

「Kubernetesって、Webアプリのオートスケーリングは得意だけど、プレイヤーが対戦中のゲームサーバーを勝手にシャットダウンしちゃうから使えないよね?」
そんな風に思っていませんか?

もしあなたが、プレイヤーの試合中にポッド(Pod)が容赦なく刈り取られる絶望を味わったことがあるなら、今回の記事はまさにあなたのためのものです。

今回は、OpenKruiseというK8sの強力な拡張エコシステムが提供する「Kruise Game」を使って、「スケールダウン保護」と「プレイヤーセッションの維持」を完璧に実現する方法を、優しく、かつ徹底的に解説していきます。

これをマスターすれば、深夜の緊急アラートに怯えることなく、美しくスケーラブルなゲームインフラを手に入れることができますよ。さあ、一緒に深淵を覗いてみましょう!

—

1. なぜゲームサーバーのK8s運用は難しいのか?

普通のWebアプリケーションなら、K8sが裏側でPodを勝手に消して新しいPodに置き換えても、ユーザーは数秒のロードやリトライで済みます。

しかし、マルチプレイのゲームサーバーはどうでしょう?

  • プレイヤーがまさに白熱したバトルを繰り広げている最中にPodが消されたら?
  • ローリングアップデートで全サーバーが再起動され、全員強制送還されたら?(プレイヤーは二度とそのゲームを遊んでくれません)

つまり、ゲームサーバーには「ステートフル(状態保持)かつ、人間の都合(セッションの終了)を待たなければならない」という、クラウドネイティブの基本思想(使い捨ての原則)に真っ向から逆らう要件があるのです。

ここで登場するのが、Kubernetesの標準機能を超えたオーケストレーションを実現する「OpenKruise(Kruise Game)」です。

—

2. Kruise Gameとは何か?

OpenKruiseは、Alibaba Cloudなどが主導し、CNCF(Cloud Native Computing Foundation)のプロジェクトとしても知られる、Kubernetesの拡張スイートです。その中のゲーム特化型モジュールが「Kruise Game」です。

Kruise Gameは、ゲームサーバー特有のライフサイクル(スケーリング、アップデート、プレイヤーステータスの管理)をKubernetes上で完全にコントロールするためのカスタムリソース(CRD)を提供してくれます。

これを使うことで、以下の神機能が手に入ります。
1. スケールイン保護: 稼働中の(プレイヤーがいる)ゲームサーバーを絶対に勝手に削除させない。
2. プレイヤーステータスの可視化: 「今、このサーバーに何人繋がっているか」をK8s側で認識できる。
3. 安全なローリングアップデート: 試合が終わったサーバーから順に、優雅にアップデートを適用する。

—

3. 環境構築と基礎セットアップ

前置きはこのくらいにして、実際に手を動かしてみましょう。
ここでは、すでにローカル(MinikubeやKindなど)またはクラウドのKubernetesクラスターが手元にあり、`kubectl`が使える前提で進めますね。

ステップ1: OpenKruiseのインストール

まずは、クラスターにOpenKruiseを導入します。公式のHelmチャートを使うのが一番安全で確実です。

Helmリポジトリを追加
helm repo add openkruise https://charts.openkruise.io
helm repo update

OpenKruiseコントローラーのインストール
helm install openkruise openkruise/openkruise –version 1.5.0

数分待って、すべてのポッドが `Running` になっていることを確認してください。

kubectl get pods -n kruise-system

「おっ、順調ですね!」このコントローラーが、あなたのクラスターにゲームサーバーを護る魔法をかけてくれます。

—

4. 実践:GameServerSetのデプロイ

Kruise Gameでは、通常の `Deployment` や `StatefulSet` の代わりに、`GameServerSet` という専用のリソースを使います。

これが今回の主役です。以下のYAMLファイル(`gameserverset.yaml`)を見てください。丁寧にコメントを入れています。

apiVersion: game.kruise.io/v1alpha1
kind: GameServerSet
metadata:
name: awesome-fps-server
namespace: default
spec:
# 常に起動しておくゲームサーバーの数
replicas: 3

# スケールイン(縮退)時のポリシー設定
scaleStrategy:
# 削除から保護する条件(例: プレイヤーが接続中のサーバーは消さない)
workloadSpread: []
# 削除対象を選ぶ優先順位(例: 最もプレイヤー数が少ないサーバーから削除)
podDeletionCost:
enabled: true

# ここで通常のPodテンプレートを定義します
podTemplate:
metadata:
labels:
app: fps-game-server
spec:
containers:

  • name: game-server

image: your-registry.example.com/fps-game-server:v1.0.0
ports:

  • containerPort: 7777

protocol: UDP
name: game-port
# ヘルスチェックやプレイヤーステータス取得用のサイドカーなどをここに置くことも多いです

このマニフェストを適用してみましょう。

kubectl apply -f gameserverset.yaml

これで、Kruise Gameによって管理された3つのゲームサーバーが立ち上がりました。

—

5. 裏技の核心:スケールダウン保護とセッション維持の仕組み

さて、ここからが本題です。「どうやってプレイヤーの切断を防ぐのか?」のカラクリを解説します。

Kruise Gameは、ゲームサーバー内部で動いているアプリケーションと連携するために、HTTP API(またはカスタムサイドカー)を利用します。

ゲームサーバー(アプリ側)は、自身の状態をKruise Gameのコントローラーに教えてあげる必要があります。たとえば、以下のようなJSONステータスを返せるように実装しておきます。

{
“currentState”: “NotReadyToScale”, // プレイ中だから消さないで!
“playerCount”: 4 // 現在4人プレイ中
}

スケールイン(縮退)の瞬間

あなたが何らかの理由で、サーバー数を `3` から `1` に減らそうと、replicasを書き換えたとします。

1. 通常のK8sなら、ランダムに2つのポッドが即座に強制終了されます(悲劇)。
2. しかし、Kruise Gameを使うと、コントローラーは各ゲームサーバーに「今消しても大丈夫?」と確認(あるいはステータスをチェック)します。
3. サーバーA:「いま試合中だから無理!」(`NotReadyToScale`)
4. サーバーB:「いま誰もいないよ、暇だよ!」(`ReadyToScale`)
5. 結果: Kruise Gameは安全な「サーバーB」だけを優しく削除し、プレイヤーがいる「サーバーA」は死守します。

プレイヤーが全員ゲームを終え、サーバーAが `ReadyToScale` に変わった瞬間、初めてそのポッドは静かに役目を終えるのです。この優しさ、泣けてきませんか?

—

6. ローリングアップデート時のセッション退避

アップデートの時も同様です。バージョン `v1.0.0` から `v1.1.0` にアップデートする際、Kruise Gameは「インプレース(In-Place)アップデート」や「段階的なPodの入替え」をサポートしています。

ゲームサーバーの場合、急に全台を再起動するのではなく、「新規のロビーサーバーとしては受付を停止(Drain状態)し、既存の試合が終了するのを待ってからポッドを再作成する」という挙動が理想です。

Kruise Gameのマニフェストに以下のようなライフサイクルフックを組み込みます。

spec:
updateStrategy:
type: RollingUpdate
# プレイヤーのセッション終了を考慮したローリングポリシー
podUpdatePolicy: InPlaceIfPossible

これにより、プレイヤーエクスペリエンス(UX)を一切損なうことなく、シームレスなCI/CDパイプラインをゲーム開発チームに提供できるようになります。

—

おわりに

今回は、Kruise Gameを用いたゲームサーバーのスケールダウン保護とセッション維持の裏技について解説しました。

  • OpenKruise / Kruise Gameを導入することで、Kubernetesが本来苦手とする「ステートフルかつ人間の都合を考慮したライフサイクル管理」が可能になること。
  • プレイヤーが接続中のポッドを誤って殺さないための「スケールイン保護」の仕組み。

これをマスターすれば、あなたの管理するゲームインフラは、鉄壁の安定性とクラウドの柔軟性を同時に手に入れることができます。「毎日の作業が劇的に楽になる」どころか、プレイヤーからのクレームがピタッと止まる快感を味わえるはずです。

インフラの裏側で、こうした緻密な配慮が動いている――これぞプロフェッショナルなSREの醍醐味ですね。ぜひ、あなたのステージング環境で試してみてください!

タイトルとURLをコピーしました