素人が何もわからずAWSにマイクラサーバを立ててみた(続編)- 自動起動と自動停止編
はじめに
前回の記事では、AWSでMinecraftサーバーを立ち上げ、Javaのインストール、サーバーの初期設定、そしてチートの有効化までを行いました。今回は、サーバー運用におけるコスト削減と利便性向上に直結する重要な設定、すなわち「サーバーの自動起動」と「プレイヤーがいなくなったら自動で停止する」仕組みについて、Geminiと二人三脚で挑戦した記録をお届けします。
今回の目標
- EC2インスタンスを立ち上げたら、自動でMinecraftサーバーが立ち上がるようにする
- プレイヤーが0人になったら、自動でEC2インスタンスを停止する
- サーバー設定など、EC2を操作したいだけの時に自動停止を防ぐ方法を知る
1. EC2を立ち上げたら自動でMinecraftサーバーが立ち上がる設定
手動でEC2を起動するたびに、SSHでログインしてMinecraftサーバーを起動するのは面倒ですよね。ここでは、LinuxのSystemdというサービス管理ツールを使って、OS起動時に自動でMinecraftサーバーが立ち上がるように設定します。
Minecraft起動スクリプトの作成
まず、Minecraftサーバーを起動するためのシンプルなシェルスクリプトを作成します。
-
EC2インスタンスにSSH接続します。
-
Minecraftサーバーのディレクトリとは別に、例えばホームディレクトリ直下に起動スクリプトを作成します。ここでは
/home/ec2-user/start_minecraft.shとします。vi /home/ec2-user/start_minecraft.shここで
viエディタが開きます。ここでちょっと寄り道:
viエディタの基本的な使い方viは慣れるまで少し独特な操作感がありますが、基本的な操作を覚えれば大丈夫です。-
起動時:コマンドモード
viを開くと、最初はコマンドモードという状態です。ここでは文字を直接入力することはできません。カーソル移動やコマンドの実行などを行います。 -
文字を入力したい:挿入モード
文字を入力するには、コマンドモードから挿入モードに切り替える必要があります。- カーソルがある位置から入力開始:
iキーを押す - カーソルがある位置の次から入力開始:
aキーを押す - カーソルがある行の下に新しい行を追加して入力開始:
oキーを押す
挿入モードになると、画面の左下あたりに-- INSERT --と表示されます。これで通常のテキストエディタのように文字を入力できます。
- カーソルがある位置から入力開始:
-
入力終了:コマンドモードに戻る
文字の入力が終わったら、Escキーを押すとコマンドモードに戻ります。-- INSERT --の表示が消えます。 -
ファイルを保存して終了:最終行モード
コマンドモードで:(コロン)キーを押すと、画面の左下にカーソルが移動し、コマンド入力待ちになります(最終行モード)。- 変更を保存して終了:
:wqと入力して Enter - 変更を保存せずに終了:
:q!と入力して Enter - 保存だけする:
:wと入力して Enter
- 変更を保存して終了:
上記
viの操作方法を参考に、以下の内容をファイルに貼り付けてください。cd /home/ec2-user/minecraft/とjava ...のパスや設定は、あなたのサーバーの実際のパスや起動コマンドに合わせてください。#!/bin/bash cd /home/ec2-user/minecraft/ java -Xmx512M -Xms512M -jar server.jar nogui変更したら、
Escキーを押してコマンドモードに戻り、:wqと入力してEnterでファイルを保存して閉じます。 -
-
スクリプトに実行権限を付与します。
chmod +x /home/ec2-user/start_minecraft.sh
Systemd ユニットファイルの作成
次に、Systemdがこのスクリプトをサービスとして管理するための設定ファイル(ユニットファイル)を作成します。
-
以下の内容で
/etc/systemd/system/minecraft.serviceファイルを作成します。sudo権限が必要です。sudo vi /etc/systemd/system/minecraft.serviceここでも
viエディタが開きますので、上記「viエディタの基本的な使い方」を参考に操作してください。[Unit] Description=Minecraft Server After=network.target [Service] User=ec2-user Group=ec2-user WorkingDirectory=/home/ec2-user/minecraft/ ExecStart=/home/ec2-user/start_minecraft.sh Restart=always # サービスが停止した場合に常に再起動 RestartSec=10s # 10秒後に再起動 StandardOutput=journal # ログをjournaldに転送 StandardError=journal [Install] WantedBy=multi-user.target-
UserとGroupはMinecraftサーバーを実行するユーザーに合わせてください(通常はec2-user)。 -
WorkingDirectoryとExecStartは、先ほど作成したスクリプトとMinecraftサーバーのディレクトリの正確なパスを指定します。 -
Restart=alwaysを設定することで、万が一Minecraftサーバーがクラッシュしても自動的に再起動されるようになります。
-
-
ファイルを保存してエディタを閉じます(
Escキー →:wq→Enter)。
Systemdの設定をリロードし、サービスを有効化・起動
新しいサービスファイルをSystemdに認識させ、OS起動時に自動で起動するように設定します。
- Systemdの設定をリロードします。
sudo systemctl daemon-reload -
minecraft.serviceをOS起動時に自動起動するよう有効化します。sudo systemctl enable minecraft.service - サービスを今すぐ起動します(テスト)。
sudo systemctl start minecraft.service - サービスのステータスを確認し、
Active: active (running)と表示されていることを確認します。sudo systemctl status minecraft.service
これで、EC2インスタンスが起動するたびに、Minecraftサーバーが自動的に立ち上がるようになりました。
2. プレイヤーが0人になったら自動でEC2を停止する設定
これはコスト削減の要となる設定です。誰もプレイしていないときにEC2インスタンスを自動停止させることで、無駄な料金発生を防ぎます。
CloudWatch エージェントのインストールと設定
Minecraftサーバーのログを監視するために、CloudWatch エージェントをEC2インスタンスにインストールし、ログをAWSのCloudWatch Logsに送信するように設定します。
-
エージェントのダウンロードとインストール:
sudo yum install -y amazon-cloudwatch-agent -
設定ファイルの作成 (
config.json):
config.jsonを作成し、Minecraftサーバーのログファイル(通常はlogs/latest.log)を監視するように設定します。sudo vi /opt/aws/amazon-cloudwatch-agent/bin/config.jsonここでも
viエディタが開きますので、上記「viエディタの基本的な使い方」を参考に操作してください。{ "logs": { "logs_collected": { "files": { "collect_list": [ { "file_path": "/home/ec2-user/minecraft/logs/latest.log", "log_group_name": "/aws/ec2/minecraft-server-log", "log_stream_name": "{instance_id}", "timestamp_format": "%H:%M:%S" } ] } } } }-
file_pathはあなたのMinecraftサーバーのログファイルの正確なパスに設定してください。 -
log_group_nameはCloudWatch Logsでログが保存されるグループ名です。
変更したら、Escキーを押してコマンドモードに戻り、:wqと入力してEnterでファイルを保存して閉じます。
-
-
CloudWatch エージェントの起動:
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json -sこれでエージェントが起動し、MinecraftサーバーのログがCloudWatch Logsにリアルタイムで送られるようになります。
CloudWatch メトリクスフィルターとアラームの設定
CloudWatch Logsに送られたログの中から「プレイヤーのログイン」と「プレイヤーのログアウト」の情報を抽出し、現在のプレイヤー数をカウントするカスタムメトリクスを作成します。そして、そのプレイヤー数が0になったら発動するアラームを設定します。
-
CloudWatch Logsでメトリクスフィルターを作成:
- AWSマネジメントコンソールでCloudWatchサービスに移動します。
- 左のナビゲーションペインで「ロググループ」を選択し、
/aws/ec2/minecraft-server-logをクリックします。 - 「メトリクスフィルター」タブを選択し、「メトリクスフィルターを作成」をクリックします。
-
プレイヤーログイン用フィルター:
- フィルターパターン:
[INFO] logged in - メトリクス名:
PlayerLoggedInCount
- フィルターパターン:
-
プレイヤーログアウト用フィルター:
- フィルターパターン:
[INFO] left the game - メトリクス名:
PlayerLeftCount
- フィルターパターン:
-
カスタムメトリクス(プレイヤー数)の作成:
- CloudWatchの左ナビゲーションペインで「メトリクス」を選択し、「すべてのメトリクス」タブをクリックします。
- 「数式と可視化されたメトリクス」タブを選択し、「数式を追加」をクリックします。
-
PlayerLoggedInCountをm1、PlayerLeftCountをm2として、数式にm1 - m2と入力し、エイリアスをPlayerCountなどと設定します。これが現在のプレイヤー数を表すメトリクスになります。
-
CloudWatch アラームの作成:
- 先ほど作成した
PlayerCountメトリクスを選択し、「アラームの作成」をクリックします。 -
アラームの条件:
- 「期間」: 1分
- 「条件」:
PlayerCountが0より小さいまたは等しい (<= 0) - 「データポイントのしきい値」: 1
-
アクションの設定:
- 「通知」: 新しいSNSトピックを作成するか、既存のトピックを選択します。このSNSトピックが、後述するLambda関数をトリガーします。例えば
minecraft-server-stop-snsという名前で作成します。
- 「通知」: 新しいSNSトピックを作成するか、既存のトピックを選択します。このSNSトピックが、後述するLambda関数をトリガーします。例えば
- 先ほど作成した
Lambda関数によるEC2の自動停止
CloudWatchアラームが「ALARM」状態になったら、それをトリガーとしてLambda関数が実行され、MinecraftサーバーのEC2インスタンスを停止します。
-
Lambda 関数の作成:
- AWSマネジメントコンソールでLambdaサービスに移動します。
- 「関数の作成」をクリックし、以下の設定を行います。
-
関数名:
stop-minecraft-server - ランタイム: Python 3.9 (または最新のサポートされているバージョン)
- 実行ロール: 「基本的な Lambda アクセス権限で新しいロールを作成する」を選択し、後で権限を最小化します。
-
関数名:
- 関数を作成したら、コードエディタに以下のPythonコードを貼り付けます。
import boto3 import os ec2 = boto3.client('ec2') def lambda_handler(event, context): # 環境変数からEC2インスタンスIDを取得 instance_id = os.environ.get('INSTANCE_ID') if not instance_id: print("Error: INSTANCE_ID environment variable is not set.") return try: # EC2インスタンスを停止 response = ec2.stop_instances(InstanceIds=[instance_id]) print(f"Stopping instance {instance_id}: {response}") except Exception as e: print(f"Error stopping instance {instance_id}: {e}") raise e -
環境変数の設定:
- Lambda関数の設定タブで、「環境変数」セクションを見つけ、「編集」をクリックします。
- キー:
INSTANCE_ID - 値: あなたのMinecraftサーバーのEC2インスタンスID (例:
i-0abcdef1234567890)
-
トリガーの設定:
- Lambda関数の「トリガーを追加」をクリックします。
- トリガーとして「SNS」を選択し、CloudWatchアラームで設定したSNSトピック(例:
minecraft-server-stop-sns)を選択します。
権限の最小化とセキュリティ強化
Lambda関数がEC2インスタンスを停止するための権限は、必要最小限に抑えるべきです。
-
カスタムIAMポリシーの作成:
- AWSマネジメントコンソールでIAMサービスに移動します。
- 左ナビゲーションペインで「ポリシー」を選択し、「ポリシーを作成」をクリックします。
- 「JSON」タブを選択し、以下のポリシーを貼り付けます。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:StopInstances", "ec2:DescribeInstances" ], "Resource": "arn:aws:ec2:YOUR_REGION:YOUR_ACCOUNT_ID:instance/YOUR_INSTANCE_ID" } ] }-
YOUR_REGIONはあなたのEC2インスタンスが存在するリージョン(例:ap-northeast-1)、YOUR_ACCOUNT_IDはあなたのAWSアカウントID、YOUR_INSTANCE_IDはMinecraftサーバーのEC2インスタンスIDに置き換えてください。 - ポリシーに
MinecraftServerStopPolicyなどの分かりやすい名前をつけ、作成します。
-
Lambda関数の実行ロールにアタッチ:
- Lambda関数の設定タブに戻り、「アクセス権限」セクションで実行ロールのリンクをクリックします。
- ロールのページで、「アクセス権限を追加」をクリックし、先ほど作成した
MinecraftServerStopPolicyをアタッチします。 - 初期に付与された広範なポリシー(例:
AWSLambdaBasicExecutionRole以外でEC2操作に関わるもの)があれば、デタッチして削除します。
これで、プレイヤーがいなくなったら自動でEC2が停止する、セキュアな自動停止システムが完成です!
2-2. EC2を動かしたいだけの時はCloudWatchをオフにすること
サーバーの設定変更やメンテナンス作業中など、プレイヤーがいない状態でEC2を起動しておきたい場合、上記で設定した自動停止機能が作動してしまい、作業が中断されてしまいます。これを防ぐために、作業中は一時的に CloudWatch アラームを無効化する必要があります。
- AWSマネジメントコンソールでCloudWatchサービスに移動します。
- 左側のナビゲーションペインで「アラーム」の下の「すべてのアラーム」を選択します。
-
MinecraftServerEmptyAlarm(アラーム作成時に自分で設定した名前) を見つけて選択します。 - 「アクション」ドロップダウンメニューから「アラームを無効にする」を選択します。
これで、アラームの状態が「ALARM」になっても、EC2インスタンスの停止アクションはトリガーされなくなります。
重要: 作業が完了したら、忘れずに同じ手順で「アラームを有効にする」に戻してください。
まとめ
今回の続編では、Minecraftサーバーをさらに便利でコスト効率よく運用するための重要なステップを学びました。Systemdによる自動起動、そしてCloudWatchとLambdaを組み合わせた自動停止機能は、サーバー管理の手間を大幅に削減してくれます。
AWSの学習は一歩ずつですが、GeminiのようなAIアシスタントの助けを借りることで、私のような初心者でも複雑な設定に挑戦し、成功体験を積むことができました。
AWSでのMinecraftサーバー運用は、クラウドの基礎を学ぶ素晴らしいサンドボックスになります。ぜひあなたも、AIアシスタントと一緒にこの挑戦を楽しんでみてください!
Discussion