DRBD*1による、分散ファイルシステムを構築してみる。DRBDはネットワーク経由のミラーリングシステムを提供する。
 これにより、2台のマシン間でデータをリアルタイムで同期でき、いつ、どちらがダウンしてもデータは無事となる。

 ここでは、NFSサーバをACT/STB構成で構築する。DRBD 8.0からは、ACT/ACT構成ができるようだが、自分の用途ではACT/STBで十分なのと、ファイルシステムの制限があるので使用しない。

システム要件

 以下の条件を満たすシステムを構築する。

インストール

 まずは、パッケージをインストール。

# apt-get install drbd8-utils heartbeat nfs-kernel-server

設定

デバイス

 設定ファイルは、以下のようになる。両マシンで同一の設定にするため、片方で設定をした後、もう片方にファイルコピーすることをおすすめする。

 関連コマンドのパーミッションを変える。

drbd1# chgrp haclient /sbin/drbdsetup
drbd1# chmod o-x /sbin/drbdsetup
drbd1# chmod u+s /sbin/drbdsetup
drbd1# chgrp haclient /sbin/drbdmeta
drbd1# chmod o-x /sbin/drbdmeta
drbd1# chmod u+s /sbin/drbdmeta
drbd2# chgrp haclient /sbin/drbdsetup
drbd2# chmod o-x /sbin/drbdsetup
drbd2# chmod u+s /sbin/drbdsetup
drbd2# chgrp haclient /sbin/drbdmeta
drbd2# chmod o-x /sbin/drbdmeta
drbd2# chmod u+s /sbin/drbdmeta

 続いて、両マシンで、DRBDの初期化、起動を行う。サービスの起動は、相手の起動を待つので、近い時間に実行する。

drbd1# drbdadm create-md r0
drbd2# drbdadm create-md r0
drbd1# /etc/init.d/drbd start
drbd2# /etc/init.d/drbd start

 この時点での、DRBDの状態は、以下のようになっている。この時点では、どちらもセカンダリで同期状態にはなっていない。

drbd1# cat /proc/drbd
version: 8.3.7 (api:88/proto:86-91)
srcversion: EE47D8BF18AC166BE219757
 0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C 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:1048308

 片方のマシンをプライマリにする。

drbd1# drbdsetup /dev/drbd0 primary -o

 この時点での、DRBDの状態は、以下のようになっている。

drbd1# cat /proc/drbd
version: 8.3.7 (api:88/proto:86-91)
srcversion: EE47D8BF18AC166BE219757
 0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----
    ns:66944 nr:0 dw:0 dr:67144 al:0 bm:4 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:981364
        [>...................] sync'ed:  6.7% (981364/1048308)K
        finish: 0:17:31 speed: 820 (640) K/sec

 裏では同期中だが、ファイルシステムを作成して、マウントする。

drbd1# mkfs.xfs /dev/drbd0
drbd1# mkdir /mnt/drbd0
drbd1# mount /dev/drbd0 /mnt/drbd0

 プライマリでファイルを作成し、プライマリとセカンダリを入れ替えて、ファイルが見えることを確認する。

drbd1# echo abcdefg > /mnt/drbd0/test
drbd1# umount /mnt/drbd0
drbd1# drbdadm secondary r0
drbd2# drbdadm primary r0
drbd2# mount /dev/drbd0 /mnt/drbd0
drbd2# cat /mnt/drbd0/test

クラスタ

 DRDBが動作してるふたつのマシン間で、それぞれを監視してシステムとしてのサービスを継続させるため、HeartBeatを使用する。
 以下のような設定ファイルを、新規に作成する。認証キーは適当に作成する。

 監視対象リソースの指定。仮想IPアドレスは192.168.0.201、DRBDはr0を監視、ファイルシステムは/dev/drbd0を監視(マウント)とする。

 監視対象指定を新形式(Version 2)に変換。

# /usr/lib/heartbeat/haresources2cib.py

 認証キー。sha1、md5のいずれかを選択する。

 認証キーのパーミッションを変更。

drbd1# chmod go-r /etc/ha.d/authkeys

 以上で設定は完了したので、先ほど編集した3つのファイルをもう片方にコピーして、heartbeatを両ノードで起動する。

