UE LyraをAgonesで管理し,Docker Compes,Minikube,EKS環境で動作させる
要約
- 前回の記事でLyraをLinux版のDedicated Serverとして稼働させた
- Serverパッケージビルドし、コンテナ化、Agonesで管理し、Docker Compose,Minikube,EKS環境でそれぞれ動作させる
- 構成やスクリプトはGitHubに配置
前回の記事
先にこちらの記事を参考にして頂くと前提知識が得られます。
Agonesとは
端的に言いますと、ゲームサーバをKubernetes上で管理する機能を提供するOSSプロジェクトです。
こちらの記事が参考になります。
公式doc
GitHub
Google Cloud blog
構成やスクリプトを設置したGitHubリポジトリ
また、コマンドを手元で実行する場合は、該当リポジトリのバッチファイル等がお手元にある前提で、後述の手順は記載しています。
ソフトウェア情報
以下のソフトウェアが稼働する環境で動作確認しています。
OS
OS:Windows 10 Pro
バージョン:22H2
ソフトウェア
ソフトウェア名 | バージョン | 備考 |
---|---|---|
Docker Desktop | Docker Desktop 4.24.2 (124339) | Engine Version 24.0.6 インストールページ |
Terraform | v1.5.7 | Minikube,EKS環境構築時使用 インストールページ Chocolateyでインストールするのが楽 |
git | version 2.37.3.windows.1 | Minikube,EKS環境構築時使用インストールページ |
Minikube | v1.31.1 | Minikube環境構築時使用インストールページ |
aws CLI | 2.11.11 | EKS環境構築時使用インストールページ |
動作前提条件の確認
後述の手順で動作するスクリプトは、以下の条件を満たしている事を前提としています。
まずはこれらの確認と対応を行います。
-
UE_ENGINE_ROOT
という環境変数があらかじめ、エンジンのルートフォルダを指定した状態で設定されている- 例:
set UE_ENGINE_ROOT UE_ENGINE_ROOT=E:\\dev\\UnrealEngine5_2_0\\UnrealEngine
- 例:
-
UE_ENGINE_ROOT
直下にLyraStarterGame
フォルダが配置されている- こちらのページの手順をご参照下さい。
GitHub上で必要な権限を所有するPersonal access tokenを発行し、使用できる状態にする
後述する手順で、EpicがGitHub Container Registry(GHCR)上に配置しているエンジンのランタイム用コンテナイメージを使用します。
認証情報等の設定が必要な為、以下の設定作業を行います。
- 前提としてこちらやこちらに記載されているように、GitHubアカウントの連携設定が必要です。
-
こちらの手順に従い、GitHub上でPersonal access tokenを発行します
- 必要な権限は
read:packages
のみです。 - 発行されたトークンは後の手順で使用します。
- こちらに記載がある通り、2023/10現在はclassicトークンのみが対応しているようです。
- 必要な権限は
-
docker login ghcr.io
コマンドを実行して、GHCRにログインします。-
Username
はGitHubのユーザー名,Password
は先ほど発行したPersonal access tokenを入力します。
-
認証に成功すると,Login Succeeded
と表示されます。
こちらも参考になります
PATは期限が切れると、同じトークンが使用できなくなるため再発行の対応が必要です
Lyraの処理部分にAgones SDKを組み込み
Lyra自体の下準備として、AgonesのSDKを組み込みます。
これにより、LyraのゲームサーバがAgonesによって管理されるようになります。
AgonesのUnrealEngine用SDKの組み込みに関しては、公式のドキュメントページに記載があります。
まずはこちらの手順に従って、Lyraの実装内にAgonesのSDKを組み込みます。
具体的には、以下のような対応が必要です。
- プラグインの追加処理
- こちらを参照してください。
- AgonesSDKの初期化処理の追加
- LyraGameSession,LyraGameModeのどちらかの初期化処理に追加します。
- Allocate,Shutdownの呼び出し処理追加
といった処理を追加します。
Linux Serverパッケージを作成する
SDKの組み込みが完了したら、Linux用のパッケージを作成します。
以下の手順を実行します。
-
container/make_package.bat Debug
コマンドを実行します- 今回の例では、Linux ServerのDebug版パッケージを作成しています。
- その他にも、
Development
,Shipping
構成でのビルドが可能です。
上記の手順をエディタ上で手動で実行したい場合は、以下の手順を実行する事で同様の対応が可能です。
手動でLinux Serverパッケージを作成する手順
- コンテンツ/SDK/デバイス管理「Linux」
- バイナリコンフィギュレーション「Debug(デバッグ)」
- ビルドターゲット「LyraServer」
を選択した状態で「プロジェクトをパッケージ化」を実行します。
自分の例では、(エンジンルート)/LyraStarterGame/Package/Debug/LinuxServerにパッケージを作成しています。
コンテナをビルドする
Linux Serverのパッケージ作成が完了したら、以下の手順に従って、コンテナをビルドします。
-
container/build.bat Debug
を実行します-
Debug
構成でコンテナをビルドします。 - その他にも、
Development
,Shipping
構成でのビルドが可能です。
-
内部動作としては、ビルド用のディレクトリに作成したパッケージ関連のファイルを設定と一緒にコンテナ内に設置しています。
Docker Composeで動作確認を行う
前準備
- Docker Desktopをインストールします。
-
docker compose
コマンドが動作する必要があります・
-
動作確認
AgonesのSDKサイドカーコンテナはローカルでテスト動作させるための、--local
オプションの機能を有しています。
この機能を利用する事でローカル環境でも、Kuberntes環境無しの疑似動作確認が可能です。
この機能を使えば
まずはSDKサイドカーコンテナと自分達で動作させているサーバが通信できているか?
つまり
自分たちが組み込んだ処理が正しく動作しているか?
確認することができそうです。
Docker Composeでも、lyra-serverと一緒にsdkコンテナを起動しています。
services:
~~~
sdk:
#ここの部分
というわけで、Docker Composeでこのまま2つのコンテナを起動して、動作確認を行いたい所ですが
このままでは動作しません。
なぜなら、AgonesのUnreal SDKはデフォルトではlocalhostで稼働しているAgonesのSDKサイドカーコンテナに接続する事を前提としている為です。
そこで、今回の例ではlocalモードで起動しているsdkのコンテナに接続する為に、コマンドラインによるコンフィグの上書きで接続先を変更するようにしています。
UPROPERTY(EditAnywhere, Category = Agones, Config)
FString SDKHost = "localhost";
Request->SetURL(FString::Format(
TEXT("http://{0}:{1}/{2}"),
{FStringFormatArg(SDKHost) ,FStringFormatArg(HttpPort), FStringFormatArg(Path)}
));
[/Script/Agones.AgonesComponent]
HttpPort=9358
HealthRateSeconds=10.0f
bDisableAutoConnect=true
SDKHost="localhost"
iniファイルでの接続先設定はlocalhostになっていますが、compose.yamlの以下の部分によって接続先をsdkコンテナに変更しています。
services:
lyra-server:
~~~
command: -log -ini:Game:[/Script/Agones.AgonesComponent]:SDKHost=sdk
この変更を行った上で、再度パッケージ作成、及びビルドを実行します。
-
container/make_package.bat Debug
コマンドを実行します -
container/build.bat Debug
を実行します
最後に、以下のコマンドで起動用スクリプトを使用してコンテナを起動します。
-
container/up.bat Debug
コマンドを実行します-
Debug
構成でコンテナを起動します。 - その他にも、
Development
,Shipping
構成での起動が可能です。
-
うまくLinuxサーバがsdkコンテナに接続できていれば、以下のようなログが出力されます。
sdk | {"ctlConf":{"Address":"sdk","IsLocal":true,"LocalFile":"","Delay":0,"Timeout":0,"Test":"","TestSdkName":"","GRPCPort":9357,"HTTPPort":9358},"featureGates":"CountsAndLists=false\u0026CustomFasSyncInterval=true\u0026Example=false\u0026FleetAllocationOverflow=false\u0026PlayerAllocationFilter=false\u0026PlayerTracking=true\u0026PodHostname=true\u0026ResetMetricsOnDelete=true\u0026SplitControllerAndExtensions=true\u0026StateAllocationFilter=true","message":"Starting sdk sidecar","severity":"info","source":"main","time":"2023-09-13T14:51:41.8346737Z","version":"1.33.0"}
sdk | {"grpcEndpoint":"sdk:9357","message":"Starting SDKServer grpc service...","severity":"info","source":"main","time":"2023-09-13T14:51:41.835595Z"}
sdk | {"httpEndpoint":"sdk:9358","message":"Starting SDKServer grpc-gateway...","severity":"info","source":"main","time":"2023-09-13T14:51:42.8366761Z"}
sdk | {"capacity":100,"message":"Setting Player Capacity","severity":"info","source":"*sdkserver.LocalSDKServer","time":"2023-09-13T14:51:46.2107055Z"}
sdk | {"message":"Allocate request has been received!","severity":"info","source":"*sdkserver.LocalSDKServer","time":"2023-09-13T14:51:46.2107192Z"}
sdk | {"message":"Gameserver update received","severity":"info","source":"*sdkserver.LocalSDKServer","time":"2023-09-13T14:51:46.2107651Z"}
sdk | {"message":"Gameserver update received","severity":"info","source":"*sdkserver.LocalSDKServer","time":"2023-09-13T14:51:46.2107976Z"}
sdk | {"message":"Health Ping Received!","severity":"info","source":"*sdkserver.LocalSDKServer","time":"2023-09-13T14:51:56.3450299Z"}
sdk | {"message":"Health stream closed.","severity":"info","source":"*sdkserver.LocalSDKServer","time":"2023-09-13T14:51:56.3450603Z"}
...
ログから分かるようにsdkコンテナがAllocateのリクエストやPingを受け取っている事が確認できます。
SDKの組み込み処理は成功していそうです。
minikubeで動作確認を行う
Docker Compose
を利用したローカルモードでの動作確認ができたら、次はminikubeを利用した動作確認を行ってみます。
ここでminikubeでの環境作成、Agonesのインストール、展開などの作業を1つずつ手作業で実行していっても良いのですが
Terraformの構成に落とし込んでいるので、基本的にはterraformコマンドの実行のみで環境構築が可能です。
今回は以下Providerの力をお借りしています。
前準備
追加の前準備として、以下の作業を実行します。
- Minikubeをインストールします
- Terraformをインストールします
動作確認
-
minikube
に移動します -
terraform init
を実行します。 -
terraform apply
を実行します。- 構成構築完了後
minikube profile list
を実行すると作成されたプロファイルに関する情報が確認できます。|-------------------------|-----------|---------|--------------|------|---------|---------|-------|--------| | Profile | VM Driver | Runtime | IP | Port | Version | Status | Nodes | Active | |-------------------------|-----------|---------|--------------|------|---------|---------|-------|--------| | lyra-on-minikube-agones | hyperv | | 172.27.55.72 | 8443 | v1.27.3 | Running | 1 | * | |-------------------------|-----------|---------|--------------|------|---------|---------|-------|--------|
- 構成構築完了後
-
クライアントから接続確認を行います。
- ゲームサーバが起動したら、起動したGameServerのIPとポートを使用してクライアントから接続確認します
-
minikube/connect.bat
を実行すると、接続確認が行えます。
-
Grafanaにアクセスして、メトリクスを確認します。
- 環境構築が完了すると、以下のメトリクスに関するドキュメントに記載されている手順を実行するのと同様の構成が作成されます。
- Grafanaのダッシュボードにログインする場合は、以下のコマンドを実行します。この状態で、
kubectl port-forward deployments/grafana 3000 -n metrics
http://localhost:3000
にアクセスするとGrafanaのダッシュボードにアクセスできます。 - 上記URLにアクセスすると、ログイン画面が表示されます。
ログイン用のパスワードは、環境構築完了後にgrafana_password
として出力されています。
username
にはadmin
を入力、password
には上記のgrafana_passwordの値
を入力します。
パスワードを再度確認したい場合は、terraform output -raw grafana_password
のコマンドを実行する事で確認できます。 - Grafanaのメトリクスを確認すると、ゲームサーバの起動や削除のタイミングでメトリクスが変化している事が確認できます。
後片付け
minikubeの環境が必要なくなったら、以下の手順で環境を削除します。
- minikubeに移動します。
-
terraform destroy
で環境を削除します。
EKSで動作確認を行う
minikubeでも動作確認ができた!となれば、いよいよどこかのマネージドKubernetes環境で動作確認を行いたいと思いますよね!?👊
と、いうことで今回はEKSでも動作確認を行ってみます。
ここでもやはり偉大な巨人達の肩を借りて、既存のTerraform Providerで構成を作成しています。
以下Providerの力をお借りしています。
前準備
追加の前準備として、以下の手順を実行します。
- AWS CLIをインストールします
-
aws sts get-caller-identity
の実行と、各種Terraformを通じて作成するリソース関連操作が可能なIAM権限が必要です。
-
ECRのリポジトリを用意する
まず、EKSで使用するコンテナイメージをECRに格納する為、リポジトリを作成します。
以下の手順を実行します。
- eks/images/に移動します
-
terraform init
を実行します -
terraform apply
を実行します
実行が完了すると、ECRのリポジトリが作成されます。
確認したい場合は、以下のAWS CLIコマンドを実行します。
aws ecr describe-repositories
確認コマンド出力例
{
"repositories": [
{
"repositoryArn": "arn:aws:ecr:ap-northeast-1:***:repository/lyra-on-k8s-agones",
"registryId": "***",
"repositoryName": "lyra-on-k8s-agones",
"repositoryUri": "***.dkr.ecr.ap-northeast-1.amazonaws.com/lyra-on-k8s-agones",
"createdAt": "2023-08-27T17:57:29+09:00",
"imageTagMutability": "MUTABLE",
"imageScanningConfiguration": {
"scanOnPush": true
},
"encryptionConfiguration": {
"encryptionType": "AES256"
}
}
]
}
ECRのリポジトリにコンテナイメージをプッシュする
上記手順でECRのリポジトリが作成できたら、コンテナイメージをプッシュします。
以下の手順を実行します。
-
eks\images\push_to_ecr.bat Debug
コマンドを実行します。
EKSクラスタ等の環境を構築する
コンテナイメージのECRへの配置が完了したら、EKSクラスタ等の環境を構築します。
以下の手順を実行します。
- eks/env/に移動します
-
terraform init
を実行します -
terraform apply
を実行します
実行が完了すると、EKSクラスタ等の環境が作成されます。 - クライアントから接続確認を行います。
- ゲームサーバが起動したら、起動したGameServerのIPとポートを使用してクライアントから接続確認します
-
eks/env/connect.bat
を実行すると、接続確認が行えます。
環境を削除する
EKS等の環境が必要なくなったら、以下の手順を実行し、環境を削除します。
- eks/env/に移動します
-
terraform destroy
を実行し、EKSクラスタ等の環境を削除します - eks/images/に移動します
-
terraform destroy
を実行し、ECRリポジトリを削除します
所感
😂「構成が多くて動作確認メンドクサスギ・・」
😐👹「・・・」
😇💥👹 🙈🙉🙊
Discussion