fluentd-server 作った の続き。fluentd-server は Fluentd の設定ファイルを中央集権的に管理するやつ。

Fluentd Server で conf を書き換えた後に、Fluentd に反映するためには、Fluentd を再起動して回らないといけないのだけど、Fluentd Server 側からキックできるようになると良いよね、と思っていたので実装してみた。コードはこちら => fluentd-server

9426888a5ef54c3a0c75dd859ddcc56d

これを実現しようと思った場合、capistrano かなにかで、ssh で対象サーバにログインして sudo /etc/init.d/td-agent restart して回る、という仕組みにしがちだと思うんだけど、そうしようとすると td-agent が入っているホスト一覧を fluentd-server で管理する必要があって実はあまり良くない。すでに chef-server でホスト管理してたりとか、内製の鯖管ツールでホスト管理していたりするような所だと、二重管理になってしまうし、ホストがじゃんじゃん増減しがちな Immutable Infrastructure とか考えると、ホスト一覧のメンテとかできればやりたくない。

じゃあ、どうするか、というと serf を使うのがよさそうと思ったのでそうしてみた。serf については以前、正月休みだし Serf 触ってみた の記事を書いたのでそちらを見てもらうと良いのだけど、一言でいうとサーバのオーケストレーションツールというやつで、もう少し言うと、serf で組んだクラスタ全体にイベントを伝搬しながら、イベントに対応したスクリプトを実行してくれるやつ。

Fluentd Server を起動するとローカルで serf agent が1つ勝手に起動するので、あとは td-agent を動かすホストで、
$ fluent-gem install serf-td-agent
$
export PATH=$(fluent-gem path serf-td-agent)/bin:$PATH
serf agent -join={Fluentd Server のアドレス} -event-handler=serf-td-agent 
ってかんじで、今回作った serf-td-agent gem を入れつつ、Fluentd Server で動いている serf あてに join してもらえば、td-agent のクラスタができあがる。あとは、Fluentd Server の Task タブで Restart ボタンを押すと、Fluentd Server がローカル serf に
$ serf event td-agent-restart
ってかんじでイベントを送るので、td-agent サーバ全体にイベントが伝搬され、sudo /etc/init.d/td-agent restart が実行されるようになる。ちなみに、Fluentd Server のローカル serf はイベントを伝搬するだけで、特に event handler スクリプトは実行しない。

これから

Status ボタンのほうでは serf event (非同期、結果を待たない) ではなく、serf query (同期、スクリプトの実行結果を受け取れる)を使っているのだけど、そのコマンド結果を逐次画面に更新するあたりはまだ実装してない。最初、websocket でやろうかと思ってたんだけど、em-websocket を使うとかってことになると、unicorn サーバとは別ポートを開ける感じになって、運用しづらいツールになっちゃうかな、と思って悩んでる。古きよき Ajax にして unicorn サーバで捌いた方が良いだろうか。

おことわり

heroku デモでは動かない。

おわりに

serf をいい感じに応用できたんじゃないかな、と思っている。Enjoy!