DRBD と Heartbeat で CentOS の WWW サーバを冗長化 (アクティブ/スタンバイの HA クラスタを構築)

クラウドがバリバリ使われている世の中なので今更感もあるが、サーバの冗長化技術を試した。

サーバを構築しながらメモしたので、あまり整理できていないところもあるけど公開。

利用するソフトウェアについて

DRBD

DRBD Download | LINBIT - Download DRBD Linux Kernel Driver LINSTOR
Distributed Redundant Block Device driver for Linux

ライセンスは GPLv2
DRBD Download | LINBIT - Download DRBD Linux Kernel Driver LINSTOR

DRBD は master/slave 形式でサーバのパーティションミラーリングをおこなう。
ネットワーク経由の RAID1 と考えられる。
この図を見るのが早い。
DRBD Download | LINBIT - Download DRBD Linux Kernel Driver LINSTOR

SPoF が存在しない、シェアードナッシングの HA クラスタを構築可能。

ブロックデバイスレベルでミラーするので、データにアクセス可能なアクティブなノードは基本的にひとつだけ。

(デュアルプライマリモードと分散ファイルシステムを組み合わせる方法はあるらしい。)
DRBD Download | LINBIT - Download DRBD Linux Kernel Driver LINSTOR

どうしてブロックレベルでミラーリングするのかは、この論文に書かれている。
DRBD Download | LINBIT - Download DRBD Linux Kernel Driver LINSTOR

フェイルオーバに関する機能はないので、他のソフトウェアと組み合わせて使うことが多い。

kernel 2.6.33 から mainline にとりこまれたので、カーネルドライバのインストールは不要になる予定。

Heartbeat

Download - Linux-HA

Heartbeat は障害検知と master の切り替えをおこなう。
マスタサーバのモニタリングをおこない、障害を検知したら、
スレーブで必要な処理をおこなってマスターにする。

今回のテスト環境

VMware Player 3.1.3 上の CentOS 5.5 i386 で WWW サーバの冗長化設定を試してみた。
kernel は 2.6.18 なので、DRBD カーネルドライバのインストールも必要。

サーバの構成で考慮すべき点。

  • 必ずしも同一スペックのサーバーでなくともよい (今回は VMware なので同一スペックでそろえる)
  • 同一サイズのパーティションを確保できる十分なサイズのディスク
  • 全てのサーバで同じバージョンのデーモンを動作させる
  • 言うまでもなくネットワークに接続できる必要あり
  • モニタリング用にシリアルポートが利用できるとベター

ディスクの準備

fdisk /dev/sdb で primary partition を作成

/dev/sdb1 1 2088 16771828+ 83 Linux

この時点では、まだ mkfs しない。

DRBD のセットアップ

DRBD をインストール

Package Manager で検索すると、複数バージョンが見つかる
ここでは drbd83-8.3.8-1.el5.centos.i386 をインストール
kmod-drbd83-8.3.8-1.el5.centos.i686 もインストール
kernel は 2.6.18-194.26.1.el5 で起動していたが、2.6.18-194.el5 で起動するように /boot/grub/grub.conf の default を修正しておく

OS の設定

  • /etc/hosts に master/slave の IP アドレスとサービスで使う仮想 IP アドレスを記入

192.168.1.1 server1
192.168.1.2 server2
192.168.1.5 mail

mkdir /replicated

  • /etc/fstab にエントリ追加

/dev/drbd0 /replicated ext3 noauto 0 0

この時点では、/replicated はマウントできない。

DRBD の設定

CentOS の場合、デフォルトの /etc/drbd.conf は空 (コメントのみ)
/etc/drbd.d/global_common.conf

#
# please have a a look at the example configuration file in
# /usr/share/doc/drbd83/drbd.conf
#
global { usage-count yes; }
common { syncer { rate 10M; } }
resource r0 {
    protocol C;
    startup {
         degr-wfc-timeout 120;
    }
    net {
         cram-hmac-alg sha1;
         shared-secret "Himitsu";
    }
    on server1.localdomain {
         device    /dev/drbd0;
         disk      /dev/sdb1;
         address   192.168.1.100:7789;
         meta-disk  internal;
    }
    on server2.localdomain {
         device    /dev/drbd0;
         disk      /dev/sdb1;
         address   192.168.1.101:7789;
         meta-disk  internal;
    }
}

