Arukasを支えるApache Mesos × Marathon

# はじめに

今年の4月にさくらインターネットに入社し、早くも半年以上が経ちました。この数ヶ月は、前職のインフラエンジニアの経験を生かしながら、バックエンド・フロントエンドの開発ができ、大変実りの多い期間でした。

開発に関わったサービスは、ArukasというDockerコンテナホスティングサービスになります。

Dockerと言えば、オーケストレーションツールとしてkubernetesが有名です。一方で、Arukasは、Apache Mesos × Marathonのオーケストレーション環境を使用して、日本初のコンテナホスティングを実現しています。

今回は、それらについて説明すると同時に、docker-composeでの簡単な試し方をご紹介します。

# Apache Mesosとは?
カリフォルニア大学バークレー校で開発されたクラスタリソース管理フレームワークです。複数の物理マシン（または仮想マシン）を１つのクラスタとして管理し、各ノードのリソース状況に合わせて、タスクを割り当て実行する機能を持ちます。

ちなみに、Mesos Frameworksと呼ばれる機能フレームワークと連携することで、さまざな機能が実現可能です。その一つとして、Marathonとの連携でコンテナオーケストレーションが可能になります。

# Marathonとは?

Mesos Frameworksの一つとして開発された、オーケストレーションプラットフォームを実現するフレームワークです。

ハードウェア、ソフトウェアレベルで発生する障害に自動的に対処する目的で開発されました。具体的には、Dockerコンテナの展開、ストレージボリュームとの連携、タスクのスケジューリング、インスタンス台数のスケーリング機能、リソースの死活監視のヘルスチェックなどの機能を備えています。

# 必要な構成

Apache Mesos + Marathonの構成を動作させるには、主に4つのサービスが必要になります。

