はじめに
td-agent
の監視と万が一の時の自動起動にmonit
を使いたいと思って調べた
monit とは?
個人的な解釈としては monit
とは以下のような機能がある。
- 指定されたプロセスの監視
- 指定されたプロセスが停止した場合には自動的にプロセスを再起動する
公式サイトはこちら。
monit -h
とりあえず monit -h
でどんなオプションがあるかを確認。
Usage: monit [options] {arguments} Options are as follows: -c file Use this control file -d n Run as a daemon once per n seconds -g name Set group name for start, stop, restart, monitor and unmonitor -l logfile Print log information to this file -p pidfile Use this lock file in daemon mode -s statefile Set the file monit should write state information to -I Do not run in background (needed for run from init) -t Run syntax check for the control file -v Verbose mode, work noisy (diagnostic output) -vv Very verbose mode, same as -v plus log stacktrace on error -H [filename] Print SHA1 and MD5 hashes of the file or of stdin if the filename is omited; monit will exit afterwards -V Print version number and patchlevel -h Print this text Optional action arguments for non-daemon mode are as follows: start all - Start all services start name - Only start the named service stop all - Stop all services stop name - Only stop the named service restart all - Stop and start all services restart name - Only restart the named service monitor all - Enable monitoring of all services monitor name - Only enable monitoring of the named service unmonitor all - Disable monitoring of all services unmonitor name - Only disable monitoring of the named service reload - Reinitialize monit status - Print full status information for each service summary - Print short status information for each service quit - Kill monit daemon process validate - Check all services and start if not running procmatch <pattern> - Test process matching pattern (Action arguments operate on services defined in the control file)
-t
オプションでテストも出来るというのは怠惰な自分には有り難い。
試す
以下の環境で試した。
簡単な設定
インストール直後は下記のように /etc/minit/
以下にファイルが作成される。尚、インストールは apt-get install monit
で楽ちん。
# tree . |-- conf.d | `-- cron |-- monitrc |-- monitrc.d | |-- cron | `-- openssh-server `-- templates |-- rootbin |-- rootrc `-- rootstrict 3 directories, 7 files
cron
のプロセスを監視するので monitrc.d
以下にある cron
ファイルを conf.d
以下にコピーして利用した。(※monitrc.d
以下に置いておくだけではプロセスは監視してくれなかった...)
sudo cp monitrc.d/cron conf.d/
コピーしたら monit
のプロセスを再起動する。
/etc/init.d/monit restart
これで monit
から crond
の監視が開始されることになる。ちなみに、 /etc/monit/conf.d
にコピーした cron
ファイルは下記の通り。
check process crond with pidfile /var/run/crond.pid group system group crond start program = "/etc/init.d/cron start" stop program = "/etc/init.d/cron stop" if 5 restarts with 5 cycles then timeout depend cron_bin depend cron_rc depend cron_spool check file cron_bin with path /usr/sbin/cron group crond include /etc/monit/templates/rootbin check file cron_rc with path "/etc/init.d/cron" group crond include /etc/monit/templates/rootbin check directory cron_spool with path /var/spool/cron/crontabs group crond if failed permission 1730 then unmonitor if failed uid root then unmonitor if failed gid crontab then unmonitor
cron のプロセスを止めてみる
早速、意図的に cron
のプロセスを止めてみる。
/etc/init.d/cron stop
しばらく(今回の環境で計測したら約 120 秒)すると /var/log/monit.log
に以下のようなログが出力されて crond
が再起動される。
[JST Dec 6 11:03:20] error : 'crond' process is not running [JST Dec 6 11:03:20] info : 'crond' trying to restart [JST Dec 6 11:03:20] info : 'crond' start: /etc/init.d/cron [JST Dec 6 11:05:20] info : 'crond' process is running with pid 3192
cron
のプロセスが起動しているかを確認する。
# ps aux | grep cron root 3192 0.0 0.0 18880 860 ? Ss 11:03 0:00 /usr/sbin/cron
おお。
も少し突っ込んで挙動を見てみる
デバッグモードで起動
-vv
を付けて monit
を起動するとデバッグモードで起動するので、それを利用して monit
がどんなお仕事をしているのかを見てみる。
--- monit.original 2013-12-06 11:10:36.995894157 +0900 +++ monit 2013-12-06 11:08:40.035898212 +0900 @@ -25,7 +25,7 @@ DELAY="/etc/monit/monit_delay" NAME=monit DESC="daemon monitor" -MONIT_OPTS= +MONIT_OPTS="-vv" PID="/var/run/$NAME.pid" # Check if DAEMON binary exist
/etc/init.d/monit
を上記のように修正して monit
を再起動する。
もう一回 cron を止めてみる
先ほどと同様に cron
のプロセスを停止してからしばらくすると以下のようなログが出力された。
[JST Dec 6 11:10:43] debug : 'cron_bin' file exists check succeeded [JST Dec 6 11:10:43] debug : 'cron_bin' is a regular file [JST Dec 6 11:10:43] debug : 'cron_bin' has valid checksums [JST Dec 6 11:10:43] debug : 'cron_bin' permission check succeeded [current permission=0755] [JST Dec 6 11:10:43] debug : 'cron_bin' uid check succeeded [current uid=0] [JST Dec 6 11:10:43] debug : 'cron_bin' gid check succeeded [current gid=0] [JST Dec 6 11:10:43] debug : 'cron_rc' file exists check succeeded [JST Dec 6 11:10:43] debug : 'cron_rc' is a regular file [JST Dec 6 11:10:43] debug : 'cron_rc' has valid checksums [JST Dec 6 11:10:43] debug : 'cron_rc' permission check succeeded [current permission=0755] [JST Dec 6 11:10:43] debug : 'cron_rc' uid check succeeded [current uid=0] [JST Dec 6 11:10:43] debug : 'cron_rc' gid check succeeded [current gid=0] [JST Dec 6 11:10:43] debug : 'cron_spool' directory exists check succeeded [JST Dec 6 11:10:43] debug : 'cron_spool' is directory [JST Dec 6 11:10:43] debug : 'cron_spool' permission check succeeded [current permission=1730] [JST Dec 6 11:10:43] debug : 'cron_spool' uid check succeeded [current uid=0] [JST Dec 6 11:10:43] debug : 'cron_spool' gid check succeeded [current gid=102] [JST Dec 6 11:10:43] debug : monit: pidfile '/var/run/crond.pid' does not exist [JST Dec 6 11:10:43] error : 'crond' process is not running [JST Dec 6 11:10:43] debug : ------------------------------------------------------------------------------- [JST Dec 6 11:10:43] debug : /usr/bin/monit() [0x41c07a] [JST Dec 6 11:10:43] debug : /usr/bin/monit(LogError+0xa0) [0x41c7d0] [JST Dec 6 11:10:43] debug : /usr/bin/monit(Event_post+0x20a) [0x418ada] [JST Dec 6 11:10:43] debug : /usr/bin/monit(check_process+0xa2) [0x42b312] [JST Dec 6 11:10:43] debug : /usr/bin/monit(validate+0x2fe) [0x42b23e] [JST Dec 6 11:10:43] debug : /usr/bin/monit(main+0x99f) [0x40d32f] [JST Dec 6 11:10:43] debug : /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) [0x7f024d240ead] [JST Dec 6 11:10:43] debug : /usr/bin/monit() [0x40d6b5] [JST Dec 6 11:10:43] debug : ------------------------------------------------------------------------------- [JST Dec 6 11:10:43] info : 'crond' trying to restart [JST Dec 6 11:10:43] debug : monit: pidfile '/var/run/crond.pid' does not exist [JST Dec 6 11:10:43] debug : monit: pidfile '/var/run/crond.pid' does not exist [JST Dec 6 11:10:43] info : 'crond' start: /etc/init.d/cron [JST Dec 6 11:10:43] debug : monit: pidfile '/var/run/crond.pid' does not exist
どうやら下記のようなことが /etc/monit/conf.d/cron
に記述された内容に基づいて行われているっぽい。
- プロセスの実行ファイルの所在のチェックとパーミッションチェック
- rc スクリプトの所在のチェックとパーミッションチェック
- cron のスプールディレクトリの所在のチェックとパーミッションチェック
- PID ファイルの所在確認
改めて /etc/monit/conf.d/cron
とログを照らしあわせて確認すると...
プロセスの実行ファイルの所在のチェックとパーミッションチェック
check file cron_bin with path /usr/sbin/cron group crond include /etc/monit/templates/rootbin
rc スクリプトの所在のチェックとパーミッションチェック
check file cron_rc with path "/etc/init.d/cron" group crond include /etc/monit/templates/rootbin
cron のスプールディレクトリの所在のチェックとパーミッションチェック
check directory cron_spool with path /var/spool/cron/crontabs group crond if failed permission 1730 then unmonitor if failed uid root then unmonitor if failed gid crontab then unmonitor
という感じであらかじめ各プロセスの監視ファイル(例:/etc/monit/conf.d/cron
)に プロセスが正しく稼働している状態を任意で記述 することで、それを基に monit
はチェックを行いプロセスの死活を監視していると思われる。
最後に
- なにげなく
monit
を使えばイイヂャんって思っていたけどちゃんと調べて良かった - 正しく動作している状態を記述してテストするという意味では監視ツールという側面と
serverspec
のようなツールの側面も持ちあわせていると思った - 異常を検知してプロセスを再起動するまでの時間はどこで定義されていて調整が可能なのかな?
- まだまだ続く(
td-agent
で利用しなければいけないので) - そもそもだけど、
td-agent
って運用開始してから落ちてしまうってことが無いくらいに安定しているからなー