【Serf】v0.6.0がリリースされたので使ってみた

【Serf】v0.6.0がリリースされたので使ってみた はてなブックマーク - 【Serf】v0.6.0がリリースされたので使ってみた


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