正月休みだし1人ハッカソンやろうかなぁと思って、Mesos を触ってみたのでそのメモ。ちなみに昨日は Serf  を触った。

触ってみた動機

はてなの人たちがサービス開発合宿を開催しましたの中で、

ということをやっていておもしろそうだったので自分もやってみた。記事を読む限りは最近流行りの Immutable Infrastructure を実現するのに Mesos がとても重要なポジションを占めることになりそうな気がしたので今のうちに触っておこう、と。

もう少し言うと上記の記事を読む限り、Mesos を使うと従来 vm を建てる時に、リソースが空いている物理サーバを見つけるために

  1. 物理サーバにすでに載っている vm の一覧を作る
  2. vm がそれぞれ使っている CPUコア数, メモリリソースを取得し、合計する
  3. 物理サーバのリソース - 2の合計 = 空き、があるか確認する

とかやってる作業を自動化できるというか、つまるところ AWS (EC2) みたいなものを自分で作れるのかな?と思って確認のために触ってみた。プライベート IaaS キタコレ。

Mesos とは

「めそす」と読むっぽい。オフィシャルサイト mesos.apache.org の Introduction を適当に要訳するとこんなかんじ

リソース効率の高い分散システムを簡単に作れる Apache Mesos

Apache Mesos は、分散アプリケーション or フレームワークに対して、効率的なリソース分離、共有を提供するクラスタ管理ソフトです。Mesos を使うと、ノードの動的共有プール上で Hadoop, MPI, Hypertable, Spark, その他のアプリケーションを走らせることができます。

特徴

  • ZooKeeper を使ったフォールトトレラントな複製マスター
  • 10,000 ノードのスケーラビリティ
  • Linux コンテナとタスク間の分離
  • マルチリソーススケジューリング (メモリとCPU)
  • 新しい並列アプリケーションを開発するための Java, Python, C++ のAPI
  • クラスタの状態を表示するためのWeb UI

つまり、物理マシン(物理じゃなくてもいいけど)を一杯ならべて1つのクラスタとして管理し、タスクを走らせる時に効率的にリソースの分配をして実行してくれるものらしい。

Twitter で使っているとか。

Mesos のインストール

Getting Started をやってみる。

簡単に試すには Mesosphere, Inc が Mesos を AWS (EC2) 上で簡単に試せる Elastic Apache Mesos というものを提供しているようなのでそれを使うのが良さそう ※うまいかんじにリソース管理して vm インスタンス作ってくれる EC2 上でさらにリソース管理アプリを動かすとかなんかシュール^^

前提パッケージインストール

なんか色々必要っぽい。これは辛い ^^; なお、CentOS 6.2 環境2台で作業している。

sudo yum install gcc-c++
sudo yum install python26-devel python-devel
sudo yum install cppunit-devel
sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
sudo yum install libunwind-devel
sudo yum install java-1.7.0-openjdk-devel

Getting Started に書いてないけれど、以下も必要だった

sudo yum install zlib-devel libz*
sudo yum install libcurl*

Mesosのインストール

ダウンロードしてビルド

wget http://ftp.riken.jp/net/apache/mesos/0.14.2/mesos-0.14.2.tar.gz
tar zxvf mesos-0.14.2.tar.gz
cd mesos-0.14.2
./configure
make

20分ぐらい待つ ^^;

Example Frameworksを走らせてみる

ちょっと Mesos でいうところの Framework が何を意味しているのかわからないけれど、とにかく Getting Started どおりに動かしてみる

Mesos Master の起動。デフォルトは 5050 番ポートなんだけど、作業環境の諸事情により 8080 番ポートで起動。

$ bin/mesos-master.sh --port=8080
I0104 16:52:20.463269 42585 main.cpp:115] Starting Mesos master
I0104 16:52:20.463495 42605 master.cpp:269] Master started on 192.168.0.1:8080
I0104 16:52:20.463572 42605 master.cpp:284] Master ID: 201401041652-311501066-5050-42585

これで 192.168.0.1:8080 のIPアドレス:ポートで Mesos Master が起動したっぽい。Web UI があるらしいのでブラウザから

http://192.168.0.1:8080

にアクセスしてみるとダッシュボードが見れる。こんなかんじの画面

MesosDashboard_Main

次に Mesos Slave を起動してみる. 5051 ポートで起動したっぽい。

$ bin/mesos-slave.sh --master=192.168.0.1:8080
I0104 16:57:38.998226 49331 slave.cpp:114] Slave started on 1)@192.168.0.1:5051
I0104 16:57:38.998725 49331 slave.cpp:214] Slave resources: cpus(*):32; mem(*):22966; disk(*):272424; ports(*):[31000-32000]

Mesos Master 側を覗いてみると、以下のように slave が追加されたと表示されている。

