High Availability

インターネットで商用アプリケーションが重大になればなるほど、役に立つサービスを提供することは非常に重要になる。クラスタリングシステムの利点はハードウェアとソフトウェアの冗長性を持たせることである。仕事の分担をクラスターが残ったノードによって、適確に引き継げるように高い可用性は失敗したノードやデーモンによってシステムを再構成する。

事実高い可用性は大きな領域だ。適確な高い有効性のあるシステムは信頼できるグループコミュニケーションのサブシステムやメンバー管理、サブシステムの定員、同時コントロールなどのサブシステムを持っているかもしれない。たくさんの仕事がある。 しかしながら、私たちは高い有効性のある LVS システムを構築するための既存のソフトウェアを使うことができる。高い有効性のあるLVS システムを構築するにはたくさんの方法があるに違いない。もし、よい方法があるなら私に教えて欲しい。以下の2つの解決法は参考のためだ。

1. mon+heartbeat+fake+coda による解決法

バーチャルサーバーの高い有効性は "mon"や"heartbeat" や"fake"や"coda" のソフトウェアを使って提供する。 "mon"は汎用リソースをモニタリングするシステムでネットワークサービスの有効性とサーバーノードをモニターするために使われる。 "heartbeat"は現在2つのノード間でシリアルラインやUDP 心拍を使って提供します。 "fake"はARPをだまして使うことによって、IPをのっとったソフトウェアのことです。 Linux Virtual Server の高い有効性は次の図で説明されています。

サーバーのフェイルオーバーは次のとおりだ。"mon" というデーモンはサービスデーモンとサーバーノードを監視するためのロードバランサー上で動作する。 fping.monitor は毎秒サーバーノードが動いているかどうか検出するために構成されていて、関連性のあるサービスモニターも m 秒ごとにすべてのノード上のサービスデーモンを検出するために構成されている。例えば、http.monitor は http サービスをチェックするために使われ、 ftp.monitor は FTP サービスのためのものである。 サーバーノードかデーモンが上がっているか、落ちているかを検出する間、lvsテーブルのルールを追加、削除するために警報が書き込まれる。 その結果、ロードバランサーはサービスデーモンやサーバーが落ちた時それを自動的に隠すことができ、正常な状態に戻った時、それらのサービスを戻らせることができる。

そしてロードバランサーが全体のシステムで単一故障したとする。一番重要なロードバランサーの故障を隠すために、私たちはロードバランサーのバックアップサーバーをセットアップする必要がある。"fake"というソフトウェアはロードバランサーが落ちた時、ロードバランサーのIPアドレスを引き継ぐためのバックアップとして使われる。 また、"heartbeat"はバックアップサーバーの"fake"が起動するか、しないかを調べるためにロードバランサーの状況を検出するために使われる。 2つの"heartbeat"デーモンはプライマリとバックアップで動作し、シリアルライン上で、周期的に"I'm alive"のようなメッセージをやりとりしている。 バックアップの"heartcode"デーモンが一定時間内でプライマリから"I'm alive"メッセージを聞くことができなかったら、バーチャルIPアドレスを引き継ぎ、ロードバランシングサービスを供給するために"fake"を起動する。 後で、プライマリから"I'm alive"メッセージを受け取ったら、バーチャルIPアドレスを解放し、またプライマリへ制御を戻すために"fake"の使用を止める。

しかし、プライマリロードバランサーのフェイルオーバーやテイクオーバーはハッシュテーブルにある現在実行中の確立されたコネクションを無くしてしまう原因になる。 それによりクライアントは接続要求をまた送らなければならない。

Coda は冗長性のある分散ファイルシステムでAndrewファイルシステムの子孫である。 ファイルを有効に簡単に管理するために、サーバーのコンテンツはCodaを使って保存する。

設定例

次にあるのはダイレクトルーティングを経由した有効性のあるバーチャルウェブサーバーのセットアップ例です。

リアルサーバーのフェイルオーバー

"mon"はクラスターでサービスデーモンとサーバーノードを監視するために使われる。 例えば、fping.monitor はサーバーノードを監視するために使われ、http.monitor は http サービスをチェックするために使われ、 ftp.monitor は FTP サービスのためのものである。 だから私たちは、サーバーノードかデーモンが上がっているか、落ちているかを検出する間、lvsテーブルのルールを追加、削除するために警報を書き込む必要がある。 これは lvs.alerと呼ばれる例だ。これはリアルサーバーのパラメータとしてIPとポート番号を使う。
#!/usr/bin/perl 
# 
# lvs.alert - Linux Virtual Server alert for mon 
# 
# It can be activated by mon to remove a real server when the 
# service is down, or add the server when the service is up. 
# 
# "mon"によって、サービスが落ちた時リアルサーバーをハッシュテーブルから削除し、 # サービスが戻ったらリアルサーバーをハッシュテーブルに追加するために起動される
# 