protocol C (完全同期モード) で設定。
DRBD Download | LINBIT - Download DRBD Linux Kernel Driver LINSTOR

その他の設定内容はここを参照すればだいたい載っている。
DRBD Download | LINBIT - Download DRBD Linux Kernel Driver LINSTOR
DRBD Download | LINBIT - Download DRBD Linux Kernel Driver LINSTOR

# drbdadm create-md r0
... (the global usage survey が表示される)
(このバージョンの利用者はこの時点でユーザ数は 5191人だった)
Writing meta data...
initializing activity log
NOT initialized bitmap
New drbd meta data block successfully created.
success

  • デーモンを動かしてステータス確認

# /etc/init.d/drbd restart
# cat /proc/drbd
この時点では "cs:WFConnection ro:Secondary/Unknown ds:Inconsistent/DUnknown" などと表示されている

"Security Level Configuration" (GUI) からおこなえばよい

コピーしたときに eth0.bak ができたようなので削除して eth0 のみとした

IP 変更
ホスト名変更
MAC アドレスの衝突に注意

  • 2台のサーバが起動した状態で、server1 からディスクの同期をおこなう (ついでに同期に必要な時間を計測)

(それぞれのサーバで drbd start しておく)
# time drbdadm -- --overwrite-data-of-peer primary all

16GB で約 30 分

# cat /proc/drbd
# /etc/rc.d/init.d/drbd status
でも同期状況は確認可能

# cat /proc/drbd
同期完了すると server1 では "cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate" などと表示される

# mkfs -t ext3 /dev/drbd0
約 1分。

これでマウントしてデータの同期ができるようになる。(この時点では Heartbeat を設定していないのでまだ手動マウント)
server1
# drbdadm primary all
# mount /dev/drbd0 /mnt
# touch /mnt/drbd_test.txt
# umount /mnt
# drbdadm secondary all

server2
# drbdadm primary all
# mount /dev/drbd0 /mnt
# ll /mnt/
(server1 でつくったファイルがあることを確認)
# umount /mnt
# drbdadm secondary all

server1
# drbdadm primary all

Heartbeat

Heartbeat をインストール

Package Manager で検索
heartbeat-2.1.3-3.el5.centos.i386
heartbeat-gui-2.1.3-3.el5.centos.i386
heartbeat-pils-2.1.3-3.el5.centos.i386
heartbeat-stronith-2.1.3-3.el5.centos.i386
ユーザ hacluster が追加される
(heartbeat は 2回インストールする必要あり?)

ファイアウォールで 694/UDP を許可しておく
Heartbeat の設定ファイル ha.cf を作成

/usr/share/doc/heartbeat-2.1.3/ha.cf を参考にしつつ、/etc/ha.d/ha.cf 作成

logfacility local0
auto_failback on
keepalive 2
deadtime 30
initdead 120
udpport 694
bcast eth0
watchdog /dev/watchdog
node server1.localdomain
node server2.localdomain
use_logd yes
crm yes

Heartbeat の設定ファイル logd.cf を作成

/usr/share/doc/heartbeat-2.1.3/logd.cf を参考にしつつ、/etc/logd.cf 作成

debugfile /var/log/ha-debug
logfile /var/log/ha-debug
logfacility none

Heartbeat の設定ファイル logd.cf を作成

/usr/share/doc/heartbeat-2.1.3/authkeys を参考にしつつ、/etc/ha.d/authkeys 作成

auth 1
1 crc

chmod 600 /etc/ha.d/authkeys

/var/lib/heartbeat/crm/ は初期状態では空だが、cib.xml が存在していれば削除しておく

cib.xml を生成するための haresources 作成 (場所は ~/ でよい)

server2 の場合は冒頭のホスト名を server2 に変える

