Mesos/Marathon/DockerでプライベートIaaSを作る

# はじめに
環境が汚くなるのが嫌で、いろいろやるたびにEC2インスタンスを作り直していました。
Dockerを使って上手くやりたいなと思っていたところに、MesosとMarathonとDockerを使うことで、AWSのEC2みたいなものを自分の環境に作れるらしいと聞いたためやってみました。
Docker Lifeが思っていたよりも快適なため、構築手順をメモにして残しておきます。

# 環境
AWSのEC2を4台使って作ってみました（すべてUbuntu14.04）。
マスタ1台とスレーブ3台の構成です。

# 手順
必要なものを順番に入れていきます。

* [PCの準備](#pcの準備)
* [Docker](#docker)
* [Mesos/Marathon](#mesosmarathon)
* [テストデプロイ](#テストデプロイ)

## PCの準備
PCを準備します。今回はEC2インスタンス（Ubuntu14.04）を4台準備しました。
EC2のインスタンスを準備するだけなので、手順は省略します。

## Docker
##### 対象：スレーブ
Dockerをインストールします。

```shell-session
$ wget -qO- https://get.docker.com/ | sh
```

問題なくインストールできたかは、Hello worldを表示させて確認します。

```shell-session
$ sudo docker run ubuntu:14.04 /bin/echo 'Hello world'
Hello world
```

参考
[Qiita - ubuntu 14.04にDockerをインストール](http://qiita.com/koara-local/items/ee887bab8c7186d00a88)
[Qiita - アプリケーションをDocker化する：Hello World](http://qiita.com/t-yotsu/items/be994a437f135b31fea4)

## Mesos/Marathon
##### 対象：マスタ
MesosとMarathonをインストールします。
また、手順はほぼ同じなのですが、設定がマスタとスレーブで異なるため、別々に書きます。
まずはマスタです。

Open JDK 8が必要なため、インストールします。

```shell-session
$ sudo apt-add-repository ppa:openjdk-r/ppa
$ sudo apt-get update
$ sudo apt-get -y install openjdk-8-jdk
```

MesosとMarathon（今回は関係ないですがChronosも）をインストールします。

```shell-session
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E56151BF
$ DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
$ CODENAME=$(lsb_release -cs)
$ echo "deb http://repos.mesosphere.com/${DISTRO} ${CODENAME} main" | sudo tee /etc/apt/sources.list.d/mesosphere.list
$ sudo apt-get -y update
$ sudo apt-get -y install mesos marathon chronos
```

Zookeeperの設定を変更します。

```shell-session
$ sudo vi /etc/zookeeper/conf/myid
server.1=<マスタのIP>:2888:3888
server.2=<スレーブ1のIP>:2888:3888
server.3=<スレーブ2のIP>:2888:3888
server.4=<スレーブ3のIP>:2888:3888
```

Mesos-Slaveが立ち上がらないように設定を変更します。

```shell-session
$ sudo service mesos-slave stop
$ sudo sh -c "echo manual > /etc/init/mesos-slave.override"
```

Zookeeper/Mesos/Marathonをリスタートします。

```shell-session
$ sudo service zookeeper restart
$ sudo service mesos-master restart
$ sudo service marathon restart
$ sudo service chronos restart　#chronosを使う場合
```

これでマスタの設定は完了です。

##### 対象：スレーブ

次にスレーブにMesosとMarathonをインストールします。
手順はほとんどマスタと同じです。

Open JDK 8が必要なため、インストールします。

```shell-session
$ sudo apt-add-repository ppa:openjdk-r/ppa
$ sudo apt-get update
$ sudo apt-get -y install openjdk-8-jdk
```

MesosとMarathon（今回は関係ないですがChronosも）をインストールします。

```shell-session
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E56151BF
$ DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
$ CODENAME=$(lsb_release -cs)
$ echo "deb http://repos.mesosphere.com/${DISTRO} ${CODENAME} main" | sudo tee /etc/apt/sources.list.d/mesosphere.list
$ sudo apt-get -y update
$ sudo apt-get -y install mesos marathon chronos
```

マスタでZookeeperが起動しているため、設定を変更します。

```shell-session
$ sudo vi /etc/mesos/zk
zk://<マスタのIP>:2181/mesos
```

Zookeeper、Mesos-Master、Marathonが立ち上がらないように設定を変更します。

```shell-session
$ sudo service zookeeper stop
$ sudo sh -c "echo manual > /etc/init/zookeeper.override"
```

```shell-session
$ sudo service mesos-master stop
$ sudo sh -c "echo manual > /etc/init/mesos-master.override"
```

```shell-session
$ sudo service marathon stop
$ sudo sh -c "echo manual > /etc/init/marathon.override"
```

今回はDockerコンテナをMesosスレーブにデプロイするため設定を変更します。

```shell-session
$ echo 'docker,mesos' | sudo tee /etc/mesos-slave/containerizers
$ echo '3mins' | sudo tee /etc/mesos-slave/executor_registration_timeout
```

Mesos-Slaveをリスタートします。

```shell-session
$ sudo service mesos-slave restart
```

これでスレーブの設定も完了です。

参考
[Ubuntu 14.04にOpen JDK 8を導入する](http://note.kurodigi.com/ubuntu1404-openjava8/)
[Setting up a Mesos and Marathon Cluster](https://open.mesosphere.com/getting-started/install/)

## テストデプロイ
インストールが完了したので、ブラウザからMarathonのUIにアクセスします。
`` http://<マスタのIP>:8080 ``

<img width="1358" alt="marathon.png" src="https://qiita-image-store.s3.amazonaws.com/0/129013/f5cba491-1dd3-60d8-dc85-617dbcd05d51.png">

ここではテストとしてSSH可能なUbuntuをデプロイします。
イメージはDocker HubにPUSH済です。[[ubuntu-ssh]](https://hub.docker.com/r/ykshr/ubuntu-ssh/)

`` Create Application `` を押して表示されたNew Applicationに、デプロイするコンテナの情報を入力します。

<img width="400" alt="newapp.png" src="https://qiita-image-store.s3.amazonaws.com/0/129013/e7212f6c-d6e0-3587-1395-f82e27ce26c3.png">

General

* ID:適当
* CPUs:適当
* Memory:適当
* Disk Space:適当
* Command:/usr/sbin/sshd -D

Docker Container

* Image:ykshr/ubuntu-ssh
* Network:Bridged

Ports

* Container Port:22

`` Create Application `` を押します。
デプロイされたコンテナを確認するとデプロイ先のホストとマッピングされたポートが分かります。

<img width="1358" alt="newapp-deploy.png" src="https://qiita-image-store.s3.amazonaws.com/0/129013/aa3a3cc9-03fc-c453-0d30-c3c062ca23d8.png">

サンプルでデプロイしたubuntuはroot/rootでSSH可能にしていますので、クライアントPCから上記のホストとポートに対してSSHします。

```shell-session
$ ssh -p <ポート> root@<ホスト名>
```

無事ログインできれば成功です！

## 参考

参考にさせて頂きました。

[正月休みだし Mesos-Docker でプライベート IaaS っぽいもの構築してみた](http://blog.livedoor.jp/sonots/archives/35451869.html)
[瞬殺で作るMesos + Chronos + Marathon + Dockerクラスタ環境](http://qiita.com/TsuyoshiUshio@github/items/9d8f5b952b635d94ae6f)