Zabbix Agentd を systemd 配下で稼働させる (el7/centos7 対応)

# Zabbix Agentd の el7/centos7 対応

Zabbix の公式パッケージは、現在まだ el7/centos7 対応されていないので
例えば `zabbix-agentd` を centos7 で動かして centos7 のサーバーを `zabbix server` から監視したい場合、

* src から入れる
* [fedora の srpm](http://download.fedoraproject.org/pub/fedora/linux/development/rawhide/source/SRPMS/zabbix-2.2.5-1.fc22.src.rpm) を持ってきて el7/centos7 で rpm を作成する
* 公式の el6 の srpm を持ってきて el7/centos7 の rpm を作成する

等あるのですが、これらの方法ですと systemd 配下でうまく動かすことができません
`zabbix-agentd` は起動するんですが、systemctl から停止ができなかったりします

## fedora の zabbix の rpm を作り直して動かしてみた場合

```shell-session
[root@server]# systemctl status zabbix-agent
zabbix-agent.service - Zabbix Monitor Agent
   Loaded: loaded (/etc/systemd/system/zabbix-agent.service; enabled)
   Active: active (exited) since Wed 2014-08-06 01:48:39 JST; 13s ago
  Process: 20689 ExecStart=/usr/sbin/zabbix_agentd (code=exited, status=0/SUCCESS)
 Main PID: 20689 (code=exited, status=0/SUCCESS)

Aug 06 01:48:39 r0026u23s00 systemd[1]: Started Zabbix Monitor Agent.
```

一見うまく行ってるように見えますが

```shell-session
[root@server]# systemctl stop zabbix-agent

[root@server]# ps -ef |grep zabbix
zabbix   20691     1  0 01:48 ?        00:00:00 /usr/sbin/zabbix_agentd
zabbix   20692 20691  0 01:48 ?        00:00:00 /usr/sbin/zabbix_agentd: collector [idle 1 sec]
zabbix   20693 20691  0 01:48 ?        00:00:00 /usr/sbin/zabbix_agentd: listener #1 [waiting for connection]
zabbix   20694 20691  0 01:48 ?        00:00:00 /usr/sbin/zabbix_agentd: listener #2 [waiting for connection]
zabbix   20695 20691  0 01:48 ?        00:00:00 /usr/sbin/zabbix_agentd: listener #3 [waiting for connection]
zabbix   20696 20691  0 01:48 ?        00:00:00 /usr/sbin/zabbix_agentd: active checks #1 [idle 1 sec]

※まだ zabbix-agentd いる

[root@server]# systemctl status zabbix-agent
zabbix-agent.service - Zabbix Monitor Agent
   Loaded: loaded (/etc/systemd/system/zabbix-agent.service; enabled)
   Active: inactive (dead) since Wed 2014-08-06 01:49:13 JST; 5s ago
  Process: 20689 ExecStart=/usr/sbin/zabbix_agentd (code=exited, status=0/SUCCESS)
 Main PID: 20689 (code=exited, status=0/SUCCESS)

Aug 06 01:48:39 r0026u23s00 systemd[1]: Started Zabbix Monitor Agent.
Aug 06 01:49:13 r0026u23s00 systemd[1]: Stopping Zabbix Monitor Agent...
Aug 06 01:49:13 r0026u23s00 systemd[1]: Stopped Zabbix Monitor Agent.
```

**zabbix-agentd 落ちてくれない (ﾉ∀`)**
kill してあげれば普通に落ちます


# systemd 配下で動かすということは

systemd についてはいろいろ調べれば出てきますが、基本は配下で動かす daemon(今回は `zabbix-agentd`) は foreground で動かす必要があります
現時点の zabbix (2.2.5) では `zabbix-agentd` をはじめ、各種 zabbix daemon は foreground 起動に対応していません
(zabbix-java-gateway 以外)

# systemd の定義で Type=forking にすればいいのでは？

実は systemd では foreground で動かないような daemon も `Type=forking` の設定を入れておくことで対応できます
だがしかし、`Type=forking` としても `zabbix-agentd` は systemd 配下にうまく入ることができません
fedora にある srpm を見ても systemd の設定ファイルである `zabbix-agent.service` は `Type=oneshot` になってるんですよね

## なぜなのか

`zabbix-agentd` は一旦 root で起動した後に、zabbix user(default) で process を fork します
この時 root で起動した親 process は exit してしまうので systemd は追跡できなくなるんです

# そんなあなたに ZBXNEXT-611

実は foreground 対応は zabbix 本家の request にあがっていたりします ([ZBXNEXT-611](https://support.zabbix.com/browse/ZBXNEXT-611))
しかも foreground 化の patch まであります
ZBXNEXT-611 では 2.2.3 用の patch になってますが、せっかくなので 2.2.5 の patch を作りました

https://github.com/makocchi-git/zabbix-2.2.5-foreground/blob/master/zabbix-foreground.patch

この patch を適用して作った zabbix daemon 達は **-f オプションが使えるようになります** (foreground mode)

```shell-session
[root@server]# zabbix_agentd -h
Zabbix Agent (daemon) v2.2.5fg (revision 47411) (17 July 2014)

usage: zabbix_agentd [-Vfhp] [-c <config-file>] [-t <item key>]

Options:

  -c --config <config-file>  Absolute path to the configuration file
  -f --foreground            Run in foreground don't fork
  -p --print                 Print known items and exit
  -t --test <item key>       Test specified item and exit
  -h --help                  Give this help
  -V --version               Display version number
```

version も fg を追加しました

# せっかくなので el7/centos7 対応の rpm を作る

公式の [zabbix repository](http://repo.zabbix.com/zabbix/2.2/rhel/6/) にある srpm を元に、上記の patch を入れて el7/centos7 化させた spec も置いておきました

https://github.com/makocchi-git/zabbix-2.2.5-foreground/blob/master/zabbix.el7.spec

(`.service` ファイルも置きましたが zabbix-agentd 以外は未検証)

## 作り方

[公式の 2.2.5 srpm](http://repo.zabbix.com/zabbix/2.2/rhel/6/SRPMS/zabbix-2.2.5-1.el6.src.rpm)を rpmbuild 環境に展開後、

* 上記 git repository 内の `*.service` を `SOURCES/` 配下に置く
* 同様に `zabbix.el7.spec` を `SPEC/` に置く
* `rpmbuild -bs zabbix.el7.spec` で srpm を作る
* mock なりなんなりで build する

で作れると思います

## zabbix-agent.service

systemd の定義 file である `zabbix-agent.service` は下記の様にしました

```ini:zabbix-agent.service
[Unit]
Description=Zabbix Monitor Agent
After=network.target

[Service]
Type=simple
Environment="CONFIG=/etc/zabbix/zabbix_agentd.conf"
EnvironmentFile=-/etc/sysconfig/zabbix-agent
ExecStart=/usr/sbin/zabbix_agentd -c ${CONFIG} -f
ExecStop=/bin/kill ${MAINPID}
KillMode=process
User=root

[Install]
WantedBy=multi-user.target
```

正直 systemd についてはまだ模索中なので、これが正解とは限らないです
とりあえず自分の環境では上記でうまく行ってます

```shell-session
[root@server]# systemctl start zabbix-agent
[root@server]# systemctl status zabbix-agent
zabbix-agent.service - Zabbix Monitor Agent
   Loaded: loaded (/usr/lib/systemd/system/zabbix-agent.service; enabled)
   Active: active (running) since Mon 2014-08-04 11:32:11 JST; 1 day 13h ago
  Process: 4555 ExecStop=/bin/kill ${MAINPID} (code=exited, status=0/SUCCESS)
 Main PID: 4562 (zabbix_agentd)
   CGroup: /system.slice/zabbix-agent.service
           |-4562 /usr/sbin/zabbix_agentd -c /etc/zabbix/zabbix_agentd.conf -f
           |-4563 /usr/sbin/zabbix_agentd: collector [idle 1 sec]
           |-4564 /usr/sbin/zabbix_agentd: listener #1 [waiting for connection]
           |-4565 /usr/sbin/zabbix_agentd: listener #2 [waiting for connection]
           |-4566 /usr/sbin/zabbix_agentd: listener #3 [waiting for connection]
           `-4567 /usr/sbin/zabbix_agentd: active checks #1 [idle 1 sec]

Aug 04 11:32:11 serv systemd[1]: Starting Zabbix Monitor Agent...
Aug 04 11:32:11 serv systemd[1]: Started Zabbix Monitor Agent.
Aug 04 11:32:11 serv zabbix_agentd[4562]: zabbix_agentd [4562]: Running in foreground...

[root@server]# systemctl stop zabbix-agent
[root@server]# ps -ef | grep zabbix
[root@server]#

※落ちた！(ﾟ∀ﾟ)
```

ちなみに `zabbix-agent.service` に `Restart=always` を入れておけば `zabbix-agent` を kill しても自動で起動させてくれます

# 最後に

当然ですが **patch に関しては個人で作ったものですので、適用する際には自己責任でお願いします**
早く本家が ZBXNEXT-611 対応してくれればいいんですけどね
`zabbix-agentd` 以外の daemon (zabbix-server とか) はまだ起動すらさせてません　動かないかも(・ω<)
これから徐々に検証していきます