Amazon Linuxで構築したサーバでプロセス監視したいなぁと思って調べたところ、monitが簡単そうだったので導入してみた。
初期セットアップ
インストール
yumでサクッとインストールできる。
$ yum install -y monit
2015年11月現在では、下記のバージョンでインストールされた。
$ monit -V
This is Monit version 5.2.5
デフォルト設定:/etc/monit.conf
では初期設定を確認してみよう。
コメントがいっぱい書いてあるが、それを無視すると、初期設定で書かれてるのは二行だけ。
$ cat /etc/monit.conf | grep -v -e '^\s*#' -e '^\s*$'
set daemon 60
include /etc/monit.d/*
簡単に解説。
set daemon 60
これは監視間隔。デフォルトでは60秒に設定されてるようだ。
monitは秒単位で監視間隔が設定でき、もっと短い間隔でも監視できるが、短くし過ぎると負荷が上がりそうなので、普通のアプリケーションはこのぐらいの間隔でいい気がする。
include /etc/monit.d/*
設定ファイルのinclude設定。デフォルトでは /etc/monit.d/ ディレクトリ配下にmonitの設定ファイルを置くと、勝手に読んでくれる。
デフォルト設定:/etc/monit.d/
では次に、 /etc/monit.d/ を覗いてみる。
$ ls /etc/monit.d/
logging
すると、最初からロギング設定のファイルが置いてある。
$ cat /etc/monit.d/logging | grep -v -e '^\s*#' -e '^\s*$'
set logfile /var/log/monit
ログが /var/log/monit に出力されるという設定だけが記述されている。
ログはsyslogに吐いたりもできるらしいが、ここではとりあえずそのままにしておく。
監視設定
デフォルト設定が確認できたので、早速プロセス監視を試してみる。
ここでは、sshdを例に設定ファイルを作成する。
設定ファイル作成
/etc/monit.d/ 配下に適当なファイル名で設定ファイルを作成する。
$ vi /etc/monit.d/sshd.conf
check process sshd with pidfile /var/run/sshd.pid
start program = "/etc/rc.d/init.d/sshd start"
stop program = "/etc/rc.d/init.d/sshd stop"
if 5 restarts within 5 cycles then unmonitor
ほとんど見たまんまだが、軽く解説。
check process sshd with pidfile /var/run/sshd.pid
監視対象のプロセスのpidファイルを指定。
なお、Webで検索すると、ほとんどpidファイルを指定した監視設定ばかり出てくるが、pidがないアプリケーションも監視できる。
start program = "/etc/rc.d/init.d/sshd start"
stop program = "/etc/rc.d/init.d/sshd stop"
プロセスの起動/終了方法を指定。
if 5 restarts within 5 cycles then unmonitor
5回再起動を試みて、ダメだったら監視対象から外す。
どう頑張っても起動しないのに、無限に再起動を試みないようにしている。
monit起動
それでは、monitを動かしてみよう。
$ service monit start
動作確認
とりあえず、sshdを止めてみる。
$ service sshd stop
$ service sshd status
openssh-daemon is stopped
この状態で、monitのログをtailしてみる。
監視間隔がデフォルトのままなら、一分以内に、下記のようなのログが流れてくる。
$ tail -f /var/log/monit
・・・・・・
[JST Nov 1 13:12:38] error : 'sshd' process is not running
[JST Nov 1 13:12:38] info : 'sshd' trying to restart
[JST Nov 1 13:12:38] info : 'sshd' start: /etc/rc.d/init.d/sshd
ログを確認した後に、sshdのステータスを見てみる。
$ service sshd status
openssh-daemon (pid 2562) is running...
ちゃんとプロセスが再起動した。ヤッタネ!
monit自体が死なないようにする
プロセス監視をするmonitさんがお亡くなりになると、非常にツライことになるので、upstartを使って死なないようにする。
起動してるサービスを停止
先ほど手動で起動したサービスは一旦止めておく。
$ service monit stop
設定ファイル作成
ココを参考に設定ファイルを作成。
$ vi /etc/init/monit.conf
description "Monit service manager"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec /usr/bin/monit -Ic /etc/monit.conf
pre-stop exec /usr/bin/monit -Ic /etc/monit.conf quit
設定反映&起動
作成した設定を読みこませる。
$ initctl reload-configuration
設定が読み込まれてることを確認。
$ initctl list | grep monit
monit stop/waiting
次にmonitを起動する。
$ initctl start monit
monit start/running, process 7145
では、早速monitを殺してみる。
$ kill 7145
で、プロセスを確認。
$ initctl list | grep monit
monit start/running, process 7148
ちゃんと蘇った!
定期的に監視を復活させる
監視設定で、下記のような記述を書くと、監視が外れる場合がある。
if 5 restarts within 5 cycles then unmonitor
無限に再起動を試みられるのも問題だが、ずっと監視が外れるのも具合が悪い。
というわけで、定期的にmonitによる監視を復活させる。
事前準備
定期的に監視を復活させるのに使う、monitor allはhttp経由で実行される。
というわけで、http経由で叩けるように /etc/monit.conf 設定を追加する。
$ echo "set httpd port 2812 and use address localhost allow localhost" >> /etc/monit.conf
ちなみに、外から叩ける必要がないので、ココでは、localhostからのアクセスのみ許可している。
cronを仕掛ける
とりあえず、一時間に一回ぐらいの頻度で実行することにした。
$ echo "0 */1 * * * /usr/bin/monit monitor all" >> /var/spool/cron/root
参考
- monit使う場合は定期的にmonit monitor allしたほうが良い
- http://hogem.hatenablog.com/entry/20090723/1248358467
CloudWatch Logsにログを投げつける
AWSを使っている場合、CloudWatch Logsにログを集約しておくと便利なので、monitのログも放り込んでおこう。
なお、CloudWatch Logs自体のインストールが完了していない場合は、先にそちらを済ませておいてほしい。
monitのログを収集するよう追記
/var/log/monit をCloudWatch Logsに食わせる設定を追記。
$ vi /etc/awslogs/awslogs.conf
[/var/log/monit]
file = /var/log/monit
log_stream_name = {hostname}
log_group_name = /var/log/monit
再起動
再起動しておく。
$ service awslogs restart
で、しばらくすると、CloudWatch Logsにmonitのログが流れてくるようになる。
必要があればアラーム設定とか入れとくといい感じだろう。
ちなみに、monit単体でもメール投げたりできるけど、AWSの場合は、CloudWatch Logsを活用したほうが柔軟性が高くなると思う。
まとめ
というわけで、monit歴1日のオレの作業メモを元に、手順を整理してみた。
まだちゃんと運用してないので、ツッコミどころも多いだろうけど、スタートとしては悪くないと思うので、monit初心者な人はぜひ参考にしてほしい。
ちなみに、はじめてQiitaに投稿してみたけど、外部に公開する文章を書くのは非常にエネルギーが必要だという事がわかった。
いつも情報公開をして助けてくれてる皆様、本当にありがとう。