アクティブ機のデータディスクが壊れたら遅滞なくフェイルオーバさせる方法

disk_crasher

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の動作状態に関する何らかの外部監視と組み合わせることをお勧めいたします。