Consul service のヘルスチェックを zabbix での監視項目と共用する

Consul での service 定義にはヘルスチェックを設定できます。Service Definition - Consul

以下のようにサービス定義に死活監視用のコマンドを登録しておくことで、一定時間ごとにコマンドを起動します。コマンドの終了ステータスが 0 : 正常、1 : warning、それ以外で critical という扱いです。このあたりは nagios, sensu 等のプラグインと互換性があるようですね。
(他に、外部から一定時間ごとに状態を API で登録する TTL 型の死活監視もあります)

{
  "Name": "nginx"
  "Check": {
    "Interval": "10s",
    "Script": "/path/to/healthcheck.sh"
  },
}

ところで、既に何らかのモニタリングツールで監視をしている場合、Node 上で動く daemon 類についてはあらかじめ監視が仕込まれていることが多いはずです。

使用しているのが nagios、sensu であればチェックスクリプトを共用できるので楽ですが、Zabbix で監視をしている場合はどのようにするのがよいか。

zabbix_get というコマンド(もしくは拙作の互換品 go-zabbix-get) を使うことで、Node 上で動いている zabbix-agent から各種情報を取ることができるため、これを Consul の死活監視にも流用できるように考えてみました。

まず、以下のような bash で書かれた wrapper script を、zabbix_get_eval という名前で用意しておきます。

#!/bin/bash
VALUES=()
# 最後の引数を除いた引数をループして zabbix_get した値を配列に入れる
for KEY in "${@:1:($#-1)}"; do
    V=`zabbix_get -k "${KEY}"`
    VALUES=("${VALUES[@]}" "${V}")
done
# 最後の引数は評価式
EXPR="${!#}"
# 評価式に値を渡して評価
bash -c "${EXPR}" -- "${VALUES[@]}"

このコマンドは引数に zabbix-agent から取得する key 名、最後の引数にそれを評価する bash script を取ります。

また、zabbix-agent の設定で、localhostからの情報取得を許可します。

Server=127.0.0.1,zabbix.example.com


以下のような状態を正常と見なす死活監視を定義してみると、

  • 動作しているnginxという名前のプロセス数が 1以上
  • かつ
  • TCP 80 を Listen している

zabbix-agent の proc.num と net.tcp.listen を以下のように使用することで、正常時には exit 0、異常時には exit 2 で終了するコマンドになります。

$ zabbix_get_eval 'proc.num[nginx]' 'net.tcp.listen[80]' '[[ $1 -ge 1 && $2 -eq 1 ]] || exit 2'

Consul に登録するサービス定義にはこれをそのまま渡せば OK です。

{
  "Name": "nginx"
  "Check": {
    "Interval": "10s",
    "Script": "zabbix_get_eval 'proc.num[nginx]' 'net.tcp.listen[80]' '[[ $1 -ge 1 && $2 -eq 1 ]] || exit 2'"
  },
}

zabbix-agent から取得できる項目は結構いろいろあり、(【参考】1 Zabbix エージェント [Zabbix Documentation 2.0]) CPUやプロセス、ネットワークの情報以外にも、面白いところでは

  • web.page.get (HTTPでURLにアクセスして内容を取得)
  • net.dns.record (DNSで名前解決した結果を取得)

などもあります。

bash での値評価は数値、文字列の一致や大小比較の他にも正規表現(=~)も使えるので、複数項目の値を使って柔軟に評価できるかと思います。