use Getopt::Std;
getopts ("s:g:h:t:l:P:V:R:W:F:u");

$ipvsadm = "/sbin/ipvsadm";
$protocol = $opt_P;
$virtual_service = $opt_V; 
$remote = $opt_R;

if ($opt_u) {
    $weight = $opt_W;
    if ($opt_F eq "nat") {
	$forwarding = "-m";
    } elsif ($opt_F eq "tun") {
	$forwarding = "-i";
    } else {
	 $forwarding = "-g";
    }

    if ($protocol eq "tcp") {
        system("$ipvsadm -a -t $virtual_service -r $remote -w $weight $forwarding");
    } else {
	system("$ipvsadm -a -u $virtual_service -r $remote -w $weight $forwarding");
    }
} else { 
    if ($protocol eq "tcp") {
	system("$ipvsadm -d -t $virtual_service -r $remote");
    } else {
	system("$ipvsadm -d -u $virtual_service -r $remote");
    }
};

lvs.alert は /usr/lib/mon/alert.d ディレクトリに置かれる。"mon"の設定ファイルは(/etc/mon/mon.cf 又は /etc/mon.cf)次のとおりクラスターにある http サービスとサーバーを監視するために設定される。 The lvs.alert is put under the /usr/lib/mon/alert.d directory. The mon configuration file (/etc/mon/mon.cf or /etc/mon.cf) can be configured to monitor the http services and servers in the cluster as follows.

#
# The mon.cf file
#
#
# global options
#
cfbasedir   = /etc/mon 
alertdir   = /usr/lib/mon/alert.d
mondir     = /usr/lib/mon/mon.d
maxprocs    = 20
histlength = 100
randstart = 30s

#
# group definitions (hostnames or IP addresses)
#
hostgroup www1 www1.domain.com 

hostgroup www2 www2.domain.com

#
# Web server 1
# 
watch www1
    service http 
       	interval 10s 
	monitor http.monitor 
	period wd {Sun-Sat} 
	    alert mail.alert wensong 
	    upalert mail.alert wensong 
	    alert lvs.alert -P tcp -V 10.0.0.3:80 -R 192.168.0.1 -W 5 -F dr
	    upalert lvs.alert -P tcp -V 10.0.0.3:80 -R 192.168.0.1 -W 5 -F dr

#
# Web server 2
# 
watch www2 
    service http 
        interval 10s 
	monitor http.monitor 
	period wd {Sun-Sat} 
	    alert mail.alert wensong 
	    upalert mail.alert wensong 
	    alert lvs.alert -P tcp -V 10.0.0.3:80 -R 192.168.0.2 -W 5 -F dr
	    upalert lvs.alert -P tcp -V 10.0.0.3:80 -R 192.168.0.2 -W 5 -F dr

もし LVS/NAT で destination port が違っていたら、 "lvs.alert -V 10.0.0.3:80 -R 192.168.0.3:8080" のように設定しないで適宜自分の環境に合わせて代えてください

ロードバランサーはサービスデーモンやサーバーが落ちたことを自動的に隠すことができ、落ちたサーバーが復帰した時、サービスを元のサーバーに戻すことができます。

ロードバランサーのフェイルオーバー

ロードバランサーが全体のシステムで単一故障するのを防ぐために、私たちはロードバランサーのバックアップをセットアップする必要があり、お互いを周期的に"heartbeat"させる必要がある。"heartbeat"パッケージを含む GettingStandard ドキュメントを読んで欲しい。それを使えば簡単に2つのノードの "heartbeat" システムをセットアップすることができる。

例えば、2つのロードバランサーが以下のようなIP アドレスを持っていたとする。
lvs1.domain.com (primary) 10.0.0.1
lvs2.domain.com (backup) 10.0.0.2
www.domain.com (VIP) 10.0.0.3

lvs1.domain.com と lvs2.domain.com の両方に "heartbeat" をインストールした後、次のとおり /etc/ha.d/ha.conf を作れ

