本の虫

著者:江添亮
ブログ: http://cpplover.blogspot.jp/
メール: boostcpp@gmail.com
Twitter: https://twitter.com/EzoeRyou
GitHub: https://github.com/EzoeRyou

アマゾンの江添のほしい物リストを著者に送るとブログ記事のネタになる

筆者にブログのネタになる品物を直接送りたい場合、住所をメールで質問してください。

Minecraftクライアントからdockerの管理ができるminecraftサーバー: Dockercraft

docker/dockercraft

公式の未改変Minecraftクライアントから接続してDockerの管理ができるMinecraft互換サーバー、Dockercraftが公開されている。

Dockercraft

Dockercraftの実行方法

1. Minecraftのインストール: Minecraft

Minecraftクライアントは改変していないので、公式リリースをそのまま使える。

2. Dockercraftイメージをpullするかビルドする。

docker pull dockercraft

もしくは、

git clone git@github.com:docker/dockercraft.git
docker build -t dockercraft dockercraft

3. Dockercraftコンテナーを実行する

docker run -t -i -d -p 25565:25565 \
-v /var/run/docker.sock:/var/run/docker.sock \
--name dockercraft \
dockercraft

Docker remote APIを使うには/var/run/docker.sockをコンテナー内でマウントする必要がある。

Minecraftサーバーのデフォルトのポートは25565だ。他のポートがいいのであれば、"-p <port>:25565"

4. Minecraft > Multiplayer > Add Serverを開く

サーバーアドレスはDockerホストのIP。デフォルトのものを使っているのであればポート番号を指定する必要はない。

Docker Machineを使っているのであれば、"docker-machine ip <machine_name>"

5. サーバーにjoinする。

少なくともひとつのコンテナーが世界に見えるはずだ。それはDockercraftサーバーをホストしているものである。

レバーとボタンを操作することで、コンテナーをスタート、ストップ、リムーブできる。Minecraftのチャットウインドウから一部のDockerコマンドがサポートされている。チャットウインドウはTキー(デフォルト)か/キーで表示される。

実装

Mnecraftクライアント自体は改変していない。操作は全てサーバーサイドで行われている。

Minecraftサーバーには、Cuberite.orgを用いた。C++で書かれた独自のMinecraft互換ゲームサーバーだ。GitHubレポジトリ

サーバーはLUAで書かれたスクリプトをプラグインとして受け付ける。そこでDocker用のものを書いた。(world/Plugins/Docker)

残念ながら、このプラグインと通信するいいAPIがない。ただしwebadminがあり、プラグインは"webtabs"に応答できる。

Plugin:AddWebTab("Docker",HandleRequest_Docker)

つまり、プラグインは、http://127.0.0.1:8080/webadmin/Docker/Dockerに送られたPOSTリクエストを見ることができる。

Goproxy

Docker remote APIのイベントはGoで書かれた小さなデーモン(go/src/goproxy)によってLUAプラグインに送られる。

func MCServerRequest(data url.Values, client *http.Client) {
    req, _ := http.NewRequest("POST", "http://127.0.0.1:8080/webadmin/Docker/Docker", strings.NewReader(data.Encode()))
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.SetBasicAuth("admin", "admin")
    client.Do(req)
}

デーモンにリクエストを送るため、LUAプラグインからgoproxyバイナリを匹数付きで実行することもできる。

function PlayerJoined(Player)
    -- refresh containers
    r = os.execute("goproxy containers")
end

貢献

Dockercraftをハックしたいならば、Docker's contributions guidelinesを参照。

これで、仕事中にMinecraftで遊んでいても、「Dockerを管理をビジュアライズしてくれる便利なツールなんです」という言い訳がたつ。

「なるほど、しかしなぜ大規模なクラフトをする必要があるんだね?」
「Docker操作を自動化するために必要な論理回路を組んでいます」