Azure Container Instanceを使ってMinecraft Bedrock Edition(統合版)サーバを立ち上げる

はじめに

Minecraft Bedrock Editionのサーバソフトウェアはアルファ版として公開されており、WindowsとLinuxで動作させることができます。

私も以前にAzureのIaaS版で構築する方法についてまとめていたのですが、有志の方がDocker Hub上にコンテナイメージを公開してくれていたので、こちらを使ってAzure Container Instanceで構築してみました。

Azure Container Instanceとは

一言でいうと、パブリッククラウド上で任意のDocker Containerを動かせるサービスです。起動が早く、また課金は秒単位なので必要な時だけ利用して、不要になったら気軽に停止や削除が行えます。

Azureの仮想ネットワーク内に配置することもできるため、Azure Kubernetes Serviceの仮想ノードなどにも利用されています。

コンテナイメージはプライベートなAzure Container Registryや、Docker Hub上のものが利用可能です。

詳しくはこちらをご覧下さい。

Azure Container Instances とは

Azure Container Instanceは利用するCPUコア数とメモリ量を基に秒単位での課金です。
今回は検証目的であるため、Azure Container Instanceに設定できる最低スペックである、1コア、1GBytes memoyで構築しました。

この場合、まるまる起動した場合で、5,000円/月程でしょうか。単純にコア数、メモリ量を倍にすると金額も倍になります。
Azure Container Instanceが停止中にもMinecraftのデータを保持するために、Azure File Storageも使っていますが、こちらはそれほど容量を必要としてないので料金も微々たるものと思われます。

Container Instances の価格

Minecraftサーバの構築

それでは構築していきましょう。今回はbash上のAzure CLIから操作を行います。手持ちの環境で用意できない場合には、Azure Cloud Shell(Bash)から操作をすると良いです。

必要な環境変数の設定

まずは環境変数を指定します。
今回は東日本リージョンに作成します。
「STORAGE_NAME」はMinecraftサーバがデータを保存するためのAzure Storage Accountの名前を決めます。
「DNS_NAME」はMinecraftアプリから接続するときのサーバ識別名になります。
どちらの名称もグローバルでユニークなものにする必要があるため、あまり安易な名称にはしないように。

# Azure settings
RGNAME=minecraft-server-rg
LOCATION=japaneast
STORAGE_NAME=XXXXXXXX
STORAGE_SHARE_NAME=bedrockdata
ACI_NAME=minecraft-bedrock-server

# Minecraft server settings(basic)
DNS_NAME=XXXXXXXX
PORT=19132

リソースグループの作成

以下のコマンドを実行して、Azureサブスクリプション上にリソースグループを作成します。

# create resource group
az group create -l $LOCATION -n $RGNAME

ストレージアカウントの作成

以下のコマンドを実行して、ストレージアカウントを作成します。一番安価(性能は遅い)な構成で作成しています。

# create storage account
az storage account create -n $STORAGE_NAME -l $LOCATION -g $RGNAME --sku Standard_LRS --access-tier Hot

ストレージアカウント作成後に、共有名の作成をします。最大クオータは1G Bytesにしました。

# create file share
az storage share create -n $STORAGE_SHARE_NAME --account-name $STORAGE_NAME --quota 1 # 1GBytes

このあとでAzure Container Instanceを作成する際に必要な、ストレージアカウントのアクセスキーを取得して、環境変数に設定しておきます。

# get storage share key
STORAGE_KEY=$(az storage account keys list -g $RGNAME --account-name $STORAGE_NAME --query "[0].value" --output tsv)

Azure Container Instanceの作成と実行

以下のコマンドで作成します。
–environment-variablesで指定している環境変数は、全てMinecraftサーバのコンテナにて解析されます。
server.propertyの値とほぼ一致しているので、詳しくはこちらを参照ください。
最後の2行「VERSION」「EULA」は変更しないほうがいいと思います。

# deploy aci
az container create \
    --cpu 1 \
    --memory 1.0 \
    -g $RGNAME \
    --name $ACI_NAME \
    --image itzg/minecraft-bedrock-server \
    --dns-name-label $DNS_NAME \
    --ports $PORT \
    --protocol UDP \
    --azure-file-volume-account-name $STORAGE_NAME \
    --azure-file-volume-account-key $STORAGE_KEY \
    --azure-file-volume-share-name $STORAGE_SHARE_NAME \
    --azure-file-volume-mount-path /data/ \
    --environment-variables \
    'SERVER_NAME'='ACI Bedrock Server' \
    'SERVER_PORT'=$PORT \
    'GAMEMODE'='survival' \
    'DIFFICULTY'='easy' \
    'LEVEL_TYPE'='default' \
    'ALLOW_CHEATS'='true' \
    'MAX_PLAYERS'='10' \
    'ONLINE_MODE'='true' \
    'WHITE_LIST'='false' \
    'VIEW_DISTANCE'='32' \
    'TICK_DISTANCE'='4' \
    'PLAYER_IDLE_TIMEOUT'='30' \
    'MAX_THREADS'='8' \
    'LEVEL_NAME'='worlds' \
    'LEVEL_SEED'='' \
    'DEFAULT_PLAYER_PERMISSION_LEVEL'='member' \
    'TEXTUREPACK_REQUIRED'='false' \
    'SERVER_AUTHORITATIVE_MOVEMENT'='true' \
    'PLAYER_MOVEMENT_SCORE_THRESHOLD'='20' \
    'PLAYER_MOVEMENT_DISTANCE_THRESHOLD'='0.3' \
    'PLAYER_MOVEMENT_DURATION_THRESHOLD_IN_MS'='500' \
    'CORRECT_PLAYER_MOVEMENT'='' \
    'VERSION'='LATEST' \
    'EULA'='TRUE'

