2007年05月22日
知っていても損はしないkeepalivedの話 〜 MISC_CHECKの注意点
keepalived では様々なヘルスチェック方式がサポートされています。
例えば DNS とか FTP とかあれとかこれとか・・・
FTP は最悪 TCP_CHECK でお茶を濁すって手もありますが、FTP サーバがポートをオープンしたまま応答不能になることも考えられるので、あまりお勧めできません。また、DNS をチェックする機能は keepalived にはありません。
そんな時に使うのが MISC_CHECK です。今回は MISC_CHECK を利用する上での注意点や設定のサンプルを紹介したいと思います。
- HTTP_GET
- SSL_GET
- SMTP_CHECK
- TCP_CHECK
例えば DNS とか FTP とかあれとかこれとか・・・
FTP は最悪 TCP_CHECK でお茶を濁すって手もありますが、FTP サーバがポートをオープンしたまま応答不能になることも考えられるので、あまりお勧めできません。また、DNS をチェックする機能は keepalived にはありません。
そんな時に使うのが MISC_CHECK です。今回は MISC_CHECK を利用する上での注意点や設定のサンプルを紹介したいと思います。
■ MISC_CHECK とは
指定したプログラムを実行して、その終了コードによってリアルサーバを UP したり DOWN させる機能です。
■使い方
使い方はとっても簡単です(笑)
misc_path で指定されたコマンドを実行し、終了コードが0ならば成功、それ以外なら失敗と見なします。また、misc_timeout 以内にコマンドが終了しない場合も失敗になります。misc_dynamic という設定を追加すると、終了コードの値によってリアルサーバの weight を変える事ができるようになります。
■ 注意点など
「これならヘルスチェック用のスクリプトをさくっと書いて misc_path に設定するだけで何でもできる!」と思うかもしれませんが、いくつか注意しなければならない点があります。
keepalived は MISC_CHECK で起動したプロセスを kill しません。
例えば以下のような設定をしてみます。
この設定で keepalived を起動すると
つまり、MISC_CHECK から呼び出されるプログラムは、リアルサーバに何が起こっても確実に自分で終了できる必要があるわけです。
ヘルスチェックスクリプトを書く場合は、リアルサーバが応答不能になった場合でも正常に動作できるように、注意する必要があります。さもないと、
■そうならないためには
それでは、MISC_CHECK で利用したいコマンドがきちんと終了できるかどうかを確認する方法をご紹介します。確認すべき事は大きくふたつ
わかりやすい例として ssh クライアントを使ってみましょう。
2台のマシン(HOST1,HOST2)を用意して、以下のようなコマンドを実行してみて下さい。
host2 の8022番ポートではなんのサービスも動いてないので接続が拒否されます。
次に、host2 のネットワークケーブルをはずして実行してみます。
TCP接続できない状況においては、最長でも5秒でコマンドが完了することが確認できると思います。
それでは以下のようにするとどうなるでしょうか。
host2 では nc コマンドの -l オプションを使って8022番ポートをオープンしておきます。そして host1 から ssh クライアントで接続してみます。どれだけ待っても ssh コマンドはエラーになりません。
というわけで、-o "ConnectTimeout=5" の指定はTCP接続のタイムアウトを指定するためのものなので、TCP接続が完了したあとでは意味を持たないのです。
つまりこれは、sshヘルスチェックのために
と記述すると、サーバがフリーズした時にヘルスチェック用の ssh プロセスが増殖してしまう事を意味しています。
ssh コマンドをそのまま MISC_CHECK に利用するのは危険なのです。
■ 設定方法のサンプル
最後に、FTPとDNSをチェックするMISC_CHECKの使用例をご紹介します。
指定したプログラムを実行して、その終了コードによってリアルサーバを UP したり DOWN させる機能です。
■使い方
使い方はとっても簡単です(笑)
MISC_CHECK { misc_path <実行コマンド> misc_timeout <タイムアウト(秒)> }
misc_path で指定されたコマンドを実行し、終了コードが0ならば成功、それ以外なら失敗と見なします。また、misc_timeout 以内にコマンドが終了しない場合も失敗になります。misc_dynamic という設定を追加すると、終了コードの値によってリアルサーバの weight を変える事ができるようになります。
# If set, exit code from healthchecker is used # to dynamically adjust the weight as follows: # exit status 0: svc check success, weight # unchanged. # exit status 1: svc check failed. # exit status 2-255: svc check success, weight # changed to 2 less than exit status. # (for example: exit status of 255 would set # weight to 253) misc_dynamic
■ 注意点など
「これならヘルスチェック用のスクリプトをさくっと書いて misc_path に設定するだけで何でもできる!」と思うかもしれませんが、いくつか注意しなければならない点があります。
keepalived は MISC_CHECK で起動したプロセスを kill しません。
例えば以下のような設定をしてみます。
virtual_server 10.0.0.1 80 { delay_loop 5 lb_algo rr lb_kind DR real_server 192.168.1.1 80 { MISC_CHECK { misc_path "/bin/sleep 3600" misc_timeout 10 } }
この設定で keepalived を起動すると
- /bin/sleep 3600 を実行
- 10秒待つ(misc_timeout)
- 終了しないので(あたりまえですが・・・)リアルサーバのステータスをダウンにする
- 5秒待つ(delay_loop)
- /bin/sleep 3600 を実行
- (以下繰り返し)
つまり、MISC_CHECK から呼び出されるプログラムは、リアルサーバに何が起こっても確実に自分で終了できる必要があるわけです。
ヘルスチェックスクリプトを書く場合は、リアルサーバが応答不能になった場合でも正常に動作できるように、注意する必要があります。さもないと、
- どっかのリアルサーバに障害が発生する
- プロセスが増え続ける
- プロセス数がいっぱいになる
- 他のヘルスチェックを起動できなくなる
- 関係ないサービスまで停止する
■そうならないためには
それでは、MISC_CHECK で利用したいコマンドがきちんと終了できるかどうかを確認する方法をご紹介します。確認すべき事は大きくふたつ
- TCP接続ができないときにエラーになること
- TCP接続はできるけどサーバから応答が無いときにエラーになること
わかりやすい例として ssh クライアントを使ってみましょう。
2台のマシン(HOST1,HOST2)を用意して、以下のようなコマンドを実行してみて下さい。
host2 の8022番ポートではなんのサービスも動いてないので接続が拒否されます。
host1: $ ssh -o "ConnectTimeout=5" -p 8022 host2 ssh: connect to host host2 port 8022: Connection refused
次に、host2 のネットワークケーブルをはずして実行してみます。
host1: $ ssh -o "ConnectTimeout=5" -p 8022 host2 ssh: connect to host host2 port 8022: Connection timed out
TCP接続できない状況においては、最長でも5秒でコマンドが完了することが確認できると思います。
それでは以下のようにするとどうなるでしょうか。
host2: $ nc -l -p 8022 host1: $ ssh -o "ConnectTimeout=5" -p 8022 host2
host2 では nc コマンドの -l オプションを使って8022番ポートをオープンしておきます。そして host1 から ssh クライアントで接続してみます。どれだけ待っても ssh コマンドはエラーになりません。
というわけで、-o "ConnectTimeout=5" の指定はTCP接続のタイムアウトを指定するためのものなので、TCP接続が完了したあとでは意味を持たないのです。
つまりこれは、sshヘルスチェックのために
MISC_CHECK { misc_path "ssh 192.168.1.1 exit 0" misc_timeout 10 }
と記述すると、サーバがフリーズした時にヘルスチェック用の ssh プロセスが増殖してしまう事を意味しています。
ssh コマンドをそのまま MISC_CHECK に利用するのは危険なのです。
■ 設定方法のサンプル
最後に、FTPとDNSをチェックするMISC_CHECKの使用例をご紹介します。
- DNSヘルスチェック
MISC_CHECK { misc_path "/usr/bin/dig +time=001 +tries=2 @192.168.1.1 klab.org" misc_timeout 5 }
- FTPヘルスチェック
MISC_CHECK { misc_path "echo -en 'NOOP\r\nQUIT\r\n' | nc -w 5 -n 192.168.1.1 21 | egrep '200 NOOP command successful'" misc_timeout 5 }
たいていのFTPサーバではNOOPコマンドが使えます。これはFTPサーバが稼働しているかどうかを調べる為のコマンドで、ログオンせずに利用可能ですので、ヘルスチェックの為のFTPアカウントを作る必要はありません。
この例ではncを使ってコマンドの送受信をしています。ncの-wオプションは、接続時のタイムアウトだけでなく、リードタイムアウトも兼ねているので、リアルサーバが応答不能になっても必ず終了してくれます。
$ nc -h 2>&1 | grep '\-w' -w secs timeout for connects and final net reads
klab_gijutsu2 at 22:44│Comments(0)│TrackBack(0)