drbd1# scp -p /etc/ha.d/ha.cf drbd2:/etc/ha.d/
drbd1# scp -p /etc/ha.d/haresources drbd2:/etc/ha.d/
drbd1# scp -p /etc/ha.d/authkeys drbd2:/etc/ha.d/
drbd1# /usr/lib/heartbeat/haresources2cib.py
drbd2# /usr/lib/heartbeat/haresources2cib.py
drbd1# /etc/init.d/heartbeat start
drbd2# /etc/init.d/heartbeat start

 起動状態を見てみる。

drbd1# crm_mon -1
Your configuration was internally updated to the latest version (pacemaker-1.0)
============
Last updated: Sun Apr 24 17:54:39 2011
Stack: Heartbeat
Current DC: drbd1 (a427ae8e-5212-4ab3-be28-f195975d4119) - partition with quorum
Version: 1.0.9-74392a28b7f31d7ddc86689598bd23114f58978b
2 Nodes configured, unknown expected votes
1 Resources configured.
============

Online: [ drbd1 drbd2 ]

 Resource Group: group_1
     IPaddr_192_168_0_201       (ocf::heartbeat:IPaddr):        Started drbd1
     drbddisk_2 (heartbeat:drbddisk):   Started drbd1
     Filesystem_3       (ocf::heartbeat:Filesystem):    Started drbd1

 マスター側でheartbeatを停止させて、フェイルオーバーすることを確認。さらに、マスター側が復帰したときにフェイルバックすることも確認。

drbd1# ls -l /mnt/drbd0/
drbd1# /etc/init.d/heartbeat stop
drbd2# ls -l /mnt/drbd0/
drbd1# /etc/init.d/heartbeat start
drbd1# ls -l /mnt/drbd0/

クラスタ起動時にコマンド実行

 クラスタが起動したときに、自分で指定した特定のコマンドを実行してみる。
 クラスタと連動するコマンドの種類はいくつかあり、ここではLSBをつかう。この場合、コマンドは"/etc/init.d/"配下に置く必要がある。
 ここでは、"/etc/init.d/haupcmd"のコマンドにする。このコマンドには、start,stop,restart,reload,force-reload,statusを用意しておくらしいが、start,stop,statusしか実際に受け取ったのは確認できていない。startは起動時、stopは停止時、statusは定期的にチェック(後述)するときに実行された。
 コマンドが用意できたら、crmで指定する。configureから、以下のように登録したあと、グループの最後に追加する。

primitive haupcmd lsb:haupcmd

 このとき、以下のように引数を追加すれば、指定した間隔でstatusを引数に実行される。正常時は0、異常時は3の終了コードを返すと良い。

primitive haupcmd lsb:haupcmd op monitor interval="120s" timeout="60s"

 クラスタ内のすべてのノードにコマンドを追加した後、"commit"で反映。
 指定したコマンドが、startを引数に実行されるはず。

NFS

 HeartBeatと連携するように設定する。
 NFS用のディレクトリを作成し、NFS情報を保存するディレクトリをDRBD上に移動する。

drbd1# /etc/init.d/nfs-kernel-server stop
drbd1# /etc/init.d/nfs-common stop
drbd2# /etc/init.d/nfs-kernel-server stop
drbd2# /etc/init.d/nfs-common stop
drbd1# mkdir /mnt/drbd0/nfsdata
drbd1# chown nobody:nogroup /mnt/drbd0/nfsdata
drbd1# mv /var/lib/nfs /mnt/drbd0/ver_lib_nfs
drbd1# ln -s /mnt/drbd0/ver_lib_nfs /var/lib/nfs
drbd2# rm -r /var/lib/nfs
drbd2# ln -s /mnt/drbd0/ver_lib_nfs /var/lib/nfs

 続いて、クラスタ設定にNFSを追加する。

drbd1# rm /var/lib/heartbeat/crm/cib.xml*
drbd1# /usr/lib/heartbeat/haresources2cib.py
drbd1# scp -p /etc/ha.d/haresources drbd2:/etc/ha.d
drbd2# rm /var/lib/heartbeat/crm/cib.xml*
drbd2# /usr/lib/heartbeat/haresources2cib.py

 さらに、NFSサービスの自動起動を止める。HeartBeatがデーモンを管理するため。