server1.localdomain IPaddr2::192.168.1.5/24/eth0/192.168.1.255 drbddisk::r0 Filesystem::/dev/drbd0::/mnt

haresources から cib.xml 作成

# /usr/lib/heartbeat/haresources2cib.py haresources
# vi /var/lib/heartbeat/crm/cib.xml

nic と cidr_netmask の value を入れ替える (eth0 <-> 24)
どうやらバグらしい。

# crm_verify -x /var/lib/heartbeat/crm/cib.xml

heartbeat 起動

# /etc/rc.d/init.d/heartbeat start
# chkconfig heartbeat on

server2 でも同様に設定する

これでフェイルバック、フェイルオーバが可能になった!

管理用コマンドを勉強しておくべし
  • ip addr show eth0 で仮想 IP を確認できる (master には secondary eth0 が表示される)
  • crm_mon で heartbeat の動作状況が確認できる
  • cibadmin でファイルバック等の設定変更ができる
  • crm_standby でスタンバイ状態の手動切り替えができる

こちらも参照。
ja/ha.cf_ja: Linux HA
http://www.linux-ha.org/doc/ch-initial-config.html
http://www.linux-ha.org/doc/re-hacf.html

冗長化するサービスの設定

今回は Apache で試してみる
server1、server2 ともに Apache を停止して、自動起動も解除しておく。

# /etc/rc.d/init.d/httpd stop
# chkconfig httpd off

DocumentRoot のデータを DRBD へコピー

# rsync -avz -e ssh --delete /var/www/ /mnt/

Apache 用に Heartbeat の設定を変更する

httpd 用の haresources 作成

server1 のみで作業すればよい

server1.localdomain IPaddr2::192.168.1.5/24/eth0/192.168.1.255 drbddisk::r0 Filesystem::/dev/drbd0::/var/www httpd

haresources から cib.xml 作成

# /usr/lib/heartbeat/haresources2cib.py --stdout haresources > /tmp/cib.xml
# vi /tmp/cib.xml

nic と cidr_netmask の value を入れ替える (eth0 <-> 24)

# crm_verify -x /tmp/cib.xml
# cibadmin -R -o resources -x /tmp/cib.xml

これで httpd が起動される。

どちらのサーバが停止しても、仮想 IP の Web サーバに接続できるようになった!

上記リンク以外で参考にした情報。

Linux Journal Sep. 2006 p.p.66-70 "DRBD in a Heartbeat", PEDRO PLA
DRBD in a Heartbeat | Linux Journal
古い記事だが、今でも参考になる。sendmail冗長化について書かれている。
複数のサービスを冗長化できるように、DRBD のマウントポイントを変える方法でなく、シンボリックリンクを使った方法をとっている。
Heartbeat の設定ファイルの構成が違っているので注意が必要。

http://centossrv.com/heartbeat-drbd.shtml

  • Web+DB PRESS vol.39 "スケーラブル Web システム工房"

DRBD と keepalived を組み合わせて VRRP を使う冗長化構成について紹介されています。
紹介記事では省略されがちな protocol や on-io-error などの説明もされていて参考になりました。

DRBD と Heartbet の構成について説明されている。DRBD 0.7 での説明がメインだが、DRBD 0.8 で GFS2 を使った Primary-Primary 構成も紹介されている。

DRBD と Heartbet の構成について説明されている。スプリットブレインを意識した設定の説明が参考になった。



Heartbeat の STONITH (Shoot The Other Node In The Head) や、DRBD でスプリットブレインが発生した場合の対処方法など、雑誌記事では扱われていない内容についても触れられている。



Linuxで作るアドバンストシステム構築ガイド』の旧版にあたる。
Linuxで作るアドバンストシステム構築ガイド』で省かれた内容もあるので、あわせて読むとよい。


内容が薄いので、最初の一冊としてはあまり適さない。

その他のリソース。
http://www.drbd.jp/index.html
Linux-HA Japan



サーバが自律的に協調動作するのは、眺めているだけで楽しいものですな。