簡易に試せるロードバランサー

仕事で, ロードバランサーを使った検証をしてみる必要があって, 久しぶりに Pound を触ってみました. 手軽に扱うことのできるオープンソースのソフトウェアです.

手元のラップトップ PC に, VMwareインスタンスを作り, まず OS をインストールします. わたしが好んで利用する OS は, Debian GNU/Linux です. といっても, 特に理由があるわけではありませんが. 現在, 最新の安定版は, バージョン 6.0.3 だそうです. これをインストールします.

Pound のセットアップ

Debian には Pound のパッケージがありますので, けっこう簡単に Pound をインストールすることができます. apt-get コマンドでインストールすることができるのは, バージョン 2.5-1 です.

# apt-get install pound
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  libpcre3
The following NEW packages will be installed:
  libpcre3 pound
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 338 kB of archives.
After this operation, 766 kB of additional disk space will be used.
Do you want to continue [Y/n]? Y
Get:1 http://ftp.jp.debian.org/debian/ squeeze/main libpcre3 i386 8.02-1.1 [231 kB]
Get:2 http://ftp.jp.debian.org/debian/ squeeze/main pound i386 2.5-1 [106 kB]
Fetched 338 kB in 0s (1,060 kB/s)
Selecting previously deselected package libpcre3.
(Reading database ... 14553 files and directories currently installed.)
Unpacking libpcre3 (from .../libpcre3_8.02-1.1_i386.deb) ...
Selecting previously deselected package pound.
Unpacking pound (from .../archives/pound_2.5-1_i386.deb) ...
Processing triggers for man-db ...
Setting up libpcre3 (8.02-1.1) ...
Setting up pound (2.5-1) ...
pound will not start unconfigured. ... (warning).
Please configure; afterwards, set startup=1 in /etc/default/pound. ... (warning).

インストール直後においては, 設定ファイル /etc/pound/pound.cfg は次のようになっています.

## Minimal sample pound.cfg
##
## see pound(8) for details


######################################################################
## global options:

User            "www-data"
Group           "www-data"
#RootJail       "/chroot/pound"

## Logging: (goes to syslog by default)
##      0       no logging
##      1       normal
##      2       extended
##      3       Apache-style (common log format)
LogLevel        1

## check backend every X secs:
Alive           30

## use hardware-accelleration card supported by openssl(1):
#SSLEngine      "<hw>"

# poundctl control socket
Control "/var/run/pound/poundctl.socket"


######################################################################
## listen, redirect and ... to:

## redirect all requests on port 8080 ("ListenHTTP") to the local webserver (see "Service" below):
ListenHTTP
        Address 127.0.0.1
        Port    8080

        ## allow PUT and DELETE also (by default only GET, POST and HEAD)?:
        xHTTP           0

        Service
                BackEnd
                        Address 127.0.0.1
                        Port    80
                End
        End
End

この設定ファイルを編集することが, まずは必要です. ちなみに, 検証したい環境の構成は, ここではたとえば次のようになっているものとします.

すなわち, クライアントが L に対してリクエストを送ると, L はそのリクエストを A または B に転送します. A または B が L に対してレスポンスを返すと, L はそのレスポンスをクライアントに返します. そこで, 先ほどの設定ファイルの ListenHTTP ディレクティブ以下を, 次のように書き換えます.

ListenHTTP
        Address 192.168.254.65
        Port    8080
        xHTTP           0
        Service
                BackEnd
                        Address 192.168.254.66
                        Port    8080
                End
                BackEnd
                        Address 192.168.254.67
                        Port    8080
                End
        End
End

設定ファイルの編集が済んだら, 次は /etc/default/pound を編集します. このファイルは, インストール直後においては, 次のようになっています.

# Defaults for pound initscript
# sourced by /etc/init.d/pound
# installed at /etc/default/pound by the maintainer scripts

# prevent startup with default configuration
# set the below varible to 1 in order to allow pound to start
startup=0

注釈中の varible は原文のままです. おそらく variable のタイポだろうと思います. startup の値を 0 から 1 に変更して, 保存します.

そして, Pound を起動します.

# /etc/init.d/pound start

以上で, ロードバランサーが立ち上がりました. あまりにも簡単でびっくりしてしまいます.

Pound による死活監視

ところで, Pound は, バックエンドの各アプリケーションサーバーの死活監視をどのようにおこなっているのでしょうか.

設定ファイルの中では Alive の値が 30 となっています. 単位は秒です. これに関しては, インターネット上の日本語の情報などを検索しますと, たとえば次のような記述が散見されます.

バッグエンドのサーバにハートビートを送る間隔(秒)を指定します。
デフォルトは 30(秒) です。
Alive を短くするとバッグエンドサーバの障害発生時のダウンタイムが短くなりますが, 短くしすぎるとリソースを消費してしまうので注意して下さい。

これ以外の記事も, その多くは 「ハートビートを送る間隔」 と説明しているようです. ということは, Pound はデフォルトでは常に 30 秒ごとに, 各バックエンドの死活監視をおこなっている, ということなのでしょうか.

しかしですね, パケットをキャプチャーして観察してみればわかるのですが, それは正しくありません. 先ほどの例で言いますと, サーバー A もサーバー B も TCP ポート 8080 のサービスが稼働中の状態にあるとき, そもそもロードバランサー L は A にも B にも一切パケットを送りません. クライアントからから新たなリクエストが来てはじめて, L は A または B のいずれかに TCP ハンドシェイクを試みようとします.

また, もし, それ以前に A または B のいずれかがダウンしていたとしても, L はここで TCP ハンドシェイクに失敗した時点で, はじめて A または B のいずれかがダウンしていることを検知します. そして, 一度それを検知すると, そこからはたしかに 30 秒ごとに TCP ハンドシェイクを試み, サービスが復活したかどうかを確認します. さらに, ダウンしていたサーバーのサービスが復活し, TCP ハンドシェイクが成功すると, そこからはもう 30 秒ごとに何かをするということはありません.

どう考えても, 30 秒ごとにハートビートを送ることで障害発生を検知している, などとは言えません.

それでは, そもそも製品同梱のマニュアルには, どのように書かれているのでしょうか.

Specify how often Pound will check for resurected back-end hosts (default: 30 seconds). In general, it is a good idea to set this as low as possible - it will find resurected hosts faster. However, if you set it too low it will consume resources - so beware.

resurected は resurrected のタイポだと思いますが, これを読めば明らかですね. ダウンしたバックエンドのサーバーが復活 (resurrection) したのかどうかを 30 秒ごとにチェックしている, ということです. つまり, 障害検知のためのものではなく, いわば復活検知のためのものなのです.

インターネット上で得られる日本語の情報は, 分野によってはけっこう貴重で, ふだん大いに助けられてはいますが, 時としてこういうことはありますね. おそらく, 「ハートビートを送る間隔」 と説明している多くの記事は, 直接的には上で引用した記事をそのまま孫引きしているのではないかと思われます. こういうことが繰り返されると, 誤訳や誤読が一人歩きして広く蔓延することにもなりかねません. 気をつけたいものです.