アクティブ機のデータディスクが壊れたら遅滞なくフェイルオーバさせる方法
DRBDでディスク故障を検出する方法
DRBDを使ったクラスタシステムは、2台のサーバに同一データが同時に保存されるため、ディスクが故障してもデータを失わないというメリットがあります (シェアードナッシングと呼びます)。もしディスクが故障してもサービスは継続可能ですが、しかしアクティブ機側のディスクが壊れたことに気づかないまま運用を続けていくわけにはいきません。
DRBDとPacemakerの設定を調整すると、アクティブ機側のディスクが故障したら自動的にフェイルオーバして管理者にメール通知するというアクションを自動化することができます。
以下に、アクティブ側データディスク故障時の自動フェイルオーバを実現するための設定を紹介します。
DRBDとPacemakerの合わせ技
必要な設定の要点は、以下の3つだけです。
- DRBDのon-io-errorをdetachにする
- まず、drbd.confのdiskセクションにあるon-io-errorパラメータ の値をdetachに設定します。この値を指定しておくと、DRBDが管理しているディスクが壊れたときにDRBDはそのディスクを切り離します。ネットワーク接続は持続するので、プライマリ側ディスクが壊れた場合、すべてのディスクI/Oの対象はセカンダリ側のディスクになります。
- Pacemakerのdefault-resource-stickinessを200にする
- ここがもっとも大切なポイントです。Pacemakerのdefault-resource-stickinessプロパティは、INFINITYを設定している方が多いですが、今回の目的を達成するには200にしてください。INFINITYのままでは自動フェイルオーバが起こりません。
- MailToリソースエージェントを追加する
- DRBDならびにPacemakerは、フェイルオーバ発生時にログに記録を残しますが、メールなどで通知してくれません。クラスタ設定の中にMailToリソースエージェントを追加しておくと、フェイルオーバが起きたときにメールを自動送信できるようになります。
なぜdefault-resource-stickiness=INFINITYではいけないのか
default-resource-stickinessは、「動作しているリソースとそのリソースが動作しているノードの結びつきの強さ」を示すスコアです。これをINFINITYに設定してしまうと、アクティブ機上で動作しているリソースは、ノード自体のダウンやオペレータによる切り替え操作以外の要因でフェイルオーバしなくなってしまいます。もちろん、この動き自体に問題はありませんが、効果が強すぎます。
drbdリソースエージェント(drbd RA)は、モニタを行うタイミングで「プライマリになるべきスコア」をPacemakerに伝えます。Pacemakerはこの値を考慮してリソースの配置を決定します。ここで、default-resource-stickinessがINFINITYになっていると、プライマリになるべきスコア値は「INTINITY+値=プライマリ」という Pacemakerの判断ルールにおいて無意味になってしまいます。200を設定すると、drbd RAが返した値もプライマリの位置決めに反映されるようになります。
設定例と動作確認方法
DRBDを使ったHAクラスタシステムがあれば、紹介した設定の効果をただちに確認できます。動作確認に使った環境の設定例を示しますので、ご参考ください。もちろんホスト名、IPアドレス、デバイス名などは適宜置き換えてください。
drbd.conf
DRBDバージョン8.3用の設定になっています。8.4用構文になっていませんが、(互換性があるので)8.4でもこのままで動くはずです。最低限のパラメータしか指定していません。on-io-error detach; がキーポイントです。
global { usage-count no; } resource r0 { protocol C; syncer { rate 20M; } disk { on-io-error detach; } device /dev/drbd0; disk /dev/vg/lv01; on cluster1 { address 10.0.0.3:7788; meta-disk internal; } on cluster2 { address 10.0.0.4:7788; meta-disk internal; } }
Pacemaker設定
WebサーバのHAクラスタを想定しています。もっとシンプルにしたければ、apache、Filesystem、IPaddr2などを省略してもいいと思います。ここでのポイントは、default-resource-stickiness="200" とMailToリソースエージェントの活用です。なおHeartbeatのためのha.cfは省略します。
property default-resource-stickiness="200" \ no-quorum-policy="ignore" \ stonith-enabled="false" primitive alert ocf:heartbeat:MailTo \ params email="root" subject="alert from webserver cluster" \ op start interval="0" timeout="20" \ op stop interval="0" timeout="20" primitive drbd_r0 ocf:linbit:drbd \ params drbd_resource="r0" \ op monitor interval="20" role="Slave" timeout="40" \ op monitor interval="10" role="Master" timeout="40" \ op start interval="0" timeout="240" \ op stop interval="0" timeout="100" primitive httpd ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op start interval="0" timeout="60" \ op stop interval="0" timeout="90" \ op monitor interval="20" timeout="30" primitive mount ocf:heartbeat:Filesystem \ params device="/dev/drbd0" fstype="ext4" directory="/h" options="noatime" \ op monitor interval="10" timeout="60" \ op start interval="0" timeout="60" \ op stop interval="0" timeout="60" primitive vip ocf:heartbeat:IPaddr2 \ params ip="10.30.101.6" cidr_netmask="16" \ op monitor interval="30" timeout="60" group webserver alert vip mount httpd ms ms_drbd_r0 drbd_r0 \ meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" location loc_webserver webserver 100: cluster1 colocation col_drbd_webserver inf: webserver ms_drbd_r0:Master order ord_drbd_webserver inf: ms_drbd_r0:promote webserver:start
クラスタの起動
cluster1とcluster2の両サーバでheartbeatを起動すると、cluster1がアクティブ機となってクラスタが起動します。crm_monコマンドで動作状態を表示させると、以下のような動作状態が表示されます。
Online: [ cluster2 cluster1 ] Master/Slave Set: ms_drbd_r0 Masters: [ cluster1 ] Slaves: [ cluster2 ] Resource Group: webserver alert (ocf::heartbeat:MailTo): Started cluster1 vip (ocf::heartbeat:IPaddr2): Started cluster1 mount (ocf::heartbeat:Filesystem): Started cluster1 httpd (ocf::heartbeat:apache): Started cluster1
アクティブ機であるcluster1側でcat /proc/drbdを実行すると、以下のような動作状態が表示されます。
version: 8.3.1X (api:88/proto:86-97) GIT-hash: dc4c32498e9cbf35734c4716b65ddd6fbd6e1eb4 build by buildsystem@linbit, 2013-01-30 08:31:13 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----- ns:1 nr:77773 dw:77774 dr:686 al:19 bm:48 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
ローカルディスクの故障をシミュレートする方法
アクティブ機のローカルディスクが壊れた状況をシミュレートするには、cluster1側で次のコマンドを実行します。
drbdadm detach r0
cat /proc/drbdの実行結果は以下のように変化します。
0: cs:Connected ro:Primary/Secondary ds:Diskless/UpToDate C r-----
ds:フィールドの値が UpToDate/ から Diskless/ に変わっていればOKです。
フェイルオーバすることを確認
今回の設定では、drbd RAのモニタは10秒間隔で実行されるため、約10秒以内にフェイルオーバが始まるはずです。crm_monの表示が変化してcluster2が新たなアクティブ機になることを確認してください。また、通知メールがroot宛に送信されることもご確認ください。
元に戻す
drbdadm attach を実行すると、ディスクが故障した状態を元に戻せます。default-resource-stickiness=INFINITY に書き換えて同様にディスクを切り離し、フェイルオーバしないこともご確認ください。
まとめ
DRBDを使うと、2台のサーバのDRBDデータ領域が同時故障しない限り、データを完全に喪失することを避けられます。しかしながら、片方のディスクだけが故障した場合でも、できるだけ早くそのことを知って修理する必要があります。
drbd.confの on-io-error detach と Pacemaker の default-resource- stickiness=200 を組み合わせると、稼働系サーバのDRBDデータ領域の故障をPacemakerが検出できるようになります。そしてフェールオーバが起こり、パフォーマンス低下を避けられます。
さらにMailToリソースエージェントを組み込んでおくことによって、管理者は障害発生をメールで知ることができます。
ただし、待機系サーバのDRBDデータ領域が故障しても、フェールオーバは起こりません。したがって、実際のクラスタ運用にあたっては、DRBDの動作状態に関する何らかの外部監視と組み合わせることをお勧めいたします。