I0104 16:57:39.001976 42609 master.cpp:1075] Attempting to register slave on host1 at slave(1)@192.168.0.0.1:5051
I0104 16:57:39.002029 42609 master.cpp:2167] Adding slave 201401041652-311501066-5050-42585-0 at hst1 with cpus(*):32; mem(*):22966; disk(*):272424; ports(*):[31000-32000]
I0104 16:57:39.002377 42627 hierarchical_allocator_process.hpp:445] Added slave 201401041652-311501066-5050-42585-0 (host1) with cpus(*):32; mem(*):22966; disk(*):272424; ports(*):[31000-32000] (and cpus(*):32; mem(*):22966; disk(*):272424; ports(*):[31000-32000] available)

Slave が1台だと面白みがないので、もう1台別のマシンも Mesos Slave として Master につないでみる。これで Slave 2台の構成に。

$ bin/mesos-slave.sh --master=192.168.0.1:8080

Mesos Dashboard の Slave タブを開くと追加されていることがわかる。

MesosDashboard_Slave

では、サンプルタスクを走らせてみる。Mesos の python 部分のテストを Mesos で走らせるサンプルっぽい?

src/examples/python/test-framework 192.168.0.1:8080

実行すると ActiveFrameworks に処理が表示され、終わると TerminatedFrameworks に表示がうつる。

MesosDashboard_Terminated

TerminatedFrameworks のリンクをクリックすると、どのホストでタスクが実行されたのかがわかる。

MesosDashboard_Completed

Host が2つにバラけているので、Mesos がうまい具合にタスク単位で複数 Slave に処理を分散させてくれているっぽいことがわかったけど、タスクの定義をどこでやっているのかがよくわからないので後で調べる。誰か教えて ;-)

Marathon とは

さきほど試したかんじだと、Mesos は基本的には、タスクを走らせるときにリソースを割り当てて、そのタスクが終わったらリソースを解放する、という動きをするものだった。

ウェブアプリのように常時起動するようなアプリケーションを動かす場合には、別の仕組みが必要で、それを可能にするのが Marathon という(メタ)フレームワークらしい。

Marathon の README を適当に要訳するとこんなかんじ。Mesos 触る前に読んだ時は意味不明だったけど、ちょっとは意味がわかるようになってきた。

Marathon は long-running サービスのための Mesos フレームワークです。Mesos が kernel だとしたら、Marathon はinit や upstart デーモンのようなものです。

Marathon はサービスを開始、停止、スケールさせるための REST API を提供します。Marathon は Scala で書かれており、複数の Marathon インスタンスを走らせる事で高可用性を確保できます。実行中タスクの状態は Mesos の抽象的な状態として保存されます。

Marathon はメタフレームワークなので、Chronos や Storm といった他の Mesos Framework を Marathon 上で走らせる事ができます。Marathon は標準シェルから起動できるものならなんでも原知らせる事ができます。Marathon 上で Marathon を走らせることもできます。

特に Mesos 試す前は「Mesos が kernel で」みたいなことが書いてあったから、本当に OS なのかと盛大に勘違いしていた。その上で Linux を動かすのかな?とか思ってたので、危なかった ^^;

Marathon のインストール

Marathon の README どおりに Mesos に Marathon を追加してみる。

事前準備

ZooKeeper 付きで起動しないといけないらしいので、ちょっと作業し直す。ZooKeeper は Mesos にくっついてダウンロードされている。

# cd /path/to/mesos
cd 3rdparty/zookeeper-3.3.4
cp conf/zoo_sample.cfg conf/zoo.cfg sudo ./bin/zkServer.sh start cd -

Mesos を ZooKeeper 付きで起動しなおす.

bin/mesos-master.sh --zk=zk://localhost:2181/mesos
bin/mesos-slave.sh --master=zk://localhost:2181/mesos

Marathonのビルド

git clone して mvn build して jar を作る。めんどい。

maven を入れる

wget http://ftp.tsukuba.wide.ad.jp/software/apache/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.zip 
unzip apache-maven-3.1.1-bin.zip
sudo mv apache-maven-3.1.1 /opt/maven

marathon をビルド

cd
git clone git@github.com:mesosphere/marathon.git
cd marathon
/opt/maven/bin/mvn package

target/marathon-0.2.2-SNAPSHOT-jar-with-dependencies.jar ファイルが出来た。

Marathonを起動

bin/start --master zk://localhost:2181/mesos --zk_hosts localhost:2181

8080番ポートで Marathon UI が起動するらしいのでアクセスしてみる。

Marathon

右上の New ボタンを押すとアプリケーション設定がでてきて、実行するコマンドと割り当てるリソースを指定できる。 試しに仮想ウェブアプリということで ncコマンドで簡易HTTPサーバ をたてて遊んでみる。

while true; do ( echo "HTTP/1.0 200 Ok"; echo; echo "Hello World" ) | nc -l $PORT; done

Marathon_New

アプリが追加されるのでクリックしてみると、編集画面が表示されて、Scale ボタンからインスタンスの数を増やしたり、Destroy ボタンで破棄したり出来る模様。下の画像はインスタンスを2つにしてみた結果の画像。1つはホスト w5 で、もう1つはホスト w6 で実行されている。ぶ、分散されてる!:D

Marathon_Edit

ここで表示されているポート番号が $PORT 変数に設定されて、nc コマンドが起動されているっぽいので、curl で試してみる

