さて、今回は日本語メーリングリストでもお問い合わせのあった、
Master/Slave構成での変な動作について
その動作の詳細、次期バージョンでの修正動向、暫定対応などをご紹介します。
Pacemaker 1.0.11に含まれるバグ
Pacemaker 1.0.11でMaster/Slaveリソースとgroupリソースに
順序制約および同居制約を設定した場合
groupリソースに含まれるリソース故障を契機にした
Master/Slaveリソースのフェイルオーバが失敗します。
日本語のメーリングリストにお問い合わせいただいた構成を簡略化した例で動作を説明します。
3つのDummyリソースをgroupにまとめて、そのgroupリソースとMaster/Slaveリソース(今回はDRBD)に
順序制約(order)、同居制約(colocation)が設定されています。
制約によって期待される動作は
– Master/Slaveリソースが起動したあとに、groupリソースが起動、
– Master/SlaveリソースのMasterが存在するノードでgroupリソースも起動、
となります。
ms-group.crm
### Cluster Option ###
property \
no-quorum-policy="ignore" \
stonith-enabled="false" \
startup-fencing="false" \
crmd-transition-delay="2s"
### Resource Defaults ###
rsc_defaults \
resource-stickiness="INFINITY" \
migration-threshold="1"
### MasterSlave Configuration ###
ms msDRBD \
prmDRBD \
meta \
master-max="1" \
master-node-max="1" \
clone-max="2" \
clone-node-max="1" \
notify="true"
### Group Configuration ###
group grpDRBD dummy01 dummy02 dummy03
### Primitive Configuration ###
primitive prmDRBD ocf:linbit:drbd \
params \
drbd_resource="r0" \
op start interval="0s" timeout="240s" on-fail="restart" \
op monitor interval="10s" timeout="20s" on-fail="restart" role="Master" \
op monitor interval="20s" timeout="20s" on-fail="restart" role="Slave" \
op promote interval="0s" timeout="90s" on-fail="restart" \
op demote interval="0s" timeout="90s" on-fail="block" \
op stop interval="0s" timeout="100s" on-fail="block"
primitive dummy01 ocf:pacemaker:Dummy \
op start interval="0s" timeout="120s" on-fail="restart" \
op monitor interval="10s" timeout="120s" on-fail="restart" \
op stop interval="0s" timeout="120s" on-fail="block"
primitive dummy02 ocf:pacemaker:Dummy \
op start interval="0s" timeout="120s" on-fail="restart" \
op monitor interval="10s" timeout="120s" on-fail="restart" \
op stop interval="0s" timeout="120s" on-fail="block"
primitive dummy03 ocf:pacemaker:Dummy \
op start interval="0s" timeout="120s" on-fail="restart" \
op monitor interval="10s" timeout="120s" on-fail="restart" \
op stop interval="0s" timeout="120s" on-fail="block"
### Resource Colocation ###
colocation rsc_colocation-1 inf: grpDRBD msDRBD:Master
### Resource Order ###
order rsc_order-1 0: msDRBD:promote grpDRBD:start
初期起動時の様子をcrm_monコマンドで確認します。
node01でMasterリソースとgroup(dummy01+dummy02+dummy03)が起動しています。
node02ではSlaveリソースが起動しています。
# crm_mon -1 -n -f
============
Last updated: Wed Nov 2 16:29:21 2011
Stack: Heartbeat
Current DC: node02 (22222222-2222-2222-2222-222222222222) - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, unknown expected votes
2 Resources configured.
============
Node node01 (11111111-1111-1111-1111-111111111111): online
dummy03 (ocf::pacemaker:Dummy) Started
dummy02 (ocf::pacemaker:Dummy) Started
dummy01 (ocf::pacemaker:Dummy) Started
prmDRBD:0 (ocf::linbit:drbd) Master
Node node02 (22222222-2222-2222-2222-222222222222): online
prmDRBD:1 (ocf::linbit:drbd) Slave
Migration summary:
* Node node01:
* Node node02:
さて、ここでgroupリソースに含まれる一番目のリソース(dummy01)を故障させてみましょう。
dummy01が故障したら、groupリソースも停止するはずですよね。
さらに、Masterリソースとgroupリソースには同居制約が設定されているのでMasterリソースとgroupリソースは
node02へフェイルオーバするはずです。
# crm resource failcount dummy01 set node01 1
だがしかし!
groupリソースは停止しましたが、Masterリソースはフェイルオーバせずにnode01に居残ってしまいました。
# crm_mon -1 -n -f
============
Last updated: Wed Nov 2 16:30:24 2011
Stack: Heartbeat
Current DC: node02 (22222222-2222-2222-2222-222222222222) - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, unknown expected votes
2 Resources configured.
============
Node node01 (11111111-1111-1111-1111-111111111111): online
prmDRBD:0 (ocf::linbit:drbd) Master
Node node02 (22222222-2222-2222-2222-222222222222): online
prmDRBD:1 (ocf::linbit:drbd) Slave
Migration summary:
* Node node01:
dummy01: migration-threshold=1 fail-count=1
* Node node02:
結論から言ってしまうと、この動作はバグなわけです。
ということで、ちょっと遷移グラフでも見てみますか。遷移グラフはDCノードに出力されています。
# ls -l /var/lib/pengine/
合計 32
-rw------- 1 hacluster haclient 611 11月 2 16:16 pe-input-0.bz2
-rw------- 1 hacluster haclient 741 11月 2 16:16 pe-input-1.bz2
-rw------- 1 hacluster haclient 747 11月 2 16:16 pe-input-2.bz2
-rw------- 1 hacluster haclient 1438 11月 2 16:29 pe-input-3.bz2
-rw------- 1 hacluster haclient 2055 11月 2 16:29 pe-input-4.bz2
-rw------- 1 hacluster haclient 2165 11月 2 16:29 pe-input-5.bz2
-rw------- 1 hacluster haclient 2424 11月 2 16:30 pe-input-6.bz2
-rw-r--r-- 1 hacluster haclient 1 11月 2 16:30 pe-input.last
DCノードのha-logを検索すると、次のようなメッセージが出力されています。
info: process_pe_message: Transition 6: PEngine Input stored in: /var/lib/pengine/pe-input-6.bz2
Master/Slaveリソースが変な感じで居残っちゃったあたりのログをみると、
どうやらそのへんの動作は遷移グラフ pe-input-6.bz2 に出力されている雰囲気。
ということで、遷移グラフの中身をのぞいてみましょう。
遷移グラフの解析にはptestというコマンドを使うのですが、ptestはcrmシェルから呼び出すこともできます。
# cd /var/lib/pengine/
# crm
crm(live)# cib import pe-input-6.bz2
crm(pe-input-6)# configure ptest vvv nograph
ptest[2343]: 2011/11/02_16:31:39 notice: unpack_config: On loss of CCM Quorum: Ignore
ptest[2343]: 2011/11/02_16:31:39 WARN: unpack_nodes: Blind faith: not fencing unseen nodes
ptest[2343]: 2011/11/02_16:31:39 notice: group_print: Resource Group: grpDRBD
ptest[2343]: 2011/11/02_16:31:39 notice: native_print: dummy01 (ocf::pacemaker:Dummy): Started node01
ptest[2343]: 2011/11/02_16:31:39 notice: native_print: dummy02 (ocf::pacemaker:Dummy): Started node01
ptest[2343]: 2011/11/02_16:31:39 notice: native_print: dummy03 (ocf::pacemaker:Dummy): Started node01
ptest[2343]: 2011/11/02_16:31:39 notice: clone_print: Master/Slave Set: msDRBD
ptest[2343]: 2011/11/02_16:31:39 notice: short_print: Masters: [ node01 ]
ptest[2343]: 2011/11/02_16:31:39 notice: short_print: Slaves: [ node02 ]
ptest[2343]: 2011/11/02_16:31:39 WARN: common_apply_stickiness: Forcing dummy01 away from node01 after 1 failures (max=1)
ptest[2343]: 2011/11/02_16:31:39 notice: LogActions: Stop resource dummy01 (node01)
ptest[2343]: 2011/11/02_16:31:39 notice: LogActions: Stop resource dummy02 (node01)
ptest[2343]: 2011/11/02_16:31:39 notice: LogActions: Stop resource dummy03 (node01)
ptest[2343]: 2011/11/02_16:31:39 notice: LogActions: Leave resource prmDRBD:0 (Master node01)
ptest[2343]: 2011/11/02_16:31:39 notice: LogActions: Leave resource prmDRBD:1 (Slave node02)
おーう。
なんかもりもりでてきました。
注目するべきは最後の2行。「Leave」とかいっちゃってるこのやる気のなさがもうイカンですね。
ホントはここで「Move」がでてほしかったところ。
というわけで、あんどりゅーくんに「こらアカン」と報告してみたところ
パッチがつくってくれました。そして、 @ksk_ha さんがPacemaker 1.0.12用のリポジトリにバックポートしてくれました。
このパッチでちゃんと期待通りの動作が得られるか試してみましょう。
とりあえず、Pacemaker 1.0.12のリポジトリから最新版のソースコードを持ってきます。
クラスタを作りこむのはめんどくさいので、makeだけしておきます。
# hg clone http://hg.clusterlabs.org/pacemaker/stable-1.0
# cd stable-1.0
# hg update -C stable-1.0
# ./autogen.sh
# ./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc --with-lcrso-dir=/usr/libexec/lcrso
# make
そして、新しいcrmシェルを探して…
# find . -name crm
./shell/crm
./include/crm
./.hg/store/data/crm
./.hg/store/data/include/crm
./.hg/store/data/lib/crm
./lib/crm
実行権限を追加します。
# cd ./shell/crm
# chmod +x crm
いよいよ、Pacemaker 1.0.12(もどき)でptestを実行!
# ./crm
crm(live)# cib import /tmp/pe-input-6.bz2
crm(pe-input-6)# configure ptest vvv nograph
ptest[19529]: 2011/11/02_17:09:29 notice: unpack_config: On loss of CCM Quorum: Ignore
ptest[19529]: 2011/11/02_17:09:29 WARN: unpack_nodes: Blind faith: not fencing unseen nodes
ptest[19529]: 2011/11/02_17:09:29 notice: group_print: Resource Group: grpDRBD
ptest[19529]: 2011/11/02_17:09:29 notice: native_print: dummy01 (ocf::pacemaker:Dummy): Started node01
ptest[19529]: 2011/11/02_17:09:29 notice: native_print: dummy02 (ocf::pacemaker:Dummy): Started node01
ptest[19529]: 2011/11/02_17:09:29 notice: native_print: dummy03 (ocf::pacemaker:Dummy): Started node01
ptest[19529]: 2011/11/02_17:09:29 notice: clone_print: Master/Slave Set: msDRBD
ptest[19529]: 2011/11/02_17:09:29 notice: short_print: Masters: [ node01 ]
ptest[19529]: 2011/11/02_17:09:29 notice: short_print: Slaves: [ node02 ]
ptest[19529]: 2011/11/02_17:09:29 WARN: common_apply_stickiness: Forcing dummy01 away from node01 after 1 failures (max=1)
ptest[19529]: 2011/11/02_17:09:29 notice: RecurringOp: Start recurring monitor (10s) for dummy01 on node02
ptest[19529]: 2011/11/02_17:09:29 notice: RecurringOp: Start recurring monitor (10s) for dummy02 on node02
ptest[19529]: 2011/11/02_17:09:29 notice: RecurringOp: Start recurring monitor (10s) for dummy03 on node02
ptest[19529]: 2011/11/02_17:09:29 notice: RecurringOp: Start recurring monitor (20s) for prmDRBD:0 on node01
ptest[19529]: 2011/11/02_17:09:29 notice: RecurringOp: Start recurring monitor (10s) for prmDRBD:1 on node02
ptest[19529]: 2011/11/02_17:09:29 notice: RecurringOp: Start recurring monitor (20s) for prmDRBD:0 on node01
ptest[19529]: 2011/11/02_17:09:29 notice: RecurringOp: Start recurring monitor (10s) for prmDRBD:1 on node02
ptest[19529]: 2011/11/02_17:09:29 notice: LogActions: Move resource dummy01 (Started node01 -> node02)
ptest[19529]: 2011/11/02_17:09:29 notice: LogActions: Move resource dummy02 (Started node01 -> node02)
ptest[19529]: 2011/11/02_17:09:29 notice: LogActions: Move resource dummy03 (Started node01 -> node02)
ptest[19529]: 2011/11/02_17:09:29 notice: LogActions: Demote prmDRBD:0 (Master -> Slave node01)
ptest[19529]: 2011/11/02_17:09:29 notice: LogActions: Promote prmDRBD:1 (Slave -> Master node02)
よっしゃ!キタコレ!
最後の5行、いい感じですよね!
まあなんかわかんないなりに、dummy01. dummy02. dummy03はnode01からnode02へ
移動(Move)しようとしているし、Master/Slaveリソースも期待通りにdemote/promoteが実行されるようです。
Pacemaker 1.0.12では、dummy01の故障で期待通りフェイルオーバが発生することがわかります。
ところで、Pacemaker 1.1系では、crm_simulateというコマンドも追加されています。
Pacemaker 1.0系へのバックポートはなかなか難しいようなので、今回は使用例だけ簡単に紹介しますが
将来的にcrm_simulateコマンドを使って解析したほうが便利になるかもしれません。
ちなみにPacemaker 1.1系の最新版はhgからGitHubへお引っ越ししました。
# git clone http://github.com/ClusterLabs/pacemaker
# cd pacemaker/
# ./autogen.sh
# ./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc --with-lcrso-dir=/usr/libexec/lcrso
# make
# find . -name crm_simulate
./tools/.libs/crm_simulate
./tools/crm_simulate
コマンドに喰わせるのは、さっきと同じ遷移グラフです。
# ./crm_simulate -S -x /tmp/pe-input-6.bz2
Current cluster status:
Online: [ node01 node02 ]
Resource Group: grpDRBD
dummy01 (ocf::pacemaker:Dummy): Started node01
dummy02 (ocf::pacemaker:Dummy): Started node01
dummy03 (ocf::pacemaker:Dummy): Started node01
Master/Slave Set: msDRBD [prmDRBD]
Masters: [ node01 ]
Slaves: [ node02 ]
Transition Summary:
crm_simulate[13819]: 2011/11/02_17:03:20 notice: LogActions: Move dummy01 (Started node01 -> node02)
crm_simulate[13819]: 2011/11/02_17:03:20 notice: LogActions: Move dummy02 (Started node01 -> node02)
crm_simulate[13819]: 2011/11/02_17:03:20 notice: LogActions: Move dummy03 (Started node01 -> node02)
crm_simulate[13819]: 2011/11/02_17:03:20 notice: LogActions: Demote prmDRBD:0 (Master -> Slave node01)
crm_simulate[13819]: 2011/11/02_17:03:20 notice: LogActions: Promote prmDRBD:1 (Slave -> Master node02)
Executing cluster transition:
* Executing action 16: dummy03_stop_0 on node01
* Executing action 4: prmDRBD:0_cancel_10000 on node01
* Executing action 5: prmDRBD:1_cancel_20000 on node02
* Executing action 13: dummy02_stop_0 on node01
* Executing action 71: prmDRBD:0_notify_0 on node01
* Executing action 73: prmDRBD:1_notify_0 on node02
* Executing action 10: dummy01_stop_0 on node01
* Executing action 25: prmDRBD:0_demote_0 on node01
* Executing action 72: prmDRBD:0_notify_0 on node01
* Executing action 74: prmDRBD:1_notify_0 on node02
* Executing action 67: prmDRBD:0_notify_0 on node01
* Executing action 69: prmDRBD:1_notify_0 on node02
* Executing action 30: prmDRBD:1_promote_0 on node02
* Executing action 68: prmDRBD:0_notify_0 on node01
* Executing action 70: prmDRBD:1_notify_0 on node02
* Executing action 11: dummy01_start_0 on node02
* Executing action 14: dummy02_start_0 on node02
* Executing action 17: dummy03_start_0 on node02
* Executing action 26: prmDRBD:0_monitor_20000 on node01
* Executing action 31: prmDRBD:1_monitor_10000 on node02
* Executing action 12: dummy01_monitor_10000 on node02
* Executing action 15: dummy02_monitor_10000 on node02
* Executing action 18: dummy03_monitor_10000 on node02
Revised cluster status:
Online: [ node01 node02 ]
Resource Group: grpDRBD
dummy01 (ocf::pacemaker:Dummy): Started node02
dummy02 (ocf::pacemaker:Dummy): Started node02
dummy03 (ocf::pacemaker:Dummy): Started node02
Master/Slave Set: msDRBD [prmDRBD]
Masters: [ node02 ]
Slaves: [ node01 ]
crm_simulateに-Vオプションを追加すると、さらに詳細なデバッグ情報を出力されます。
# ./crm_simulate -S -x /tmp/pe-input-6.bz2 -VVV
crm_simulateは、今回のようなレグレッションテストだけではなく、擬似故障の発生にも使用できます。
Pacemaker 1.0系では使えないコマンドなんですが、次期バージョンでとても楽しみな機能の一つです。