作成中のログは以下のコマンドで確認できます。

(実行例)
$ az container attach -g $RGNAME -n $ACI_NAME
[2020-09-01 05:40:14 INFO] Starting Server
[2020-09-01 05:40:14 INFO] Version 1.16.20.3
[2020-09-01 05:40:14 INFO] Session ID 4857a44d-8455-4f38-8e12-b442464ec173
[2020-09-01 05:40:14 INFO] Level Name: worlds
[2020-09-01 05:40:14 INFO] Game mode: 0 Survival
[2020-09-01 05:40:14 INFO] Difficulty: 1 EASY
[2020-09-01 05:40:19 INFO] opening worlds/worlds/db

ログの表示は定期的に更新されます。最後に「Server started.」と表示されたら起動完了です。
初回の起動には数分の時間がかかります。

[2020-09-01 05:41:20 INFO] IPv4 supported, port: 19132
[2020-09-01 05:41:20 INFO] IPv6 supported, port: 19133
[2020-09-01 05:41:20 INFO] IPv4 supported, port: 39726
[2020-09-01 05:41:20 INFO] IPv6 supported, port: 32812
[2020-09-01 05:41:24 INFO] Server started.

ログ表示は最後に[Ctrl]+[C]を押して停止します。

Minecraftアプリからの接続とxuidの確認

サーバ名は先の環境変数で指定したDNS_NAME+リージョン名+「.azurecontainer.io」となります。

以下のコマンドでも確認できます。

az container show -g $RGNAME -n $ACI_NAME --query "ipAddress.fqdn" -o tsv

それでは、PCからMinecraftを起動します。
「遊ぶ」で先に進みます。

上部のタブから「サーバー」を選択後、「サーバーを追加」を選択します。

外部サーバーを追加画面で、「サーバー名」は適当に、サーバーアドレスには先程確認したAzure Container InstanceのFQDNを入力します。「ポート」は19132です。
最後に「保存」を押します。

サーバ一覧画面に戻ったら、先程作成したサーバーを選択後、「サーバーに参加」を押します。

警告画面が出ますが気にしません。「続行」を押します。

ワールド作成中画面がでるので少し待ちます。

はい、繋がりました。

ここで喜んではいけません。一旦先程説明した、Azure Container Instanceのログ表示をもう一度行い、今ログインしている「あなた」のxuidを確認します。

(実行例)
$ az container attach -g $RGNAME -n $ACI_NAME
[2020-09-01 05:41:24 INFO] Server started.
[2020-09-01 05:53:56 INFO] Player connected: XXXXXXXX, xuid: ZZZZZZZZZZZZZZZZ

このログに表示されている16桁のxuidを控えておきます。

ユーザにオペレータ権限を付与

新しくMinecractサーバにログインしたユーザはメンバー権限を付与する設定にしたので、自分だけにオペレータ権限を付与します。

公式で配布されているMinecraftサーバを仮想マシン上で動かす場合には、そのサーバプログラム上で各種オペレータコマンドが叩けるので良いのですが、Azure Container Instanceで立ち上げた場合、実行中のプロセスそのものにアタッチする事が、どうやら出来なさそうなので各種オペレータコマンドはアプリから行うようにします。

以下の「permissions.json」ファイルをローカルPC上(もしくはCloud Shell上)で作成します。
中のxuidには先程確認した自分のidを設定します。

[
    {
        "permission": "operator",
        "xuid": "ZZZZZZZZZZZZZZZZ"
    }
]

このファイルを、Azure File Storage上の共有フォルダ直下にコピーします。

# upload permissions.json
az storage file upload --account-name $STORAGE_NAME --account-key $STORAGE_KEY --share-name $STORAGE_SHARE_NAME --source permissions.json --path permissions.json

最後にAzure Container Instanceを停止して起動します。再起動だとうまくpermissions.jsonが反映されないようでした。

# stop container instance
az container stop -g $RGNAME -n $ACI_NAME

# start container instance
az container start -g $RGNAME -n $ACI_NAME

再度Minecraftアプリからサーバに接続して、オペレータコマンドを叩いてみましょう。

まんまとダイヤモンド64個ゲットできましたね!

遊ばないときは

Minecraftで遊ばないときには、Azure Container Instanceを停止しておくことで、Azureの課金をおさえることができます。

先程も紹介しましたが、以下のコマンドで停止と起動が行えます。

[停止]

# stop container instance
RGNAME=minecraft-server-rg
ACI_NAME=minecraft-bedrock-server
az container stop -g $RGNAME -n $ACI_NAME

[起動]

# start container instance
RGNAME=minecraft-server-rg
ACI_NAME=minecraft-bedrock-server
az container start -g $RGNAME -n $ACI_NAME

少し遊んでみて

30分くらい遊んでみて、夕刻までに(チートコマンドを使いつつ)素敵な豪邸を建てたのですが、特にレスポンスで気になることはありませんでした。

AzureポータルからAzure Container Instanceの負荷状況を見ると、とりあえず一人でもくもく遊ぶ程度であれば最低スペック(1Core/1GB Memory)でも大丈夫なのではと思います。

おわりに

こんなに簡単にMinecraftサーバが立ち上げられるのも、Azureのおかげもそうですが、Docker Hubにイメージを公開してくれているitzgさんにも感謝です。