$ curl http://localhost:31826
Hello World

おー、できた。さらに Mesos Slave でプロセスを確認すると、

$ ps -ef | grep "nc -l"
sonots     15994 15931  0 19:31 ?        00:00:00 sh -c while true; do ( echo "HTTP/1.0 200 Ok"; echo; echo "Hello World" ) | nc -l $PORT; done

と確かにプロセスが起動していることを確かめられた。なお、このプロセスの親プロセスが

$ ps -ef | grep 15931
sonots     15931  4165  0 19:31 ?        00:00:01 /home/sonots/mesos-0.14.2/src/.libs/lt-mesos-executor
sonots     15994 15931  0 19:31 ?        00:00:00 sh -c while true; do ( echo "HTTP/1.0 200 Ok"; echo; echo "Hello World" ) | nc -l $PORT; done

のように mesos-executer とやらになっていて、こいつがリソースの利用を制限したりしているのだろうけれど、この辺りまだどうやってるのかわかっていない。

あと、今回は UI 上でアプリを追加したり削除したりしてみたけれど、REST API が用意してあって、コマンドラインで追加、削除することも出来る模様。ありがたい。

Mesos-Docker

Marthon でウェブアプリを動かせるようになったけれど、Mesos Slave 上でそのままアプリが動くわけなので、例えば rails アプリを動かそうとおもった場合、どの Mesos Slave に配分されても動くように全ての Mesos Slave に ruby をインストールしておかないといけないわけで、これが perl アプリ、python アプリ、memcached、nginx のように多岐にわたると辛い思いをすることが想像に難くない。

というわけで、Docker コンテナに環境を隔離して、Docker コンテナとアプリを同時に起動させたい、というのは当然の発想だと思う。それを実現してくれるのが Mesos-Docker なんだと思う。便利!

ということでこの辺は明日やる。まだ触ってない ^^;

おまけ

せっかく調べたので蛇足っぽい気もするけど、もうちょっとメモを晒す

数少ない日本語リソースの中から Mesos: A Cloud Scheduler (1) - steps to phantasien の記事を引用させてもらうと

資源割り当ては大きな分散システムにとって一般的な問題。実際 Hadoop の中にはそんな仕組みがあるわけだけれど、同じ事を Hadoop 以外でもやりたい。

ということで、Mesos は、Hadoop がやっていた資源割り当てを、Hadoop 以外でも使えるように一般化したもの、と考えてよいらしい。 そちらの記事でも言及しているけど、今は Hadoop 本体でも YARN という形で、データ処理とクラスタリソースマネジメントを分離したらしいので、それと競合になっている。

その辺が気になる Hadoop 界隈の人は @kimutansk さんの Hadoop YARNとApache Mesosの違いって何? - 夢とガラクタの集積場 の記事を読むと良さそう。 要約すると、Hadoop で使うにはもちろん YARN のほうがいいけど、それ以外のアプリケーション(Dockerとか)目的で使うには Mesos のほうが仕組みが出来上がっているという印象。ってかんじですかね。

あと、Jenkins を Mesos 上で動かすこともできるっぽい => jenkinsci/mesos-plugin。 Jenkins slave でタスクを実行するときに、いいかんじにリソース配分してくれて並列実行してくれるのかな。なんか良さそう。今回は触ってないけど. 

まとめ

Mesos (+ Marathon) を触ってみた。

  1. Mesos はクラスタリソースマネージャ。物理マシン(物理じゃなくてもいいけど)を一杯ならべて1つのクラスタとして管理し、タスクを走らせる時に効率的にリソースの分配をして実行してくれるもの
  2. Mesos は基本的にはタスクを走らせるときにリソースを割り当てて終わったら解放する動きをするため、ウェブアプリのように常時起動するようなアプリケーションを動かすためには別の仕組みが必要で、それを可能にするのが Marathon

ということがわかった。元々プライベート IaaS が作れるのかな?と思って触った Mesos だけれども、Mesos そのものはもっと用途が広くて、Jenkins のジョブを分散処理させるのに使えたりするということもわかった。

まだ Mesos-Docker を触っていないので結論を出すのは早いのだけど、プライベート IaaS っぽいものを作れそうな気がしてきたし、はてなの人たちがやっていたような Immutable Infrastructure というか Blue-Green Deployment の仕組みも作れそうなのでワクテカしている ← 今ココ

ただ、タスクの分配アルゴリズムや、リソースの利用を制限している仕組みなど、詳細な仕組みがまだ良くわかっていなかったりするので、そのあたりは今後の課題としたい。誰か詳しい人教えて :D 

続き: 正月休みだし Mesos-Docker 触ってみた 

Further Reading

日本語リソースがほとんどないのだけれど、自分の観測範囲では Mesos の記事を書いているのは @jedipunkz 氏、@kimutansk氏、@riywo 氏のお三方ぐらいなのでこの三人をフォローしておけば良いのかな。特に @kimutansk 氏は論文まで読んでいるようで頭が下がります。参考になりますm(_ _)m