5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Azure 上の Minecraft マルチサーバを IFTTT でいい感じに制御して節約する

Last updated at Posted at 2020-01-15

GnhyNVj.png

はじめに

Azure の仮想マシンを使って、 Minecraft (Spigot) マルチサーバを立ち上げて運用しています。

参加メンバーは全員会社勤めなので、平日の日中はサーバを停止して、「平日の夜・土日の終日」の間だけ自動でサーバが立ち上がるようにしています。

今回は、サーバの開始・起動スケジュールを IFTTT の DateTime トリガーと連動するため Azure Automation を使い、更に 仮想マシンの起動と終了に連動する Minecraft サーバ を構築しました。

最終的にはサーバの起動通知を Discord に送るようにしてメンバーが確認できるようにしています。

この記事では、以下の手順で解説しています(基礎知識的な部分は省略しています)。

  • 仮想マシンの構築
    • VM の起動と終了に連動した Minecraft サーバを構築します
  • Azure Automation で Webhook を作成する
    • VM の起動と終了を行い、Discord に Webhook で通知する Runbook を構築します
  • IFTTT で Webhook のトリガーを作成する

仮想マシンの構築

今回作成した VM は以下のようなスペックでした。

  • SKU: Standard D2s v3 (2 vcpu 数、8 GiB メモリ)
  • Region: 東日本
  • Image: Ubuntu Server 18.04 LTS

D2s v3 で ¥9,166/月 ですが、平日は 6h 程しか稼働しないため大体 300h/月 となり、月額のおよそ 1/2 程度で運用しています(価格だけ見たらやっぱりちょっと高い気もする)。

Spigot サーバの構築

今回は Docker を使って構築しました。
nimmis/docker-spigot を Clone して docker-compose.yml の値を変更するだけで終わりです。

VM上にCloneする
$ sudo mkdir -p /minecraft
$ sudo chown -R mcserver:mcserver /minecraft
$ git clone --depth=1 https://github.com/nimmis/docker-spigot /minecraft
docker-compose.yml
version: "2"
services:
  spigot-main:
    container_name: "spigot-main"
    build: "."
    ports:
      - 80:8123
      - 25565:25565
    environment:
      - MC_MAXMEM=8g
      - MC_MINMEM=1g
      - SPIGOT_AUTORESTART=yes
      - SPIGOT_VER=1.14.4
      - SPIGOT_UID=1000
    volumes:
      - "./server:/minecraft"
    restart: "always"

これで docker-compose up すれば spigot.jar のビルドが走り、以降はサーバが自動で立ち上がるようになっています。

終了時スクリプト

仮想マシンが停止しようとする時に、Minecraft サーバのワールドデータを /save-all した上で終了する必要がありますが、今回利用したイメージは、コンテナが Stop する際にそのあたりを自動でやってくれています。

なので終了時スクリプトを書いてシャットダウン時にコンテナを停止するようにします。

終了時スクリプトの作成

$ sudo vim       /etc/init.d/stop-mcserver.sh
$ sudo chmod a+x /etc/init.d/stop-mcserver.sh 
$ sudo ln -s     /etc/init.d/stop-mcserver.sh /etc/rc6.d/K99stop-mcserver
/etc/init.d/stop-mcserver.sh
#!/bin/bash

cd /minecraft

/usr/local/bin/docker-compose stop

また、 restart: "always" なので次回起動時に自動的にコンテナが立ち上がって Minecraft サーバが復帰するため、これで自動起動・終了の仕組みが完成します!!!

しなかった

原因が未だに分からないんですが、Azure の仮想マシンが再起動した後に何故かコンテナが自動で立ち上がりません。

ですが、SSH して docker ps などを叩くと 微妙なラグの後にコンテナが起動 したため、おそらく Docker daemon のプロセスが正しく起動していないのではと考えられます。

起動時スクリプト

なので、起動時に Docker API を叩く無害なコマンドを実行させることで無理やり Docker daemon を起動させています。

これで、仮想マシンが再起動した後もコンテナが自動で立ち上がるようになりました。

起動時スクリプト

$ crontab -e

crontab の中身:

# m h  dom mon dow   command
@reboot /usr/bin/docker --version > dev/null 2>&1

Azure Automation で仮想マシンを起動・終了させる

Azure Automation の Runbook でこれらの内容を実装します。

  • サーバを起動させる
  • サーバを停止させる
  • 起動・停止したら Discord の Webhook で通知する
  • Automation 開始トリガーを Incoming Webhook にする

サーバを起動・停止させる

これは、 Runbook ギャラリーの人気上位にある 2つのスクリプトをインポートすれば終わりです。

KENh7Yw.png

ですが、インポートしてきた Runbook は Azure の仕様変更に合わせて更新されておらず、正しく起動・停止できたのにも関わらず Automation ジョブが Error で終わるようになっています。

NZjTQR0.png

原因は Notify VM Started/Stopped ノードの実行条件式が古いためで、これを現在の ActivityOutput のプロパティに合わせることで解決します(あと Notify Failed To Start/Stop ノードあたりのエラー内容の取得方法も古かったため直しました)。

Discord の Webhook で通知する

※ Webhook は作成済みです

以下のような感じでそれぞれの出力メッセージを IDictionary -> JSON に変換して、その内容を Webhook で Discord に通知しています。

RbvYPhT.png

Format message

Write-Output ノードを使い、Discord の Webhook の仕様に合わせてコンテンツを作成。

PowerShell式
@{
  content = $_
}

ConvertTo-Json

Format message からアクティビティの出力を受け取る

Notify to webhook

Invoke-WebRequest ノードを使い、ConvertTo-Json のアクティビティの出力を POST で送信。
Content-Type に application/json; charset=utf-8 を指定しないと日本語が文字化けする。
あと UseBasicParsing フラグも True にしないとジョブが正しく終わらなかった(はず)。

開始トリガーの Incoming-Webhook を作成する

それぞれの Runbook で Webhook を作成して動くかどうか確認する。
LvlPIZ2.png

$ curl -X POST -H "Content-Type: application/json" https://WEBHOOK

このように通知されて仮想マシンが起動・終了すれば OK(Runbook 上のメッセージを日本語に変えています)。
pI3rVqX.png

それぞれの Webhook URL を控えておきます。

IFTTT のトリガーを作成する

IFTTT の DateTime トリガーから Every day of the week at を選択します。

スクリーンショット 2020-01-15 15.49.56.png

曜日と時間が選択出来るので、例えば 平日の19時に実行するようなトリガー を作成します。
スクリーンショット 2020-01-15 15.51.05.png

次に実行するアクションで Webhook を選択し、先程の Webhook URL を設定します。
スクリーンショット 2020-01-15 15.52.39.png

これを複数個作成し、1週間分の起動・停止スケジュールを作成すれば完成です。
GnhyNVj.png

ちなみに

Azure Automation 自体にもスケジュール実行機能が備わっていますが、正直使い勝手が良くないのと スマートフォン上から編集しづらいので IFTTT 経由でスケジュールを編集出来る方がより簡単です。

完全に蛇足ですが仮に祝日判定などの機能追加をする場合も、Runbook 上で構築するよりも Discord の Bot を別途ホストして独自でスケジューリングを実装するのが良いと思います。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?