Zabbix LLDにdocker関連のファイルを発見させない

環境: Debian wheezy (7.5), Docker 0.11.0 (-e lxc), Zabbix 2.2.3 (Docker周りが変則環境なことに注意)

LLD (Low Level Discovery) の vfs.fs.discovery ではファイルシステムとして認識される全てをディレクトリを返します。

通常は問題ないのですが、自分の環境ではDockerから```/var/lib/docker```配下の何かを多数マウントされることがあり、ちょいと困っていました。頻繁にdockerのイメージやコンテナをいじるとZabbix Serverは終始丁寧にこれを追いかけます。邪魔です。

具体的には、vfs.fs.discoveryの結果は以下のようなJSONで返されます

```json
{
	"data":[
		{
			"{#FSNAME}":"\/",
			"{#FSTYPE}":"rootfs"},
		{
			"{#FSNAME}":"\/sys",
			"{#FSTYPE}":"sysfs"},
		{
			"{#FSNAME}":"\/proc",
			"{#FSTYPE}":"proc"},
		{
			"{#FSNAME}":"\/dev",
			"{#FSTYPE}":"devtmpfs"},
		{
			"{#FSNAME}":"\/dev\/pts",
			"{#FSTYPE}":"devpts"},
		{
			"{#FSNAME}":"\/run",
			"{#FSTYPE}":"tmpfs"},
		{
			"{#FSNAME}":"\/",
			"{#FSTYPE}":"ext4"},
		{
			"{#FSNAME}":"\/run\/lock",
			"{#FSTYPE}":"tmpfs"},
		{
			"{#FSNAME}":"\/run\/shm",
			"{#FSTYPE}":"tmpfs"},
		{
			"{#FSNAME}":"\/boot",
			"{#FSTYPE}":"ext2"},
		{
			"{#FSNAME}":"\/var\/lib\/nfs\/rpc_pipefs",
			"{#FSTYPE}":"rpc_pipefs"},
		{
			"{#FSNAME}":"\/proc\/sys\/fs\/binfmt_misc",
			"{#FSTYPE}":"binfmt_misc"},
		{
			"{#FSNAME}":"\/sys\/fs\/fuse\/connections",
			"{#FSTYPE}":"fusectl"},
		{
			"{#FSNAME}":"\/var\/lib\/docker\/aufs\/mnt\/2f6...07ef395f2-init",
			"{#FSTYPE}":"aufs"},
		{
			"{#FSNAME}":"\/var\/lib\/docker\/aufs\/mnt\/2f6...07ef395f2",
			"{#FSTYPE}":"aufs"},
		{
			"{#FSNAME}":"\/var\/lib\/docker\/aufs\/mnt\/2f6...07ef395f2\/.dockerinit",
			"{#FSTYPE}":"ext4"},
		{
			"{#FSNAME}":"\/var\/lib\/docker\/aufs\/mnt\/2f6...07ef395f2\/.dockerenv",
			"{#FSTYPE}":"ext4"},
		{
			"{#FSNAME}":"\/var\/lib\/docker\/aufs\/mnt\/2f6...407ef395f2\/etc\/resolv.conf",
			"{#FSTYPE}":"ext4"},
		{
			"{#FSNAME}":"\/var\/lib\/docker\/aufs\/mnt\/2f6...07ef395f2\/etc\/hostname",
			"{#FSTYPE}":"ext4"},
		{
			"{#FSNAME}":"\/var\/lib\/docker\/aufs\/mnt\/2f6...07ef395f2\/etc\/hosts",
			"{#FSTYPE}":"ext4"},
		{
			"{#FSNAME}":"\/var\/lib\/docker",
			"{#FSTYPE}":"ext4"},
		{
			"{#FSNAME}":"\/sys\/fs\/cgroup",
			"{#FSTYPE}":"cgroup"}]}
```

この```/var/lib/docker```に関わるFSだけを消す、という設定を行おうとしましたが、2.2ではどうも難しい印象です。

私の環境(Debian wheezy + docker 0.11.0、そもそも変則構成です注意)を使っている場合、Zabbixは```/var/lib/docker```配下のものを aufs と ext4 の両方の形式で認識していました。

ext4 は別の監視して欲しいFS (具体的には```/```)でも使っているため、```#FSTYPE```フィルタ対象からは外せません。

代わりに```#FSNAME```にdockerという文字列があったら弾く、と設定すると、今度はtmpfs等の有象無象のFSをZabbixが監視し始めます。標準でMounted Filesytem Discoveryが利用するフィルタ (POSIX拡張正規表現)は以下の通り

