share facebook facebook twitter menu hatena pocket slack

2015.02.19 THU

俺の consul チートシート(3)

川原 洋平

WRITTEN BY 川原 洋平

ども、あらためて Consul を勉強している cloudpackかっぱ (@inokara) です。

はじめに

consul exec や consul watch あたりを色々と試してみる。

参考

consul exec

ざっくりホワっと

クラスタ内のノードにて一斉にコマンドを実行させることが出来るという脳筋な自分にはとても嬉しいコマンド。

トライ

例えば consul クラスタ内のノードでリーダーノードの確認をしてみる。

$ consul exec curl -s -X GET http://localhost:8500/v1/status/leader
    ip-xxx-xx-xx-36: "xxx.xx.xx.36:8300"
==> ip-xxx-xx-xx-36: finished with exit code 0
    ip-xxx-xx-xx-35: "xxx.xx.xx.36:8300"
    ip-xxx-xx-xx-37: "xxx.xx.xx.36:8300"
==> ip-xxx-xx-xx-35: finished with exit code 0
==> ip-xxx-xx-xx-37: finished with exit code 0
3 / 3 node(s) completed / acknowledged
$

上記のように各ノードでの実行結果が返ってくる。

さらに、yum でパッケージのインストールなんかも…。

$ consul exec sudo yum install htop
    ip-xxx-xx-xx-36: sudo: sudo を実行するには tty がなければいけません。すみません
    ip-xxx-xx-xx-36:
==> ip-xxx-xx-xx-36: finished with exit code 1
    ip-xxx-xx-xx-37: sudo: sorry, you must have a tty to run sudo
    ip-xxx-xx-xx-37:
==> ip-xxx-xx-xx-37: finished with exit code 1
    ip-xxx-xx-xx-35: sudo: sorry, you must have a tty to run sudo
    ip-xxx-xx-xx-35:
==> ip-xxx-xx-xx-35: finished with exit code 1
3 / 3 node(s) completed / acknowledged

惜しい、root 権限が必要なコマンドはちょっと敷居が高そう…。(すみませんと謝られてもこちらが恐縮する…)

また、全てのノードではなく一部のノードのみで実行させたい場合には以下のように --node オプションを付けて実行する。

$ consul members
Node             Address            Status  Type    Build  Protocol
ip-xxx-xx-xx-36  xxx.xx.xx.36:8301  alive   server  0.4.1  2
ip-xxx-xx-xx-35  xxx.xx.xx.35:8301  alive   server  0.4.1  2
ip-xxx-xx-xx-37  xxx.xx.xx.37:8301  alive   server  0.4.1  2
$ consul exec -node="ip-xxx-xx-xx-35" '/usr/local/bin/consul -v'
    ip-xxx-xx-xx-35: Consul v0.4.1
    ip-xxx-xx-xx-35: Consul Protocol: 2 (Understands back to: 1)
    ip-xxx-xx-xx-35:
==> ip-xxx-xx-xx-35: finished with exit code 0
1 / 1 node(s) completed / acknowledged

consul exec のオプションを見る限りでは…

Usage: consul exec [options] [-|command...]

  Evaluates a command on remote Consul nodes. The nodes responding can
  be filtered using regular expressions on node name, service, and tag
  definitions. If a command is '-', stdin will be read until EOF
  and used as a script input.

Options:

  -http-addr=127.0.0.1:8500  HTTP address of the Consul agent.
  -datacenter=""             Datacenter to dispatch in. Defaults to that of agent.
  -prefix="_rexec"           Prefix in the KV store to use for request data
  -node=""                                       Regular expression to filter on node names
  -service=""                Regular expression to filter on service instances
  -tag=""                    Regular expression to filter on service tags. Must be used
                             with -service.
  -wait=2s                   Period to wait with no responses before terminating execution.
  -wait-repl=200ms           Period to wait for replication before firing event. This is an
                             optimization to allow stale reads to be performed.
  -verbose                   Enables verbose output

各ノード以外にもデータセンター毎、サービス毎、タグ毎にコマンドを実行することが出来そう。

consul watch

ざっくりホワっと

クラスタ、イベント、サービス、ノード等の変化を検知したら定義されたアクションを実行してくれる。

以下のように設定を書くことで有効になる。

{
  "watches": [
    {
      "type": "nodes",
      "handler": "/opt/bin/test.sh"
    }
  ]
}

type には以下が指定可能。

-type - Watch type. Required, one of "key", "keyprefix", "services", "nodes", "services", "checks", or "event".

handler に実行したいスクリプト等を指定する。

トライ

クラスタからノードが外れた場合には…

EC2 の付け替えスクリプトを実行させた。

イベントをトリガーに試してみたいので以下のように設定を用意。

{
  "watches": [
    {
      "type": "event",
      "name": "foo",
      "handler": "/opt/bin/logging.sh"
    }
  ]
}

logging.sh は以下のような logger を使ってログを吐くだけのスクリプト。

#!/bin/sh

logger -t consul-watch "hello."

consul event を実行してみる。

$ consul event -name="foo"
Event ID: e78f544e-4998-b77b-f12e-9ee50586984f

上記のようにイベント ID が出力された。実際に /var/log/messages を確認。

$ tail /var/log/messages | grep hello
Feb 14 09:03:03 ip-xxx-xx-xx-36 consul-watch: hello.
Feb 14 09:04:08 ip-xxx-xx-xx-36 consul-watch: hello.
Feb 14 09:06:15 ip-xxx-xx-xx-36 consul-watch: hello.

ログが出力されているので consul event を検知してハンドラが実行されている。

ということで…

今日の知見

  • consul exec はクラスタ内のノードに対して一斉に処理を実行させることが出来る
  • 但し、root 権限が必要なコマンドは無理っぽい
  • 全てのノードだけではなくデータセンターやタグ等で絞り込むことが出来る
  • consul watch はクラスタ内の各種変化を検知して任意の処理を行わせることが出来る

まだまだ…

consul について理解が薄いので引き続き触っていく。

お疲れ様でした。

元記事はこちらです。
俺の consul チートシート(3)