Edited at

consul-templateのイベント発火トリガーについて調査した

More than 1 year has passed since last update.

ざっくり説明するとconsul-templateとは

consulの様々なイベントを検知して

「テンプレート更新」 > 「任意のコマンド実行」

してくれるツールです。

今回実現したかったのは consul-kvsの変更をトリガーにしてほげほげする ことです。

最初はconsul-templateがどういう条件でイベント発火するのかよくわからなかったのですが、

ドキュメントをよく見たらその辺りの仕様が記載されていたのでメモしておきます。



どういう条件でwatchしているのか?

何の事はない話で、基本的には

読み込むテンプレート内で利用している値が変更されたかどうか

を見ているようです。

素晴らしいですね。(※一部例外あり)



例: kvsのキーの値を監視する場合

以下のようなテンプレートで key を参照するだけでよいです。


/tmp/in_watch_key.tmpl

update hogekey > {{ key "/hogekey" }}



こんな感じでconsul-templateを実行して…

consul-template   -consul xxx.xxx.xxx.xxx:8500 -template "/tmp/in_watch_key.tmpl:/tmp/out_watch_key.tmpl:cat /tmp/out_watch_key.tmpl"


kvsを変更すると、以下のように表示されます(きちんと値が変わった時だけ発火する)

# kvsへput

curl -XPUT -d 'blahblahblah' http://xxxxxxx:8500/v1/kv/hogekey

# consul-template側
...
update hogekey > blahblahblah



APIリファレンス

ついでに、どのようなAPIが定義されているかも記載しておきます。

see also: https://github.com/hashicorp/consul-template#api-functions


datacenters

カタログ内の全てのデータセンターを表示(イベント発火なし)。

{{datacenters}}


file

agent側のローカルファイル変更(中身を見ている様子)を監視/発火。

ユースケースがいまいち思いつかない…

また、consul-template起動時にファイルが存在していないとエラーになります。

{{file "/path/to/local/file"}}


key

kvsのkeyの値を監視/発火。

{{key "service/redis/maxconns"}}

# データセンター指定版

{{key "service/redis/maxconns@east-aws"}}


ls

kvsの指定したprefixトップレベルの全てのキーバリューを監視/発火。

{{range ls "service/redis"}}

{{.Key}} {{.Value}}{{end}}

上記の場合、 "service/redis/*"階層のキーバリューの変更 を監視します。


nodes

カタログ内の全てのノードを監視/発火。

{{nodes}}

# データセンター指定版

{{nodes "@east-aws"}}


service

指定されたサービスグループに対して監視/発火。

# webappサービスを表示

{{service "webapp"}}

# rangeでは []*Service 構造体を返す

{{range service "webapp@datacenter"}}
server {{.Name}} {{.Address}}:{{.Port}}{{end}}

# デフォルトではヘルシーなサービス情報のみ表示するが、ステータスを指定して表示も可能

# ステータス関係なくすべてのサービスを表示
{{service "webapp" "any"}}
# ステータス=passing のサービスを表示
{{service "webapp" "passing"}}
# ステータス=passing or warning or critical のサービスを表示
{{service "webapp" "passing, warning, critical"}}


services

カタログ内のすべてのサービスを表示。(サービス変更時のイベント発火について未確認)

{{services}}

# データセンター指定版

{{services "@east-aws"}}

# rangeで取ると、サービスの構造体でデータ参照することが出来ます

# see. http://www.consul.io/docs/agent/services.html
{{range services}}
{{.Name}}
{{range .Tags}}
{{.}}{{end}}
{{end}}


tree

kvsの指定したprefix以下の全てのキーバリューを監視/発火。

{{range tree "service/redis"}}

{{.Key}} {{.Value}}{{end}}

上記の場合、 "service/redis/*" 以下の階層のキーバリューの変更 を監視します。



補足: ls と tree の違い

ドキュメント読んでてもいまいちイメージがわからなかったので

実際に動かして試してみました。

ls と tree は、そのままUnixコマンドのイメージで考えるとわかりやすいと思います。

ls は 指定した階層のみ 、 tree は 指定した階層以下すべて を対象にします。


Example: ls

以下はすべて "service/redis" を指定している時の挙動です。

# NG: 指定したキーそのものを更新しても発火しません

curl -XPUT -d 'data' http://localhost:8500/v1/kv/service/redis

# OK: 配下のキーが増えた時
curl -XPUT -d 'xxx.xxx.xxx.xxx' http://localhost:8500/v1/kv/service/redis/node1
# OK: 配下のキーの値を更新した時
curl -XPUT -d 'yyy.yyy.yyy.yyy' http://localhost:8500/v1/kv/service/redis/node1

# NG: 階層を超えて増やしても発火しません
curl -XPUT -d 'aaa.aaa.aaa.aaa' http://localhost:8500/v1/kv/service/redis/node0/master
# NG: 深い階層のキーの値を更新しても発火しません
curl -XPUT -d 'bbb.bbb.bbb.bbb' http://localhost:8500/v1/kv/service/redis/node0/master


Example: tree

以下はすべて "service/redis" を指定している時の挙動です。

# NG: 指定したキーそのものを更新しても発火しません

curl -XPUT -d 'data' http://localhost:8500/v1/kv/service/redis

# OK: 配下のキーが増えた時
curl -XPUT -d 'xxx.xxx.xxx.xxx' http://localhost:8500/v1/kv/service/redis/node1
# OK: 配下のキーの値を更新した時
curl -XPUT -d 'yyy.yyy.yyy.yyy' http://localhost:8500/v1/kv/service/redis/node1

# OK: 階層を超えて増えた時
curl -XPUT -d 'aaa.aaa.aaa.aaa' http://localhost:8500/v1/kv/service/redis/node0/master
# OK: 深い階層のキーの値を更新した時
curl -XPUT -d 'bbb.bbb.bbb.bbb' http://localhost:8500/v1/kv/service/redis/node0/master


まとめ

consul-template、便利すぎてヤバい