```
^(btrfs|ext2|ext3|ext4|jfs|reiser|xfs|ffs|ufs|jfs|jfs2|vxfs|hfs|ntfs|fat32)$
```

これにマッチしないtmpfsやrpc_pipefsは監視されない、ということです。さすがにこのフィルタを外したくないです。

これは、フィルタを複数設定できないZabbix 2.2以前の制約と考えました。開発中とされる2.4では複数フィルタに対応するそうなのでこの問題は起こらないと思われますが、とりまここでは漸次的な対策を考えてみます。

具体的には、```UserParameter```をエージェント側に追加してみます。前提としてエージェントは127.0.0.1からもリクエストを受け付けるものとします。まず上記の加工前JSONを```zabbix_get```で得るためです。正直ちょっと頭悪い印象ですが、良い方法が思いつきませんでした。

```
UserParameter=amedama.fs.discovery.nodocker,zabbix_get -s localhost -k vfs.fs.discovery | jq '{data: [.data | .[] | select(.["{#FSNAME}"] | contains("docker") | not)]}'
```

ここは唐突にjqの演習です。(http://stedolan.github.io/jq/) jq 1.3 はDebian wheezy (7.5)には通常入っていないのでsidからソースを取ってきてビルドします。
単にバイナリを本家から取ってきても良いでしょう。

jqに渡している中身をもう一度見てみます

```
{data: [.data | .[] | select(.["{#FSNAME}"] | contains("docker") | not)]}
```

dataとその配下の[]を剥ぎ取り、"{#FSNAME}"に(```.["{#FSNAME}"]```) dockerが入って(```contains("docker")```) いなかった (```not```) 場合だけその要素を採用し (```select()```)、再び[]で囲ってリストとし、辞書的に```{data: }```で更に囲います。

結果は以下のようになります。

```json
{
  "data": [
    {
      "{#FSTYPE}": "rootfs",
      "{#FSNAME}": "/"
    },
    {
      "{#FSTYPE}": "sysfs",
      "{#FSNAME}": "/sys"
    },
    {
      "{#FSTYPE}": "proc",
      "{#FSNAME}": "/proc"
    },
    {
      "{#FSTYPE}": "devtmpfs",
      "{#FSNAME}": "/dev"
    },
    {
      "{#FSTYPE}": "devpts",
      "{#FSNAME}": "/dev/pts"
    },
    {
      "{#FSTYPE}": "tmpfs",
      "{#FSNAME}": "/run"
    },
    {
      "{#FSTYPE}": "ext4",
      "{#FSNAME}": "/"
    },
    {
      "{#FSTYPE}": "tmpfs",
      "{#FSNAME}": "/run/lock"
    },
    {
      "{#FSTYPE}": "tmpfs",
      "{#FSNAME}": "/run/shm"
    },
    {
      "{#FSTYPE}": "ext2",
      "{#FSNAME}": "/boot"
    },
    {
      "{#FSTYPE}": "rpc_pipefs",
      "{#FSNAME}": "/var/lib/nfs/rpc_pipefs"
    },
    {
      "{#FSTYPE}": "binfmt_misc",
      "{#FSNAME}": "/proc/sys/fs/binfmt_misc"
    },
    {
      "{#FSTYPE}": "fusectl",
      "{#FSNAME}": "/sys/fs/fuse/connections"
    },
    {
      "{#FSTYPE}": "cgroup",
      "{#FSNAME}": "/sys/fs/cgroup"
    }
  ]
}
```

これをZabbix Server側で利用する設定にします。

ただし既存のTemplate OS Linuxにこれを追加することは出来ませんでした。

Discoveryのキーの異なるDiscoveryアイテムを作成するのですが、DiscoveryにリンクしているItem prototypes等はもともとのDiscovery (vfs.fs.discovery) と全く同じです。よって、Items, Triggers, Graphs等のプロトタイプのキー自体が一致して衝突します。

さすがに全ての監視環境でこんな```UserParameter```ハックを追加するわけにはいきませんので、このコンフリクトはちょっと面倒でした。サーバサイドだけで管理出来ないことをやると色々面倒です。

試験運用するLinux環境用にテンプレートレベルでfull cloneしました。2.4でテンプレート周りの挙動に改善が入るとこーだい氏が言ってた気がしますが、今回の問題と関係するかまではわかりません。

2.4 のリリース予定機能は一部、こちらから確認出来ます。
https://www.zabbix.com/documentation/2.4/manual/introduction/whatsnew240