DRBD+heartbeat+LVM(on Fedora Core10)によるクラスタリング
こんにちは、亀本です。
今回は、PHPとかから少し離れて、サーバのクラスタリングのお話です。
ちょっと仕事で冗長化システムを組む必要があったので、せっかくなので記事にまとめました。
さて、ここで目指すのは、DRBDを使ったデータ レプリケーションサーバ( Master / Slave 構成 )の自動フェイルオーバークラスタ( 非フェイルバック構成 )です。
ネットワーク構成としては、ルータから結ばれるLAN(eth0に接続)とは別に、eth1で1対1のLAN接続を行います。
また、heartbeatでのクラスタ構成後は、eth0に仮想IPとして192.168.1.100を割り振るようにします。
eth1の設定は、
# vi /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
HWADDR=00:00:00:00:00:00
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.50.1
NETMASK=255.255.255.0
のような感じになります。
また、他にもheartbeat用にttyS0 (RS-232Cのシリアル) をクロスで結んでいます。
こちらは特に設定の必要はありませんし、付けなくてもシステムは組めます。
1. サーバ構築時のパーティション設定
ハードディスク構成は、Hardware RAID 1+0 ベースの1 Logical Drive でやってます。
作成するパーティション構成としては、最終的に
○物理レイヤ
/dev/cciss/c0d0
c0d0p0 LVM Volume
c0d0p1 /boot # ブートローダ
○LVM
/dev/LVMVol1/lv_root /
/dev/LVMVol1/lv_var /var # なんとなく分けた。このあたりはご自由に。。
/dev/LVMVol1/lv_data /data # drbdによるレプリケーション対象ドライブ。あとから/dev/drbd0でラッピングされます。
/dev/LVMVol1/lv_meta (none) # drbdのmetaデータ格納用ドライブ
という構成を目指します。LVMVol1がLVMのボリュームグループ名、lv_rootなどはLV名です。
この構成を作成するにあたり、OSのインストール時に注意すべき事として、lv_metaに相当するmetaデータ用パーティションの取り扱いがあります。
この領域は、DRBDがメタデータを作成する際に独自ファイルシステムを作成しようとするので、OS側でフォーマットされてしまっているとエラーが発生する事があります。
なので、OSインストール時には作成せず、領域だけ残すようにして、root,var,data領域を作成しましょう。
また、後々サーバ名も必要になるので、localhost.localdomainなどではなく、ちゃんとしたサーバ名をつけておくようにしてください。
なお、もし構築済みのサーバでLVM領域をめいっぱい使いきってしまっ ている場合には、LVM領域の変更をする必要があります。
その方法についても、あとで少しふれておきます。
2. DRBDのインストール
ここでは、最小構成(Base + Vimぐらい) でインストールした前提で話を進めます。
なお、yumの設定やyum updateはやってある前提です。
2.1 コンパイルに必要なツールの準備
Fedora CoreではDRBDのrpmパッケージは用意されておらず、自前でコンパイルする必要があります。
そのため、まずDRBDのrpm作成に必要なツール類をインストールします。
# yum install make gcc glibc flex rpm-build
自分の環境ではmake,glibcは入っていたので、gcc、flex、rpm-buildとその関連パッケージがインストールされました。
また、DRBDのコンパイルにはカーネルのソース等も必要になるので、それらも入手しておきます。
# yum install kernel-devel
# yumdownloader --source kernel
# rpm -ivh kernel-2.6.27.29-170.2.78.fc10.src.rpm
rpmのインストールではユーザ/グループのwornが出ますが気にしなくて大丈夫です。
2.2 DRBDのコンパイルとインストール
次に、DRBDのソースを取得してきて、DRBDをコンパイルします。
DRBDのソースは、http://oss.linbit.com/drbd/ からダウンロードできます。
# wget http://oss.linbit.com/drbd/8.3/drbd-8.3.2.tar.gz
あとは、以下のようにソー スを展開してmakeすれば、rpmの作成まで一括でやってくれます。
# tar xvzf drbd-8.3.2.tar.gz
# cd drbd-8.3.2
# make rpm
make終了後に以下のように作成したrpmの一覧が出れば成功です。
You have now:
-rw-r--r-- 1 root root 220334 2009-08-14 02:09 dist/RPMS/x86_64/drbd-8.3.2-3.x86_64.rpm
-rw-r--r-- 1 root root 1079065 2009-08-14 02:09 dist/RPMS/x86_64/drbd-km-2.6.27.29_170.2.78.fc10.x86_64-8.3.2-3.x86_64.rpm
あとは、このrpmを展開すれば、インストールは完了です。
# cd dist/RPMS/x86_64/
# rpm -ivh *.rpm
2.3 DRBDインストール後の注意点
DRBDは、カーネルモジュール作成時にカーネルのソースを利用しているため、カーネルのバージョンが変わってしまうと動かなくなってしまう場合があります。
そのため、カーネルのバージョンアップがかかるようなア ップデートをかける場合には、DRBDの再構築も忘れずに行うようにしてください。
cronでyum のアップデートを行うように設定している場合は、アップデート対象からkernelを除外しておくなどの対応をしておき、kernelのメンテナンスだけは手動で行うようにするとよいでしょう。
# vi /etc/yum.conf
exclude=kernel*
3. DRBDのセットアップ
続けて、DRBDを動作させるためのセットアップを行っていきます。
3.1 DRBDのmetaデータについて
DRBDは、実際に共有されるデータ以外にも、変更データ管理用のmetaデータを作成しますが、そのmetaデータの管理方法には「データ領 域に含める(internal)」「外部領域を利用する(external)」の2種類の方法が用意されています。
どちらが良いのか、というのは一概には言えないようなのですが、internalでやり方を書いてあるものは多くてもexternalでやっているドキュメントがあまり見当たらなかったので、今回は外部領域を利用する方法を紹介します。
3.2 metaデータ用LVの作成
まずはmetaデータを格納する領域を確保します。
どのくらい領域が余っているかは、以下のようにして確認できます。
# vgdisplay |grep Free
Free PE / Size 209 / 6.53 GB
自分の環境では、端数を残しておいたらこのくらいになりましたが、metaデータにはさすがにちょっと6Gは多い気もしますね。まぁ今回はこれで行きます。
次のようにして、LVを作成します。
# lvcreate -l 209 -n lv_meta LVMVol1
Logical volume "lv_meta" created
容量をバイトサイズで指定したい場合には、-l 209の代わりに -L 6G などと指定してあげればOKです。
3.3 領域を使いきっていた場合
OSインストール時に領域を残してあれば上記の操作だけで大丈夫ですが、LVMの領域を使いきっていた場合には、何かしらのLVをリサイズして縮小し、使用領域を確保する必要があります。
/dev/LVMVol1/lv_data (ext3)を縮小する場合には
# lvdisplay -C |grep lv_data
lv_data LVMVol1 -wi-ao 292.97G
# umount /data
# resize2fs /dev/LVMVol1/lv_data 290G
# lvreduce -L 290G /dev/LVMVol1/lv_data
# mount /data
とします。なお、リサイズに伴ってデータが欠損する危険はついて回りますので、そこは自己責任でお願いします。
(よほど使いこんでいなければ、大丈夫そうですが。。。)
これで、2Gちょっとぐらいの領域が新たに確保できるようになるので、あとは3.2で紹介した方法でmetaデータ用のLVを作ってください。
3.4 drbd.confの設定
ここまででmetaデータ用の領域が確保できたので、続けてDRBDの設定drbd.confを以下のように作成しましょう。
# vi /etc/drbd.conf
resource r0 {
protocol B;
handlers {
pri-on-incon-degr "halt -f";
}
startup {
wfc-timeout 120;
degr-wfc-timeout 120;
}
syncer {
rate 100M;
}
disk {
on-io-error detach;
}
net {
cram-hmac-alg "sha1";
shared-secret "HogeHoge";
after-sb-0pri disconnect;
after-sb-1pri disconnect;
after-sb-2pri disconnect;
rr-conflict disconnect;
}
on db1.example.com {
device /dev/drbd0;
disk /dev/LVMVol1/lv_data;
address 192.168.50.1:7788;
flexible-meta-disk /dev/LVMVol1/lv_meta;
}
on db2.example.com {
device /dev/drbd0;
disk /dev/LVMVol1/lv_data;
address 192.168.50.2:7788;
flexible-meta-disk /dev/LVMVol1/lv_meta;
}
}
各項目の細かい説明は、man drbd.confや 邦訳( http://www.drbd.jp/documentation/drbd.conf.html )を参照してください。
ここでは、環境に合わせて必ず変更が必要な on句の説明をしておきます。
まず、on db1.example.com となっているonの後の名前は、uname -nで出てくる各サーバのホスト名である必要があります。それぞれの対象サーバで設定を行いましょう。
また、addressではそれぞれのサーバのIP、およびDRBDの通信に使うポート番号を指定します。
次にdiskとdeviceですが、diskが実際にDRBDが書き込みを行うデバイス本体で、deviceがDRBDのデバイス名です。
この設定では、/dev/drbd0というデバイスに対しての書き込みが、DRBDを経由してそれぞれのサーバの/dev/LVMVol1/lv_dataに書き込まれることになります。
こう設定すると、lv_dataデバイスはDRBDの支配下に置かれることになります。
そのため、今までlv_dataをマウントしていた/dataディレクトリは今後/dev/drbd0をマウントするようにシステムの設定を変更する必要があります。
最後に、flexible-meta-diskですが、これが先ほど作ったメタデータ格納用のデータ領域の指定です。
3.5 DRBDボリュームの作成
以上でdrbd.confの設定が終わったので、実際にDRBDのリソースを作成します。
# drbdadm create-md r0
md_offset 0
al_offset 4096
bm_offset 36864
Found some data
==> This might destroy existing data! <==
Do you want to proceed?
[need to type 'yes' to confirm]
ここで、yesとタイプして進めれば、metaデータの作成が完了し、DRBDを起動する準備が整います。
なお、create-mdの後に指定しているのはresourceの後ろに書いたリソース名で、この名前は自由に変えられます。
3.6 internalでやる場合の注意
metaデータ領域をinternalにする場合には、flexible-meta-diskの指定を[ internal ]変更する事で可能です。
共有対象となる領域内(今回で言えば/dev/LVMVol1/lv_data)にmetaデータを保存する領域を作成するので、この領域が何かしらのFileSystemでフォーマットされていると、こちらのFAQで参照できるようなエラーに当たる事があります。
その場合はFAQにしたがい、ボリュームを作り直すなりしてトライしてみてください。
4 DRBDの起動と同期
これまでの作業を、2台のサーバで設定し終えたら、DRBDの起動準備が整います。
あとは、DRBDを起動して同期作業を行いましょう。
4.1 モジュールのロード
まずは、DRBDのカーネルモジュールをロードします。
# modprobe drbd
以下のようになればOKです。
# lsmod|grep drbd
drbd 225992 0
4.2 DRBDの起動
いよいよDRBDの起動です。以下のようにして、起動させてください。
# /etc/init.d/drbd start
2台のサーバのうち、最初に起動したサーバの方では以下のような警告が出ますので、yesとタイプして先に進み、もう1台も起動してください。
Starting DRBD resources: [ d(r0) s(r0) n(r0) ]..........
***************************************************************
DRBD's startup script waits for the peer node(s) to appear.
- In case this node was already a degraded cluster before the
reboot the timeout is 120 seconds. [degr-wfc-timeout]
- If the peer was available before the reboot the timeout will
expire after 120 seconds. [wfc-timeout]
(These values are for resource 'r0'; 0 sec -> wait forever)
To abort waiting enter 'yes' [ 52]:yes
各サーバのDRBDを起動したら、以下のようにして状態を確認してみましょう。
# cat /proc/drbd
version: 8.3.2 (api:88/proto:86-90)
GIT-hash: dd7985327f146f33b86d4bff5ca8c94234ce840e build by root@db1.example.com, 2009-08-14 02:09:08
0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent B r----
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:307200000
となり、cs:Connected ro:Secondary/Secondary と、両方ともセカンダリで接続されているのが分かります。
この状態ではまだ、/dev/drbd0はマウントする事ができません。
4.3 プライマリの設定とデータ同期
では、1台をプライマリに昇格し、/dev/drbd0をマウントしてデータ同期できるようにしましょう。
プライマリにしたいサーバで、以下のコマンドを実行します。
# drbdadm -- --overwrite-data-of-peer primary r0
これで、実行した側のサーバがプライマリに切り替わり、同時にデータの同期が開始されます。
セカンダリ側では何もする必要はありません。
初回同期の際には、差分の同期ではなく全データの完全同期が行われます。
その様子も、/proc/drbd をみる事で把握する事が出来ます。
# cat /proc/drbd
version: 8.3.2 (api:88/proto:86-90)
GIT-hash: dd7985327f146f33b86d4bff5ca8c94234ce840e build by root@db1.example.com, 2009-08-14 02:09:08
0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent B r----
ns:8887460 nr:0 dw:0 dr:8888236 al:0 bm:542 lo:1710 pe:31 ua:1886 ap:0 ep:1 wo:b oos:298312664
[>....................] sync'ed: 2.9% (291320/300000)M
finish: 0:38:00 speed: 130,412 (80,064) K/sec
この同期が100%になれば、晴れてDRBDのレプリケーションが完成です。
4.4 DRBDボリュームのマウントと 設定変更
この時点で、プライマリ側では/dev/drbd0を利用する事が出来るようになり、書き込んだ内容はすべて同期されるようになります。
# mount -t ext3 /dev/drbd0 /data/
さて、これでDRBDは使えるようになりましたが、最後にrebootなどした際に謝ってlv_dataが/dataにマウントされてしまわないよう、fstabを変更して、以下のようにlv_dataの項目をコメントアウトしておきます。
# vi /etc/fstab
/dev/LVMVol1/lv_root / ext3 defaults 1 1
#/dev/LVMVol1/lv_data /data ext3 defaults 1 2
/dev/LVMVol1/lv_var /var ext3 defaults 1 2
.
.
.
これで、誤ってlv_dataがマウントされてしまう事もなくなります。
なお、今回は最終的にheartbeatがDRBDの面倒を見ることになるので、ここではfstabに新しい設定などは加えていませんが、自分でマウントする場合などは
/dev/drbd0 /data ext3 defaults 1 0
のような設定を追加しておくと便利でしょう。
5. heartbeatのインストールとDRBD連携
DRBDの設置が完了したので、続けてheartbeatをインストールし、DRBDと連携させてみます。
5.1 インストール
Fedora Core 10では、heartbeatはyumでインストール可能です。
# yum install heartbeat
以上でインストール完了です。
5.2 設定とDRBD連動
では、これを2台のサーバで連動するように、設定します。
heartbeatの動作には、/etc/ha.d/ディレクトリの中に、
・authkeys
・ha.cf
・haresources
の3つを作成する必要があります。
多くの設定項目がありますが、付属のサンプルがあるのでこれをコピーして使うとよいでしょう。
# cp /usr/share/doc/heartbeat-2.1.3/authkeys /etc/ha.d/
# cp /usr/share/doc/heartbeat-2.1.3/ha.cf /etc/ha.d/
# cp /usr/share/doc/heartbeat-2.1.3/haresources /etc/ha.d/
これらを順に設定して行きます。
まず、authkeysは、以下の2行をコメントアウト解除します。
# vi /etc/ha.d/authkeys
auth 1
1 crc
また、パーミッションも次のように変更しておく必要があります。
# chmod 600 /etc/ha.d/authkeys
次にha.dは、以下のように項目を設定して行きます。
ほとんどがコメントアウトを解除するだけですが、一部値が違うものは変更してください。
# vi /etc/ha.d/ha.cf
keepalive 2
deadtime 30
warntime 10
initdead 120
udpport 694
baud 19200
serial /dev/ttyS0
ucast eth1 192.168.50.2
auto_failback off
node db1.example.com
node db2.example.com
ここで、ucastはeth1から192.168.50.2に向けてユニキャストでheartbeatの確認をする、という意味の設定で、192.168.50.2に該当するサーバでは
ucast eth1 192.168.50.1
のような設定になります。
また、node はheartbeatの対象となるサーバの、uname で取得できるサーバ名を設定します。
なお、baudとserialはシリアルケーブル用の設定なので、シリアルケーブルをつながない場合には必要ありません。
最後にharesourcesには、以下の1行を追加してください。
# vi /etc/ha.d/haresources
db1.example.com 192.168.1.100/24 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3
これらを設定したのに、heartbeatを再起動しましょう。(install時に自動的に起動しているので、再起動になります)
以上で、設定はす べて完了です。
heartbeatが正常にフェイルオーバーするかを確認するには、ifconfigやdfなどで設定情報を確認した後、現在プライマリとして動作しているサーバのheartbeatwをstopするなどして、セカンダリサーバがきちんと仮想IPを持ったり、/dataディレクトリに/dev/drbd0がマウントされていたりするかチェックすればよいでしょう。
また、stopしたheartbeatを再度startしても、自動フェイルバックせずにそのまま稼働し続けます。
だいぶ長くなってしまいましたが、これでベースシステムとしてのheartbeat + DRBD (+ LVM)の自動フェイルオーバークラスタの出来上がりです。
DRBD + heartbeatはちゃんと設定すると色々と細かい制御ができていい感じなので、ぜひぜひ活用していきたいですね。