FluentdをMesos + Docker + Marathonで動かしてみた

Fluentd Advent Calendar 2013の一部です。(PST だとまだ 20 日なのでお許し下さい。。。)

最初は iOS からCocoaFluentLoggerでなんか送って遊んでみようかと思ってたんですが、単にタップした場所のログ送るくらいだったらあっさりできてしまって(CocoaFluentLogger の出来が良い)、それ以上楽しいことをやるには iOS のスキルが足りなかったので、急遽 Mesos で遊ぶことにしました。動かなかったらごめんなさい!

概要

今回は Mesos クラスタの上に Fluentd(td-agent)を好きな数だけ配置して、フロントとして HAProxy を立て、バックエンドに Elasticsearch を置いてみました。結果は Kibana で見ます。

Fluentd, HAProxy, Elasticsearch, Kibana はどれも Docker のコンテナにしています。今回は Fluentd のみ Mesos クラスタ上に Marathon 使って展開して、残りは Mesos master 上に手でコンテナを起動しています。エンドポイント的な存在は Marathon 使って配置すると host や port が変わるのでちょっと向きません。なんかいい感じの Framework が必要ですね。

確認した環境

作り方

build にあります。Ubuntu 13.04 をベースに Vagrantfile を書きました。細かいことを除くと、Mesosphere 提供のスクリプトで Mesos とかをまるっとインストールして、いくつか Docker コンテナを pull して、自作のコンテナを build してます。でかいんですが、package した box を dropbox に置いたので、試すときは自分で box 作る必要ありません。

試し方

先ほどの box を base に Vagrantfile を書きました。git clone して vagrant up してみてください。Mesos master が 1 台と Mesos slave が 2 台起動して、クラスタが組まれているはずです。始める前に Docker(LXC)の dnsmasq に hosts ファイルを確実に反映させるために、lxc-net を再起動します。(Docker コンテナはホストの dnsmasq で名前解決する設定にしてます) なんか調子が悪そうなら vagrant reload するといいかもしれません。。。

$ vagrant ssh mesos-master
$ sudo service lxc-net restart

$ vagrant ssh mesos-slave[12]
$ sudo service lxc-net restart

ではまず mesos-master にログインして、Elasticsearch と Kibana を起動します。

$ vagrant ssh mesos-master
$ sudo docker run -d -p 9200:9200 arcus/elasticsearch
$ sudo docker run -d -p 8888:80 -e ES_PORT=9200 -e ES_HOST=mesos-master arcus/kibana

これで手元のブラウザから http://mesos-master:8888 を見ると、Kibana が見えると思います。(hostmanager が laptop の hosts に追加してくれてるはず)

次に、Marathon 経由で td-agent を Mesos 上に展開します。env を渡したいので json を手で書いてます。

$ vagrant ssh mesos-master
$ cat /vagrant/td-agent.json
{
    "id": "td-agent",
    "instances": "2",
    "mem": "100",
    "cpus": "1",
    "executor": "/var/lib/mesos/executors/docker",
    "cmd": "td-agent",
    "env": {
        "ES_PORT": "9200",
        "ES_HOST": "mesos-master"
    }
}
$ cat /vagrant/td-agent.json | http POST http://mesos-master:8080/v1/apps/start
HTTP/1.1 204 No Content
Content-Type: application/json
Server: Jetty(8.y.z-SNAPSHOT)

Marathon のページ(http://mesos-master:8080)を見ると、td-agent が起動してると思います。

最後に、HAProxy を mesos-master 上の Docker で起動します。

$ vagrant ssh mesos-master
$ sudo docker run -d -p 5555:8080 -e MARATHON_URL=http://mesos-master:8080 -e APP_ID=td-agent -e HEALTH_PATH=/?json=%7B%7D haproxy

あとは徐ろに mesos-master:5555 に対して Fluentd の in_http のフォーマットでログを投げてあげると、Kibana で結果が見れるはず。

$ vagrant ssh mesos-master
$ http POST http://mesos-master:5555/test a=1

Mesos slave は片方落としてもそこで動いてた Fluentd のインスタンスは Marathon によって別の slave に移されます。ただし、HAProxy の方にそれを反映するために、コンテナを再起動(docker restart CONTAINER_ID)する必要があります。

苦労したポイント

Fluentd, ES, Kibana を Docker で動かすのは前回できていたので、あとは Mesos との結合が大変でした。Mesosphere のスクリプトが新しい Docker の形式に対応してなくてパッチ送ったり、Mesos の host 名と hosts ファイルの関係で苦労したり、Vagrant のネットワーク設定で苦労したり。。。

あと、Marathon の API から HAProxy の config を作るスクリプト書いたりしました。Mesoshpere が同じのを提供してますが、アプリケーション専用の HAProxy にしたかったので python でサクッと書きました。Fluentd の in_http はなにかパラメータ送ってあげないと 200 番返してくれないのでヘルスチェック用の path もカスタムできるようにしてます。

まとめ

言葉で説明するよりも、レポジトリを覗いて実際にマシンを動かしてもらえれば、Mesos + Docker + Marathon のおもしろさが少しは伝わるかと思います。また、もしこの環境の上で何かしようという方がいれば少しは参考にはなるかと思います。疑問等あればコメントか Twitter でどうぞ。

Fluentd についてまったく手を動かしてなくて申し訳ないです。本当は、HAProxy にログを投げる web app 書いて、それも Marathon で展開して、別の HAProxy 立てて、Mesos 素晴らしい!みたいなところまでやろうと思ったんですが、やる気が無くなったのでみなさんの宿題とします。やる気のある人は僕に聞いてもらえれば何をすればいいかは教えられますので興味ある方はぜひ。

僕はというと、ひとまず満足したので、iOS 作りに精を出したいと思います^^

参考リンク

  • opp 14-09-06 (土) 9:00

    こんにちは。
    試そうと思い box をダウンロードしようとしたところ、401 Not Authorized でした。
    可能であれば対応お願いします。
    (github のリリースページとか便利です)
    古い記事にすみません。


Ryosuke Iwanaga

Software engineer / Anime / NFL / Father. Posts are my own, not endorsed by any org.