drbd1# update-rc.d nfs-kernel-server remove
drbd1# update-rc.d nfs-common remove
drbd2# update-rc.d nfs-kernel-server remove
drbd2# update-rc.d nfs-common remove

 最後に、方ノードのHeartBeatを落として、正常に切り替わることを確認して完了。

 ノードを切り替えて書き込みができるようになるまで1分40秒程度かかるが、データのロストはなかった。

iSCSI

 iSCSIもHeartBeatと連携するように設定する。
 iSCSIの監視は、有効ノード側がiSCSIターゲットにリソースを追加する方式なので、/etc/ha.d/haresources への記述はしない。紛らわしいので、このファイルは中身を空にしておく。
 crmコマンドを使って、/var/lib/heartbeat/crm/cib.xml を更新する。マスタ側で実行すれば、設定も同期される。

# crm
crm(live)# configure
crm(live)configure# primitive iSCSI_Target ocf:heartbeat:iSCSITarget params implementation="iet" iqn="iqn.2001-04.com.example:storage.disk2.sys1.xyz" tid="1" op monitor interval="10s"
crm(live)configure# primitive iSCSI_Target_LUN0 ocf:heartbeat:iSCSILogicalUnit params implementation="iet" target_iqn="iqn.2001-04.com.example:storage.disk2.sys1.xyz" lun="0" path="/dev/drbd2" op monitor interval="10s"
crm(live)configure# edit
crm(live)configure# commit

 editコマンドでは、起動順番を指定するため、"group"の行を以下のように変更する。

group group_1 drbddisk_1 Filesystem_2 nfs-kernel-server_3 iSCSI_Target iSCSI_Target_LUN0 IPaddr_192_168_0_201

 crmで、アップグレードしろと怒られる場合は、以下のコマンドを実行する。

# cibadmin --upgrade --force

 debian squeezeの場合、シャットダウン時のサービス終了順が、iscsitargetの後にheartbeatなので、順番を変える。こうしないと、iSCSIがうまく切り替えれない。

 定を有効にするため、update-rc.dを実行する。

# update-rc.d heartbeat remove
# update-rc.d heartbeat defaults

運用

コマンド集

 運用中に、動作状況を確認するコマンドをあげる。

HeartBeatの動作状況(リアルタイム)crm_mon
HeartBeatの動作状況(現在状態)crm_mon -1
DRBDの状態/etc/init.d/drbd status
NFSサーバの公開状態exportfs -v
NFSサーバのマウント情報showmount -a

スプリットブレインからの回復

 ネットワークから切り離された場合など、両ノードでアクティブになったときに整合性がとれなくなる可能性がある。その場合は、手動で回復させる*2
 drbd1をマスタにして、drbd2に同期させる(drbd2のデータは消える)場合は、以下のように行う。

drbd2# drbdadm secondary r0
drbd2# drbdadm -- --discard-my-data connect r0
debd1# drbdadm connect r0

 以下のようなエラーになった場合、

drbd2# drbdadm -- --discard-my-data connect r0
0: Failure: (125) Device has a net-config (use disconnect first)

 次のようにする。

drbd2# drbdadm disconnect r0
drbd2# drbdadm -- --discard-my-data connect r0

ノード障害からの回復

 パッケージなどをインストールした後、/etc/drbd.d/sdb1.resをコピーし、drbdadm create-md r0を実行後、DRBDを起動するだけ。すぐに同期が始まる。

はまったこと

dopdがうまく動作しない

 スプリットブレインになるのをなるべく減らすため、dopdを使おうとしたが、どうもうまく動かない。
 outdate-peerの動作を見ると、環境変数DRBD_PEERに対向ホスト名が設定されると書いてある。ということは、設定ファイルに対向ホスト名の情報が必要だと言うこと。つまり、floatingでのIPアドレスのみの指定では、ホスト名がわからないのでだめと言うことに。
 on xxxx でホスト名を指定する方法にするとうまく動作した。

参考


*1 Distributed Replicated Block Device
*2 設定により、条件付きで自動回復も可能。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2012-06-19 (火) 17:30:43 (2680d)