## 構成図
![006.jpeg](https://qiita-image-store.s3.amazonaws.com/0/231922/6380317c-a090-d3ca-480a-0c8b3e59e453.jpeg)
「コンテナ・ベース・オーケストレーション - Docker/Kurbernetesで作るクラウド時代のシステム基盤」の書籍より引用

## Mesos Master
Mesos SlaveやMesos Frameworksを取りまとめ、統合・連携のコントロールを行います。

Mesos Frameworksのタスク実行リクエストに応じて、Mesos Slaveにタスクの実行の指示を行い、その実行結果を取りまとめ、Mesos Frameworksに報告するような全体のコントロールを担います。

## Mesos Slave

各ノードにインストールされるエージェントです。ノードが保有するコンピューティングリソース（CPU、RAM、ネットワークなど）をMesosクラスタ全体で共有可能にします。

具体的には、Mesos Master経由でMesos Frameworksのリクエストを受け取り、それに応じたタスク処理を実行します。タスクの実行可能なリソースの確認、リソースに応じてタスクをノード上にデプロイする役割を担います。

## Marathon

Dockerコンテナリソースの最適な配置、コンテナアプリケーションのデプロイなどを行います。Webブラウザからタスクの操作や編集が出来るコントロールパネルが備わっています。今回は、このコントロールパネルからコンテナを起動する実例もご紹介します。

## Apache Zoomkeeper

クラスタやタスクの状態を保管しておくKey-Valueストアです。

MesosはそれらのデータをZoomkeeperに保存するように設計されているため必要になります。





# 実際に起動してみる

それでは、実際に上で説明した構成の構築・起動を行なってみようと思います。
今回は、Docker Hubで公開されているオフィシャルイメージを使用して、dokcer-composeで起動します。


## docker-compose.yml

以下のdocker-compose.ymlを作成するだけで構築・起動が可能です。

```
version: '3'

services:
  mesos-master:
    image: mesosphere/mesos-master:1.7.0
    hostname: mesos-master
    entrypoint: [ "mesos-master" ]
    ports:
      - "5050:5050"
    depends_on:
      - zookeeper
    environment:
      - MESOS_CLUSTER=local
      - MESOS_HOSTNAME=mesos-master.docker
      - MESOS_LOG_DIR=/var/log
      - MESOS_WORK_DIR=/var/lib/mesos
      - MESOS_QUORUM=1
      - MESOS_ZK=zk://zookeeper:2181/mesos

  mesos-slave:
    image: mesosphere/mesos-slave:1.7.0
    entrypoint:
      - mesos-slave
    privileged: true
    hostname: mesos-slave
    ports:
      - "5051:5051"
    depends_on:
      - zookeeper
      - mesos-master
    environment:
      - MESOS_CONTAINERIZERS=docker,mesos
      - MESOS_ISOLATOR=cgroups/cpu,cgroups/mem
      - MESOS_LOG_DIR=/var/log
      - MESOS_MASTER=zk://zookeeper:2181/mesos
      - MESOS_PORT=5051
      - MESOS_WORK_DIR=/var/lib/mesos
      - MESOS_DOCKER_STOP_TIMEOUT=50secs
      - MESOS_EXECUTOR_REGISTRATION_TIMEOUT=15mins
      - MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD=60secs
      - MESOS_RESOURCES=cpus:2;mem:2048;disk:20480;ports(*):[12000-12999]
      - MESOS_SYSTEMD_ENABLE_SUPPORT=false
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "$PWD/tmp/hadoop-2.8.0:/hadoop"

  marathon:
    image: mesosphere/marathon:v1.6.549
    hostname: marathon
    ports:
     - "8080:8080"
    depends_on:
      - zookeeper
      - mesos-master
      - mesos-slave
    extra_hosts:
      - "seaof-172-17-0-1.arukascloud.io:172.17.0.1"
    environment:
      - MARATHON_ENV_VARS_PREFIX="MARATHON_"
      - MARATHON_ZK=zk://zookeeper:2181/marathon
      - MARATHON_MASTER=zk://zookeeper:2181/mesos

  zookeeper:
    image: zookeeper:3.4.13
    hostname: zookeeper
    ports:
      - "2181:2181"
```

## 起動コマンド

```
docker-compose up
```
**全てのコンテナをイメージで起動しているためBuildは必要ありません。**

## Marathon URL

http://localhost:8080 にアクセスすると、Marathonのコントロールパネルが表示されます。

**これでApache Mesos × Marathon環境の構築・起動が出来ました。**

<img width="853" alt="Screen Shot 2018-12-13 at 18.04.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/231922/fa84cfea-f721-bf43-fc2a-e228571ff0d2.png">

# Nginxコンテナをデプロイする

Apache Mesos × Marathonが正常に起動したところで、実際にコンテナをデプロイしてみます。

## アプリケーションを作成する

まずは、「Create Apllication」をクリックすると、以下のようにアプリケーション作成ページが表示されます。

最初のページで任意のIDを入力して下さい。

<img width="740" alt="Screen Shot 2018-12-13 at 18.11.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/231922/ad67de60-eb41-c91d-3978-e20b892b5d6f.png">

Docker hubで公開されているImage名を入力します。今回は、「Nginx:latest」を使用します。

そして、Dockerネットワークに接続出来るように、Networkは必ず「Bridged」を選択して下さい。

<img width="740" alt="Screen Shot 2018-12-13 at 18.11.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/231922/80a6fce9-4ae7-be91-e015-f189f8480e6f.png">

最後に、ポート番号を入力します。ここでは、Dockerネットワーク内で使用されるポート番号を入力して下さい。

今回は、Web用のポートだけが開いていれば、デフォルト設定のNginxにアクセス出来ますので、「80番」と入力して下さい。

**コンテナ 0.0.0.0:80 -> ホスト localhost:ランダムポート**

<img width="739" alt="Screen Shot 2018-12-13 at 18.12.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/231922/1fb9bc2f-3924-550d-d97f-54b7e54ad012.png">

最後に、一番下の「Create Apllication」をクリックすると、自動的にアプリケーションの作成が始まります。

最初の「Status」が「Deploying」となっているが、しばらく待つと「Runnig」に変わります。「Runnig」となれば、正常にデプロイ出来たことになります。

<img width="853" alt="Screen Shot 2018-12-13 at 18.20.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/231922/4a26f31e-6625-c1a2-f360-df1853333746.png">

実際に、Nginxをブラウザで確認してみようと思いますが、接続用のランダムポートが必要になります。

ランダムポートは、アプリケーションの詳細から確認出来ます。

そのアプリケーションの詳細は、Name（nginx-application） => ID（nginx-application.89b9ccc1-feb9-11e8-b390-0242c0a8c005）の順にクリックすると確認が出来ます。赤丸で囲った箇所のポート番号を確認しておいて下さい。

<img width="1678" alt="Screen Shot 2018-12-13 at 18.29.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/231922/9356d8c6-375d-6b5f-6b29-9f82eb03e5d1.png">



<img width="601" alt="Screen Shot 2018-12-13 at 18.30.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/231922/aef24164-487d-42c2-1e1a-d8a55509ca05.png">

localhost経由で確認したポート番号を指定すると、Nginxの初期ページが表示されます。

http://localhost:12705
**ポート番号は起動する度にランダムに変わります。**

<img width="607" alt="Screen Shot 2018-12-13 at 18.36.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/231922/0998315e-68ef-f28a-cc43-971181e19e3e.png">

# まとめ

今回は、最も簡単にデプロイ出来るNginxイメージで試しましたが、自分でイメージを手作りすることで、開発したアプリも簡単にデプロイ出来ます。

日本ではあまり有名ではないApache Mesos × Marathonですが、TwitterやNetflixで使用された実績がある、安定したコンテナオーケストレーション環境です。

興味を持っていただけましたら、一度触ってみて下さい。出来たら、Arukasの方もよろしくお願します。