Nagiosのイベントハンドラで障害の自動回復?

こんにちは、インフラ担当のszkです。


サーバやNW機器の監視ツールとして多くの方がNagiosを利用されていると思いますが、
Nagiosのどんな機能を使ってますか?

  • 監視機能
  • 通知機能
  • 回復措置機能

「回復措置機能」?。。。正確には回復措置機能は無いのですが、障害発生時に
自動的に回復措置を促すことができる「イベントハンドラ」という機能があります。


「機能は知っているけど、使ってないなー」


障害は発生時に、人間の目で確認して回復措置を行わないと監視の誤検知などがあって
不安というのが実際本音ではあります。


「じゃ、紹介すんなよ!」


と突っ込まれそうですが、障害発生のパターンや原因がはっきりしていて、回復措置が
確立している場合には結構有効ではないかと思っています。
簡単な一例として、

  • 原因はわからないが、突然あるサービスが落ちる
  • いったんサービスが落ちると、サービスの開始が出来ない
  • 回復させるためには、サーバ再起動が一番手っ取り早い


Linuxを想定したイベントハンドラを使用方法はNagiosのマニュアルにありますが、
今回はあえてWindowsのサンプルと、私なりの使用方法を紹介したいと思います。
なおイベントハンドラ以外のNagiosやNRPEの設定の詳細は割愛させて頂きます。



まず監視の仕様としては同じサーバに対して2種類の監視設定を行います。

  • イベントハンドラを使用せず通知のみの通常の監視設定
    ⇒通常の監視設定
  • イベントハンドラを使用する監視設定
    ⇒監視期間(check_period)が土日もしくは平日深夜~早朝などに絞る
    ⇒監視サイクルが長め(normal_check_interval、retry_check_interval)
        もしくはリトライ回数(max_check_attempts)を多めにする


人が対応できる時間帯は障害通知を確認後に手動でサーバを再起動し、
休日や深夜~早朝など、人が対応出来ない時間帯は自動でサーバを再起動するようにします。
監視サイクルを長めにする、監視リトライ回数を多めにするのは誤検知を防ぐ狙いです。

上記仕様を満たすイベントハンドラを使用した監視設定の例は

### service.cfg
define service {
                  service_description            Test-Service
                  use                                        generic-service
                  host_name                           Test-SV
                  check_period                       22-07
                  normal_check_interval        60
                  retry_check_interval            20
                  max_check_attempts          3
                  event_handler                      check_nrpe_Reboot_NT
                  check_command                 check_nrpe_cmd!nt_service
                  contact_groups                    Infra-Group
}

###nrpe.cfg

command[nt_service]=C:\nrpe_nt\bin\service_nrpe_nt.exe "Test Service"
command[RebootServer_nt]=cscript //nologo "C:\nrpe_nt\bin\eventhandler.vbs" $ARG1$ $ARG2$ $ARG3$

          ↑監視されるWindows側のNRPE設定



今回は監視サーバ(Nagios)のイベントハンドラが、回復措置として行うコマンドをNRPE経由で実行します。
そのため、
監視されるWindowsサーバが高負荷で、リモートからのコマンドを受け付けられない状態では
イベントハンドラの意味を成しません。当たり前ですけど。。。


Windowsイベントハンドラスクリプトこちらを参考にしていますが、環境によって動作しない場合があります。
あくまでもサンプルです。

''''eventhandler.vbs

Set args = WScript.Arguments


Select Case args.item(0)
  Case "OK":
             wscript.quit(0)
  Case "WARNING":
             wscript.quit(0)
  Case "UNKNOWN":
             wscript.quit(0)
  Case "CRITICAL":
             Select Case args.item(1)
       Case "HARD":
                 'Reboot Server
                 Call ForceReboot()

       Case "SOFT":
                 Select Case args.item(2)
             Case "4":
                       'Reboot Server
                       Call ForceReboot()
        Case Else
         wscript.quit(0)
        End Select
   End Select
End Select

wscript.quit(0)


Sub ForceReboot()
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "C:\nrpe_nt\bin\mailsend.vbs"
wscript.sleep(3000)
Set objSystemSet = GetObject("winmgmts:{impersonationLevel=impersonate,(Shutdown)}").InstancesOf("Win32_OperatingSystem")

For Each objSystem In objSystemSet
        objSystem.Win32Shutdown 6
Next
End Sub




監視ステータス"CRITICAL"の中に、"HARD"と"SOFT"がありますが、
max_check_attempts=3の場合、

  • "HARD"はmax_check_attemptsの上限到達
     ⇒監視結果が"CRITICAL"でリトライを3回繰り返し、障害通知行われる状態
  • "SOFT"はmax_check_attemptsの上限内
     ⇒監視結果が"CRITICAL"でリトライが2回以内。障害通知はまだ行われない状態

上記スクリプトはサンプルなので、わざと"HARD"と"SOFT"の条件を書いていますが、
max_check_attempts=3の場合は、リトライ回数が3でサーバの強制再起動が発生します。
(監視リトライの4回は理論的には発生しない)


監視サーバ(Nagios)側でイベントハンドラのコマンドを定義します。

#### event_handler command

define command {
 command_name   check_nrpe_Reboot_NT
 command_line   $USER1$/check_nrpe -H $HOSTADDRESS$ -c RebootServer_nt -a  $SERVICESTATE$ $SERVICESTATETYPE$ $SERVICEATTEMPT$
}


引数の内容は

  • $SERVICESTATE$:監視結果のステータス("OK"、"WARNING"、"UNKNOWN"、"CRITICAL")
  • $SERVICESTATETYPE$:CRITICAL時の状態("HARD"、"SOFT")
  • $SERVICEATTEMPT$:監視リトライ回数


イベントハンドラに関わる設定はこんな感じです。
実運用の前に十分なテストが必要なことは言うまでもありません。


興味のある方はお試し下さい。

では、また。