HashiCorp 社によるオーケストレーションツール、Serf の最新バージョン v.0.6.0 が 5/9 (現地5/8)に公開されました。
新機能としては、鍵ローテーション対応や、タグ指定のために外部 JSON ファイルが利用可能になったこと、’serf info’ で統計情報が出力されること、ノード追加時のオプションで’–retry-join’がサポートされたことがあげられます。改良点としては、’serf query’ の出力結果で JSON が選べるようになったほか、syslog へのログ出力が可能になったことです。
Serf 芸人(見習い)としては、とりあえず使ってみなくては!、という事で、以下検証になります。
■ README に目を通してみると
今回の更新情報を見るためには、README を読むのが手っ取り早いですね。
新機能を見ていくと、
- 鍵のローテーションを行えるよう、’serf keys’ コマンドと、-keyring-file オプションが利用可能になりました。’serf keys’ は、暗号化時に利用可能なオプションで、クラスタのメンバに対して、一斉に鍵の更新を通知/反映する仕組みとのこと。ただし、従来のオプション ‘-encrypt’ とは同時に使えません。(具体的な挙動は試そうとおもったのですが、-keyring-file の中身の記述方式がまだ分かってないので・・・JSON?)
- タグの外部ファイル読み込み、保存が可能になりました。エージェントを停止しても、タグの情報が保持されます。これは、’-tag-file’ を serf agent 起動時に指定すると、もしファイル内容 (JSON形式) があれば、それをタグとして読み込みます。また、変更があれば、指定ファイルを更新します。
- ‘serf info’ コマンドによって、serf ノードのデバッグ情報(イベントハンドラ発生回数など)を参照出来るようになりました。
- ‘-retry-join=<アドレス>’ は、serf agent 起動時の join 先が接続出来ない場合の、リトライ先を指定します。複数の join 先が指定できます。これは ‘-discovery’ が使えない
( mDNS に対応していない)環境で Serf クラスタを組むとき、SPOF になりがちな join 先を複数指定する時、有用になりそうです。’-retry-interval’ でリトライ間隔(デフォルトは 30 秒)を調整できるほか、’-retry-max’ で指定したリトライ回数を超えると自動的に Serf を停止する事もできます(デフォルトは 0 = 無限ループ)。
その他の主な改良点は、バグ修正、追加機能は、
- ‘-rejoin’ フラグによって、ノード離脱時に自動的に再接続を試みるかどうか指定
- ‘-syslog’ オプションによって、syslog ( /var/log/messages ) にログ出力可能に
- ‘serf query’ が JSON 形式の出力をサポート
- 設定ファイルに未知のタグがあれば警告が出るように
など、追加されているようです。詳細は、v0.6 の README をご確認ください。
以下、自分の気になった機能の検証です。
■ タグの外部ファイル保存対応
これまでの Serf エージェントのタグは、対象エージェントが停止すると情報が失われるため、例えば IP アドレスの差し替え作業が発生すると、同じ役割(同じインスタンス)を持った Serf エージェントであっても、都度、タグの設定が必要でした。
Serf エージェント起動時に ‘-tags-file’ を指定すると
- エージェント起動時に指定したタグの情報を読み込む(ここまでは従来も出来た)
- タグの情報が更新されたら、対象ファイルを動的に更新する
このような機能が追加されました。いわゆる、データ保全性といいますか、可用性が高まったのではないかと思います。エージェントを停止したり、エージェントが稼働している環境を移動しても、そのエージェントが動作している環境の情報を保持できるため、これは地味に便利そうです。
$ serf agent -tags-file=/opt/serf/serf-tags.json
このように起動するとして、予め JOSN ファイルの内容に
{
"role": "web"
}
記述があれば、自動的に反映されます。
$ serf members
manager.pocketstudio.net 192.168.39.3:7946 alive role=web
この状態でタグを更新しますと、
$ serf tags -set hello=world
Successfully updated agent tags
その結果がファイル内容にも反映されます。
$ cat /opt/serf/serf-tags.json
{
"role": "web",
"hello": "world"
}
■ serf query の結果を JSON で取得
‘serf query’ でクエリを発行するときのフォーマットを指定できます。
$ serf query sh uptime Query 'sh' dispatched Ack from 'manager.pocketstudio.net' Response from 'manager.pocketstudio.net': 06:27:47 up 3 days, 9:16, 8 users, load average: 0.00, 0.00, 0.00 Ack from 'node1.pocketstudio.net' Response from 'node1.pocketstudio.net': 11:10:26 up 3 days, 1:20, 2 users, load average: 0.00, 0.00, 0.00 Total Acks: 2 Total Responses: 2
出力するには ‘-format=json’ を追加します。位置は query の直後です。
$ serf query -format=json sh uptime
{
"Acks": [
"manager.pocketstudio.net",
"node1.pocketstudio.net"
],
"Responses": {
"manager.pocketstudio.net": " 06:28:55 up 3 days, 9:17, 8 users, load average: 0.00, 0.00, 0.00\n",
"node1.pocketstudio.net": " 11:11:34 up 3 days, 1:21, 2 users, load average: 0.00, 0.00, 0.00\n"
}
}
使いどころとしては、何かの外部処理結果を取り込んで、また別の仕組みと連携する事が期待出来そうですね。
■ syslog への出力対応
serf agent の起動オプションに ‘-syslog’ を追加すると、/var/log/messages に Serf のログが表示されるようになりました。ログというのは、serf agent 起動直後や、イベント発生時に表示される内容です。
# tail /var/log/messages May 9 06:08:39 manager serf[20593]: agent: Serf agent starting May 9 06:08:39 manager serf[20593]: serf: EventMemberJoin: manager.pocketstudio.net 192.168.39.3 May 9 06:08:39 manager serf[20593]: agent: joining: [192.168.39.3:7946] replay: false May 9 06:08:39 manager serf[20593]: memberlist: Responding to push/pull sync with: 192.168.39.3:36611 May 9 06:08:39 manager serf[20593]: memberlist: Initiating push/pull sync with: 192.168.39.3:7946 May 9 06:08:39 manager serf[20593]: agent: joined: 1 nodes May 9 06:08:39 manager serf[20593]: agent.mdns: Joined 1 hosts May 9 06:08:40 manager serf[20593]: agent: Received event: member-join
利点は、一般的な /var/log/messages を参照できるようになったので、ログを見たいときに都度 serf monitor コマンドを実行する必要がありません。また、syslog を通しますので、外部のサーバにログを送ったり、あるいは fluentd や logstash などで、Serf クラスタのログを一括収集させることも期待できます。
■ serf info でクラスタ情報の表示
‘serf info’ コマンドを実行すると、稼働しているサーバ上の、ローカルな Serf デバッグ情報(東経情報的なもの)が表示されます。
# serf info agent: name = manager.pocketstudio.net runtime: arch = amd64 cpu_count = 1 goroutines = 25 max_procs = 1 os = linux version = go1.2 serf: event_queue = 0 event_time = 1 failed = 0 intent_queue = 1 left = 0 member_time = 2 members = 1 query_queue = 0 query_time = 1 tags: hello = world role = web
また、’-format’ オプションが使えますので、JSON 形式を指定すると、結果を JSON で得ることも出来ます。何か他のツールと組みあわせると、Serf ノードの稼働状況正常性確認に応用できそうですね。
$serf info -format=json { "agent": { "name": "manager.pocketstudio.net" }, "runtime": { "arch": "amd64", "cpu_count": "1", "goroutines": "25", "max_procs": "1", "os": "linux", "version": "go1.2" }, "serf": { "event_queue": "0", "event_time": "1", "failed": "0", "intent_queue": "1", "left": "0", "member_time": "2", "members": "1", "query_queue": "0", "query_time": "1" }, "tags": { "hello": "world", "role": "web" } }
■ retry に関連するオプション
‘-retry-join’ は複数指定できますので、Serf クラスタに接続できない時の再接続先を冗長化できます。’-retry-join’ は、 ‘serf join’ の ‘-discovery’ が無い環境で力を発揮しそうです。
$ serf agent -retry-join=192.168.39.2 -retry-join=192.168.39.4 \ -retry-max=1 -retry-interval=5s
‘-retry-max’ は、指定した回数接続を試みます。’-retry-interval’は、再接続の為の時間を調整します(デフォルトは30s)。接続できない場合、次のようにログを出力して Serf は停止します。
[INFO] agent: joining: [192.168.39.2 192.168.39.4] replay: false [WARN] agent: error joining: dial tcp 192.168.39.4:7946: no route to host [ERR] agent: maximum retry join attempts made, exiting [INFO] agent: requesting serf shutdown [WARN] Shutdown without a Leave [INFO] agent: shutdown complete
■ 参考
GitHub 上の CHANGELOG.md
https://github.com/hashicorp/serf/blob/v0.6.0/CHANGELOG.md#060-may-8-2014