Zabbixのicmppingアイテム動作不具合

ZabbixをDRBD+heartbeatを使用したHAクラスタ構成で導入した環境で、icmpping(StandAloneテンプレートに付属)アイテムによる状態取得が正常に行えない事象に遭遇した。Zabbixのバージョンは1.6.x系と1.8.2、64bit/32bit版など環境を変えて検証を行ってみたがバージョンによる違いはなく、結論としてはZabbixサーバの設定ファイルで指定した「SourceIP」パラメータが直接的な原因であることがわかった。今日は備忘録を兼ねて、コトの顛末をまとめておく。

問題の挙動を確認したシステム環境

  • OS:CentOS 5.4、FedraCore 12 (32bit/64bit)
  • DB:MySQL 5.0、5.1
  • Zabbix:1.6.2、1.6.4、1.8.2 (32bit/64bit)

※インストール方法はRPM/ソースコンパイルに依存しない

事象と検知した際の経緯

Zabbixエージェントを導入できない機器の監視を、手っ取り早くStandAloneテンプレートを使用し監視していたが、ICMPチェック(PING)不通になった場合にアラートを通知するようなトリガーはデフォルトでは定義されていない。そのため、手動でicmppingアイテムのチェック結果が0(Down)となった場合にアラート通知を行うよう設定を追加した。トリガー定義追加後、動作確認してみると正常に動作していない。取得した最新データを確認してもやはり正常に動作しておらず、監視対象機器が起動していようが停止していようが常にDown(0)のステータスとなってしまう。要はトリガーの定義ミスではなく、icmppingで値を取得する時点で期待通りの動作になっていないと言える。

原因調査と判明したこと

icmppingアイテムのチェックは、実際にはZabbixサーバがZabbixとは別に導入されたfpingを実行し、監視対象に対してICMP死活チェックを行う(PING応答速度を測るicmpperfも同様)。ZabbixサーバのログDEBUGレベルを3⇒4に変更したり、fpingバイナリ自体を調査用に作成したシェルなどに置き換えてみたところ、fpingを使ったチェック実行時に導入したfpingが対応していない「-S<サーバソースIP>」というパラメータがセットされていることが判明。

Zabbixのソースを確認したところ、CONFIG_SOURCE_IP(=SourceIPパラメータと思われる)が明示的にセットされている場合は、fpingコマンド実行時に「-S」を付加して実行していたことがわかった。該当のソースは 「src/libs/zbxicmpping/icmpping.c」にある「process_ping()」にあたる。Zabbix 1.6.4のソース66〜95行目を抜粋したものが以下。


static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int max_error_len)
{
FILE *f;
char filename[MAX_STRING_LEN], tmp[MAX_STRING_LEN],
*c, source_ip[64];
int i;
ZBX_FPING_HOST *host;
#ifdef HAVE_IPV6
char *fping;
int family = 0;
#endif

assert(hosts);

zabbix_log(LOG_LEVEL_DEBUG, "In process_ping()");

if (NULL != CONFIG_SOURCE_IP)
zbx_snprintf(source_ip, sizeof(source_ip), "-S%s ", CONFIG_SOURCE_IP);
else
*source_ip = '\0';

if (access(CONFIG_FPING_LOCATION, F_OK|X_OK) == -1)
{
zbx_snprintf(error, max_error_len, "%s: [%d] %s", CONFIG_FPING_LOCATION, errno, strerror(errno));
return NOTSUPPORTED;
}

zbx_snprintf(filename, sizeof(filename), "%s/zabbix_server_%li.pinger",
CONFIG_TMPDIR,
zbx_get_thread_id());

当初はZabbixのバグかとも思ったのだが、ソースを軽く見た感じではこの挙動は仕様と言えそうだ。実は調査の中で、問題が出ていない環境もあり違いは何だろうと思案していた。RPM/ソースコンパイルと言ったインストール方法も含めて疑ったものの、結論としては「HAクラスタ構成としていた環境でのみ、Zabbixサーバの設定ファイル内でSourceIPパラメータを明示的に設定していたこと」が決定的な違いだったと言える。
fping実行時のコマンドラインオプションの組立て方がZabbixの仕様通りという前提であれば、この問題を解決するためには何が問題なのかというとそれは「fpingが-Sオプションを認識できないこと」となる。

問題の解決に向けて

Zabbixサーバをシングル構成で構築するのであれば、そもそも問題の原因となっているSourceIPパラメータの値をクリアすればよい。逆説的に言うと、シングル構成のサーバを扱う上でこの問題には遭遇しなかったはず。ただ今回のようにHAクラスタ構成を取る場合には、クラスタを構成するリアルサーバが切り替わっても監視対象側ではそれを意識することなく監視機能が動作してくれることを期待しているため、SourceIPパラメータを外すという対応はあまり行いたくない。前述の事情から、今回の対策はやはりfpingをなんとか-Sオプションに対応させる、がよいように思われる。

色々と調べてみた結果、debian関連のソースパッケージで、fpingの-S対応パッチを作っている方がいたので、今回はこれを利用させて頂く。
http://packages.debian.org/source/lenny/fping
にあるfpingのソースとパッチを使用しfpingをビルド、RPMで導入した既存のfping


# rpm -e `rpm -qa | grep fping`
# ls -l
-rw-r--r-- 1 root root 6656 3月 4 2008 fping_2.4b2-to-ipv6-15.diff.gz
-rw-r--r-- 1 root root 624 3月 4 2008 fping_2.4b2-to-ipv6-15.dsc
-rw-r--r-- 1 root root 63333 2月 1 2002 fping_2.4b2-to-ipv6.orig.tar.gz
# tar xvzf fping_2.4b2-to-ipv6.orig.tar.gz
# gunzip fping_2.4b2-to-ipv6-15.diff.gz
# cd fping-2.4b2_to-ipv6/
# patch -p1 < ../fping_2.4b2-to-ipv6-15.diff
# ./configure
# make && make install
# find / -name fping -type f | head -1
/usr/local/sbin/fping

ソースコンパイルしたfpingが-Sオプションをサポートすることを確認
# /usr/local/sbin/fping -S192.168.1.200 192.168.1.1
192.168.1.1 is alive

fpingが-Sオプションを無事サポートするようになったところで、あとはZabbixサーバが実行できるようZabbixサーバの設定とfpingバイナリ自体の権限を適切な設定に変更、Zabbixを再起動し対応終了。icmppingアイテムが正常に値を取得し、追加したトリガーが機能することを確認。


# ll /usr/local/sbin/fping
-rwxr-xr-x 1 root root 58915 4月 14 17:22 /usr/local/sbin/fping
# chown root.zabbix /usr/local/sbin/fping
# chmod 775 /usr/local/sbin/fping
# chmod ug+s /usr/local/sbin/fping
# ll /usr/local/sbin/fping
-rwsrwsr-x 1 root zabbix 58915 4月 14 17:22 /usr/local/sbin/fping