GCP初心者がGCEでマイクラサーバを建ててみた話

#はじめに
GCPを初めて半年未満の初心者が勉強のためにマイクラサーバを建ててみたって話です。

#目標
- GCEでマイクラサーバを構築
- Discordからインスタンスの制御
- GCPの操作に慣れる

#構成
- VMインスタンス1（マイクラサーバ）
- VMインスタンス2（discord bot）
- クラウドストレージ（バックアップ用）
- サービスアカウント１（discordからの制御用）

#構成図
![マイクラサーバ構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110334/67f7b9d9-ef42-ecee-ad56-907a56ecf616.png)

#手順
##1. マイクラサーバ用のインスタンスの作成
なにはともあれマイクラサーバ用のインスタンスを作成しないとなにも始まりませんね。
基本的には以下の公式ドキュメントを参照し作成していきます。
GCPは公式ドキュメントはかなりわかりやすいものが用意されていて初心者には大助かりでした。
>[Compute Engine での Minecraft サーバーのセットアップ](https://cloud.google.com/solutions/gaming/minecraft-server?hl=ja#automate_start_up_and_shutdown_procedures)

インスタンスについては私はこのような設定で作成しました。

| 項目       　　　　| 内容　　　　　　     |
|:-----------------|:------------------|
| インスタンス名       | mineserver        |
| リージョン           | us-central1       |
| ゾーン             | us-central1-f     |
|シリーズ             | N1                |
| マシンタイプ         | n1-standard-2     |   
| ブートディスク        | CentOS 7          |
| プリエンプティブ      | 有効              |
| ネットワークインタフェース外部IP |IPアドレスを作成 |


**プリエンプティブル インスタンスの制限**
プリエンプティブルインスタンスを有効にするメリットは、単純にインスタンスの費用が通常の3分の１で済みます。
今回のマイクラサーバについては、ログインしっぱなしなんて状況はほとんど無いと思いましたので、コストを大幅に下げれることを優先しプリエンプティブルインスタンスを採用しました。
目標にも記載しましたが、discordからゲームをする時だけインスタンスをスタートし、終わったらストップするのであまり障害はないものと思っています。

デメリットについては、公式ドキュメントに詳しく記載されているのでそちらを参照してください。
>[プリエンプティブル インスタンスの制限](https://cloud.google.com/compute/docs/instances/preemptible#understanding_the_preemption_process)


**永続ディスクの追加**
追加ディスクについては以下の通りに作成します。

| 項目       | 内容        |
|:-----------------|:------------------|
| ディスク名             | minecraft-disk              |
| ディスクタイプ           | SSD永続タイプ              |
| ソースタイプ             | 空のタイプ              |
| サイズ               | 50GB              |

##2. マイクラサーバのインストール・実行
こちらも基本的には上記に記載した公式ドキュメントを元に進めていきますが、
公式はOSがDebianを使用しており、私はCentOSを使用しているのでコマンドが一部ですが違ってきます。
違っている箇所を記載していますので、公式ドキュメントと合わせて読んでいただけると幸いです。

**Java ランタイム環境（JRE）をセットアップする**

```shell
#まずは既存パッケージの最新版へアップデート
$ yum update

#JREのインストール
$ yum install -y default-jre-headless
```
**マイクラサーバのダウンロードとインストール**
公式ではwgetを使いダウンロードしていますが、centOSにはデフォルトで`wget`は無いのでインストールします。
マイクラサーバのダウンロードリンクについてはminecraftのダウンロードページから最新のリンクをコピーして差し替えてください。

```shell
#wgetのインストール
$ yum install wget

#マイクラサーバのインストール
$ wget https://launcher.mojang.com/v1/objects/f1a0073671057f01aa843443fef34330281333ce/server.jar
```

**サーバの初回起動**
下記のコマンドに「-Xms1G -Xmx3G」とあるが、こちらはメモリの割り当てをしているもので、
マシンスペックに合わせて調整が可能です。

```shell

#マイクラサーバの実行
$ java -Xms1G -Xmx3G -d64 -jar server.jar nogui
```

**マイクラサーバを使用するにあったての合意条件**
初回起動が終わると同ディレクトリ内にいくつかファイルが生成され、その中に`eula.txt`というファイルがあるので下記コマンドで開き編集します。
EULA の条件に同意する場合は、`eula` の値を `false` から `true` に変更し、保存して終了します。

```shell

$ vi eula.txt

#以下eula.txtの内容

#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).
#Thu Nov 21 18:02:54 UTC 2019
eula=true　　<-- ここを「false」から「true」に変更する
```

ここまでで最低限必要なセットアップは完了しました。
ですが、このままだとサーバからログアウトするとセッションが切れてマイクラサーバは停止してしまいます。
この問題を解決するために`screen`を使用します。
まずは`screen`のインストールからです。

```shell
#screenのインストール
$ yum install screen
```
インストールした`screen`を使いマイクラサーバを実行します。
スクリーンコマンドの使い方は以下のページを参考にさせていただきました。
>[Linux screenコマンド使い方](https://qiita.com/hnishi/items/3190f2901f88e2594a5f)

```shell
#screenを使いマイクラサーバの実行
$ screen -S mcs java -Xms1G -Xmx3G -d64 -jar server.jar nogui
```

**クライアントがマイクラサーバにログインできるようにする**

公式ドキュメントに書かれているように、マイクラサーバは25565 をデフォルト リスニング ポートとして使用しますのでそちら許可するファイアウォールルールを作成します。
ポートを変更したい場合は同ディレクトリにある`server.properties`を編集することで変更可能です。
また、`server.properties`では他にもマイクラサーバの様々な設定を変更することが可能です。
>[サーバ設定ファイル(server.properties)](https://minecraft.server-memo.net/server-properties/)

**インスタンスの起動と停止を自動化する**
サーバーを定期的に停止する予定がある場合は、インスタンスに起動スクリプトとシャットダウン スクリプトを追加して、よく使用する起動と停止を自動化します。

後々行うdiscordからのインスタンス制御時に必要なので今のうちに設定しておく。

GCP Console の [VM インスタンス] -> [インスタンス名をクリック] -> [編集] -> [カスタムメタデータ]セクションで、`startup-script` という名前の新しいキーを追加し、以下のスクリプトを [値] フィールドにコピーします。

```

#!/bin/bash
mount /dev/disk/by-id/google-minecraft-disk /home/minecraft
(crontab -l | grep -v -F "/home/minecraft/backup.sh" ; echo "0 */4 * * * /home/minecraft/backup.sh")| crontab -
cd /home/minecraft
screen -d -m -S mcs java -Xms1G -Xmx3G -d64 -jar server.jar nogui
```

シャットダウン手順を自動化するには、`shutdown-script` という別のキーを追加し、その [値] フィールドに以下のスクリプトをコピーします。

```
#!/bin/bash
/home/minecraft/backup.sh
sudo screen -r mcs -X stuff '/stop\n'
```

##3. 定期バックアップの設定・実行
マイクラをプレイしていて突然クラッシュしデータが飛んでしまった。なんて悲しいことは私も何度か経験があります。
そんな時のために定期的にバックアップを取ることは必須ですよね。

基本は公式ドキュメントの「定期バックアップをスケジュールする」の項目通りに進めます。

まずは公式ドキュメントの通り、新しい Cloud Storage Regional バケットを作成します。
バケットを作成するリージョンはお好みで置き換えてください。
私は`asia-northeast1 (東京)`で作成しました。

バックアップ用のスクリプトを作成し、`cron`を使い定期的に実行します。

```shell
#バックアップ用スクリプトの作成
$ vi /home/minecraft/backup.sh

#以下backup.shの内容

#!/bin/bash
screen -r mcs -X stuff '/save-all\n/save-off\n'
/usr/bin/gsutil cp -R ${BASH_SOURCE%/*}/world gs://[BUCKET_NAME]/$(date "+%Y%m%d-%H%M%S")-world
screen -r mcs -X stuff '/save-on\n'

#作成したスクリプトの権限を変更
$ chmod 755 /home/minecraft/backup.sh

```

`cron`ジョブをスケジュールするには、`crontab`に書き込む必要があります。

```shell

$ crontab -e

#以下crontabの内容
0 */4 * * * /home/minecraft/backup.sh
```

上記の設定をすると4時間ごとに`backup.sh`を実行されるようになります。
公式ドキュメントでは4時間でされていますが、私はクラッシュし復旧させる際に4時間も前の状態に戻るのは精神的にきついので1時間ごとにしました(笑)。

**バックアップを世代保存する**
バックアップを取り続けるだけですと、ファイルが膨大になってしまいますので一定の世代分だけを常に残すように設定します。
`CloudStorage`ではオブジェクトのライフサイクル管理という機能があります。
簡単に説明すると自動的に古いバックアップを削除してくれるものです。

設定については公式ドキュメントの「古いバックアップを自動的に削除する」の項目通りに進めます。
1点公式ドキュメントとは違う設定をした項目は、
[オブジェクト条件の選択] セクションで、[年齢] を選択します。年齢を 7 日間ではなく3日間にしました。
私の場合は1時間ごとにバックアップを取るので1日で24回、7日間も残すとなると168回分のバックアップが残ります。さすがにコストを考慮し3日間にしました。

#まとめ

いかがでしたでしょうか、ここまででマイクラサーバの構築は終了です。
次回は今回作成したマイクラサーバをDiscordから制御できるようにしていきます。

次回 -> [DiscordからGCPインスタンスを操作してみた話](https://qiita.com/rodotan/items/5d1b5489e3f18460a40a)