【検証】Serf 0.5.0の新機能を試してみた【queryが便利】

【検証】Serf 0.5.0の新機能を試してみた【queryが便利】 はてなブックマーク - 【検証】Serf 0.5.0の新機能を試してみた【queryが便利】


Serf version 0.5.0 が 3月12日付けでリリース(CHANGELOG)。

今回は新しく「query」コマンドがサポートされた事が、一番大きな変更点の模様。コマンドの実行結果が確認できるので、個人的にはこれが強力な機能と思ってます、例えば、複数のリスト化されていないサーバ群に対して、一括 SSH コマンドの実行&結果確認が出来るようになりました。勿論、任意のスクリプトを実行させることも出来ますし、何気に運用が弁理になりそうと期待しています。

その他、の主な変更点は、serf コマンドに reacability (到達性) がサポートされたり、serf member で -name によるフィルタがサポートされたこと、そして、member-reap イベントのサポートなど。

以下、query コマンドと reachability 機能を試してみました。

◆ 新しい query コマンドとは

「query」は、これまでの「event」コマンドと同じように動作します。「serf event」コマンドは、実行すると、あらかじめ指定したスクリプトなりコマンドが実行されます。ただし、これまではコマンドの実行結果を確認することが出来ませんでした

一方の「serf query」コマンドは、コマンド実行結果をクライアント側で受け取ることが出来ます。これが event コマンドとの違いです。event コマンドでは、コマンドが正常終了したかどうかは直接確認することが出来ず、ファイルに書き出すなり、何らかの処理を実行する必要がありました。serf query  であれば、そのような手間が無くなります。

例として、複数台のサーバで uptime を同時に実行し、結果を確認する query を指定します。query を使うためには、event と同じように、serf agent 起動時に指定します。

$ serf agent -iface=eth1 -discover=serf -event-handler=query=uptime

設定のポイントは、「query」イベント発生時に、指定するコマンドを「-event-handelr=query=コマンド名」で指定する事です。ここでは uptime コマンドを記述しましたが、任意のスクリプトを指定できます。

複数台の serf agent を上記の設定で稼働させます。その状態で serf のコマンドラインでイベントを発行するには「serf query」コマンドを実行します。以下は実行例です。

serf query test
Query 'test' dispatched
Ack from 'node2.pocketstudio.net'
Response from 'node2.pocketstudio.net':  23:52:55 up  5:23,  2 users,  load average: 0.00, 0.00, 0.00
Ack from 'node1.pocketstudio.net'
Response from 'node1.pocketstudio.net':  23:52:55 up  5:08,  2 users,  load average: 0.04, 0.01, 0.00
Total Acks: 2
Total Responses: 2

このように、コマンドライン上で、各サーバの状況が確認できます。

では、次にクエリ名の指定方法です。上記の例では、serf query コマンド実行時に、常に uptime が走ってしまいます。実際には、クエリ名によって、コマンドを使い分ける事が出来ます。

例えば、query名が「check」の場合にのみ uptime を実行させる場合、次のように指定します。

$ serf agent -iface=eth1 -discover=serf -event-handler=query:check=uptime

こうしておけば、先ほどのように適当に query コマンドを発行しても

$ serf query test
Query 'test' dispatched
Ack from 'node2.pocketstudio.net'
Ack from 'node1.pocketstudio.net'
Total Acks: 2
Total Responses: 0

何もレスポンスはありません。

では、query に「check」という名前を与えてみると、次のように実行されます。

# serf query check
Query 'check' dispatched
Ack from 'node2.pocketstudio.net'
Response from 'node2.pocketstudio.net':  23:56:37 up  5:27,  2 users,  load average: 0.00, 0.00, 0.00
Ack from 'node1.pocketstudio.net'
Response from 'node1.pocketstudio.net':  23:56:38 up  5:12,  2 users,  load average: 0.00, 0.00, 0.00
Total Acks: 2
Total Responses: 2

このように、各サーバで uptime コマンドが実行されました。

では、次に汎用的にコマンドを実行させる事を試します。クエリ名「sh」の時に、シェルとして「/bin/sh」に処理を引き渡します。

# serf agent -iface=eth1 -discover=serf -event-handler=query:sh=/bin/sh

この状態で、serf  query コマンドを実行します。uptime という引数(Serfでは payload と呼ばれています)を付けてみると、同様の処理が実行されます。

