ようへいの日々精進XP

よかろうもん

monit について調べたのでメモ

はじめに

  • 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 に記述された内容に基づいて行われているっぽい。

改めて /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 って運用開始してから落ちてしまうってことが無いくらいに安定しているからなー