#
#       keepalive: heartbeats の間隔は何秒にするか
#
keepalive 2
#
#       deadtime: 落ちたホストを宣言する間隔は何秒にするか
#
deadtime 10
#       hopfudge: 設定ファイル中で最大ホップ数からノードの数を引く
hopfudge 1
#
#       udpport: UDP ポートは何番?
#
udpport 1001
#       udp: heartbeat に使うのはどのインターフェイス?
udp     eth0
#
#       logfacility: syslog のために使う機能は?
#
logfacility     local0
#
#       クラスターにあるマシンは?
#	"uname -n" で見つからないと駄目です
#       書式 : node    nodename ...
    
node    lvs1.domain.com
node    lvs2.domain.com

/etc/ha.d/haresources にあるファイルは次のとおりです:

lvs1.domain.com 10.0.0.3 lvs mon

/etc/rc.d/init.d/lvs にあるファイルは次のとおりです:

#!/bin/sh

#
# あなたはローカルファイルシステムにだけ含まれるパスをセットしたいだろう 
#
PATH=/bin:/usr/bin:/sbin:/usr/sbin
export PATH

IPVSADM=/sbin/ipvsadm

case "$1" in
    start)
	if [ -x $IPVSADM ]
	then
            echo 1 > /proc/sys/net/ipv4/ip_forward
	    $IPVSADM -A -t 10.0.0.3:80
	    $IPVSADM -a -t 10.0.0.3:80 -r 192.168.0.1 -w 5 -g
	    $IPVSADM -a -t 10.0.0.3:80 -r 192.168.0.2 -w 5 -g
	fi
	;;
    stop)
	if [ -x $IPVSADM ]
	then
	    $IPVSADM -C
	fi
	;;
    *)
    	echo "Usage: lvs {start|stop}"
	exit 1
esac

exit 0

最後に、lvs1 と lvs2 の両方のノードですべてのファイルが作られているかどうか確認し、あなた自身の設定を伝えてから、heartbeat デーモンを2つのノードでスタートさせなさい。

"fake"(余計な ARP による IP のテイクオーバー)はすでに heartbeat に含まれている。だから "fake" を改めてセットアップする必要はない。 lvs1.domain.com のノードが落ちた時、lvs2.domain.com は lvs1.domain.com のすべてのリソースを引き継ぐだろう。すなわち、余計な ARP によって IPアドレス 10.0.0.3 のHA リソースを引き継ぎ、/etc/rc.d/init.d/lvs と /etc/rc.d/init.d/mon のスクリプトをスタートさせる。lvs1.domain.com が正常に戻ったら、lvs2.domain.com は HA リソースを解放し、制御を lvs1.domain.com に戻す。

2. The ldirectord と heartbeat 解決法

ldirectord (Linux Director Daemon)はJacob Riefによって書かれたリアルサーバー(http や https)のサービスを監視するためのスタンドアローンなデーモンです。 インストールは簡単でheartbeatと一緒に動作します。 ldirectord プログラムは ipvs の TAR-BALL にある contrib ディレクトリの下や、最新の heartbeat の CVS レポジトリをチェックすれば見つけることができます。 ldirectord についてのすべての情報は 'perldoc ldirectord' を見てください。 この偉大なプログラムを書いてくれたJacob Riefに感謝!

mon を使った ldirectord の利点は次にあるとおりです

いずれにしても、 ldirectord も手動でスタートできるしストップさせることもできる。あなたはロードバランサーのバックアップなしで LVS クラスターを使うことができる。

設定例

mon と heartbeat と fake と coda の解決法による導入例として、次のように /etc/ha.d/www.cf を設定することができる。

#
# ldirectord のための /etc/ha.d/www.cf
#

# timeout:  リアルサーバーが落ちたと宣言されるまでの秒数
timeout = 10

# checkinterval: サーバーがチェックするまでの秒数
checkinterval = 10

#
# virtual = x.y.z.w:p
#     protocol = tcp|udp
#     scheduler = rr|wrr|lc|wlc
#     real = x.y.z.w:p gate|masq|ipip [weight]
#     ...
#     

virtual = 10.0.0.3:80
     protocol = tcp
     scheduler = wlc
     real = 192.168.0.1:80 gate 5
     real = 192.168.0.2:80 gate 5
     request = "/.testpage"
     receive = "test page"

/etc/ha.d/haresources ファイルは次のようにシンプルだ:

    lvs1.domain.com IPaddr::10.0.0.3 ldirectord::www

WEBサーバーに1つ、ドキュメントルートに .testpage を作る必要がある。

    echo "test page" > .testpage

プライマリとバックアップで heartbeat デーモンを動かしなさい。もし設定が間違っていたら、それぞれの /var/log/ha-log と /var/log/ldirector.log を調べなさい。


$Id: HighAvailability.html,v 1.4 2000/03/21 12:55:00 wensong Exp $
Created on: 1998/12/5