$ serf query sh uptime
Query 'sh' dispatched
Ack from 'node2.pocketstudio.net'
Response from 'node2.pocketstudio.net':  00:02:03 up  5:32,  2 users,  load average: 0.15, 0.03, 0.01
Ack from 'node1.pocketstudio.net'
Response from 'node1.pocketstudio.net':  00:02:03 up  5:18,  2 users,  load average: 0.00, 0.00, 0.00

Total Acks: 2
Total Responses: 2

他にも、Apache の状態確認を service コマンドで行ってみましょう。

$ serf query sh 'service httpd status'
Query 'sh' dispatched
Ack from 'node2.pocketstudio.net'
Response from 'node2.pocketstudio.net': httpd (pid  1059) is running...
Ack from 'node1.pocketstudio.net'
Response from 'node1.pocketstudio.net': httpd (pid  1060) is running...

Total Acks: 2
Total Responses: 2

このように状況を確認するだけでなく、

# serf query sh 'service httpd stop'
Query 'sh' dispatched
Ack from 'node2.pocketstudio.net'
Ack from 'node1.pocketstudio.net'
Response from 'node2.pocketstudio.net': Stopping httpd: [  OK  ]
Response from 'node1.pocketstudio.net': Stopping httpd: [  OK  ]
Total Acks: 2
Total Responses: 2

一括して停止することも出来ます。

注意点としては、標準で扱えるのは 1024 byte までのようです。それ以上のデータを受け取ろうとすると警告が出て処理されません。とはいえ、一般的なコマンドの実行と結果の確認程度であれば、十分と考えられます。

◆serf query の面白いところ

serf query の使いどころは、「-tag」と組みあわせられる点です。たとえば、従来ウェブサーバに相当するサーバ群で、一斉にコマンドを実行したい時は、あらかじめ手許に対象サーバのリストが必要でした。serf であれば「-tag」で指定されたタグ名のサーバ群に対して一斉処理を行えるため、リストが無くても(動的にホスト一覧が替わってしまう環境でも)制御できるのがユニークな所。

正確なホスト名や IP アドレスのリストが無くても、serf を用いて tag の適切な管理を行えるようになります。アイディア次第で、面白い事が出来そうなので、運用現場としては活用のしがいがあるのではないでしょうか。

◆serf query をスクリプトで管理するには

新しいイベントハンドラ「SERF_QUERY_NAME」がサポートされました。従来のイベントハンドラ管理用のスクリプトがあれば、環境変数によって、様々な処理の使い分けが期待できます。

指定例:
$ serf agent -event-handler=/opt/serf/query.sh

たとえば、クエリ名によって処理をわけたい場合は、query.sh の内容を次のようにします。

#!/bin/sh

read line
echo ${line}

case ${SERF_QUERY_NAME} in
    "uptime")
        uptime;;
    "date")
        date;;
    "w")
        w ${line};;
    "sh")
        ${line};;
esac

exit 0

クエリ名が「uptime」であればuptime、「date」であればdate、「w」はwを実行します。スクリプト中の${line}は payload(引数)にあたる部分です。クエリ名「sh」の場合は、そのまま任意のコマンドを実行させています。

ポイントとしては、従来のイベントハンドラと共存出来る点です。何かしら、イベント発生時に結果を返したい場合、この SERF_QUERY_NAME を活用することが出来るようになりました。

◆serf の到達製確認

地味に便利なのが、この機能かもしれません。serf のコマンドラインのオプションで、各ノードの到達性を確認出来ます。serf members でも一覧が表示されますが、このコマンドは数値で返すので、状況によっては分かりやすいのではないでしょうか。

$ serf reachability
Total members: 2, live members: 2
Starting reachability test...
Successfully contacted all live nodes

オプションで「-verbose」を付けると、秒数まで表示されます。

$ serf reachability -verbose
Total members: 2, live members: 2
Starting reachability test...
        Ack from 'node2.pocketstudio.net'
        Ack from 'node1.pocketstudio.net'
Query time: 3.20 sec, time to last response: 0.13 sec

このように結果を数値で取得できます。そのため、これを他の監視ツールに引き渡すことで、正常性やレスポンスの監視に応用することが期待出来ますね。

◆参考

Commands: Query – Serf
http://www.serfdom.io/docs/commands/query.html

Commands: Reachability – Serf
http://www.serfdom.io/docs/commands/reachability.html