PacemakerのQuorumを試してみる

クラスタ管理の中核を担うPacemakerには、クラスタ全体の安定性とデータ整合性を維持するための重要な仕組みの一つとして「Quorum(過半数)」があります。Quorumは、クラスタ内でのノード数や状況に応じて、どのようにサービスを継続または停止するかを判断する役割を果たします。この機能を適切に設定し運用することで、障害発生時にもクラスタ全体が不要な分断やデータ不整合を回避できるようになります。
本記事では、Quorumの基本的な概念を解説するとともに、実際にPacemaker上で設定や動作を試してみる手順を詳しくご紹介します。クラスタシステムの信頼性を高めたいと考えている方にとって、Quorumの動作を理解し、効果的に運用できるようになることは非常に有益です。それでは、具体的な検証を進めながら、PacemakerのQuorumを深掘りしていきましょう!
構成
検証にはCorosyncとPacemakerのバージョンが、Corosync 3.1.0 、Pacemaker 2.0.5の環境を使いました。
※LINBITのデモライセンスを使うと、これが最新のバージョンになります。
仮想環境に3ノードのLinuxゲストOSを構築して、ホスト名とIPアドレスを次のようにします。
ホスト名 | IPアドレス1 | IPアドレス2 | IPアドレス3 |
node1 | 192.168.3.46 | 10.0.0.46 | 10.0.1.46 |
node2 | 192.168.3.47 | 10.0.0.47 | 10.0.1.47 |
node3 | 192.168.3.48 | 10.0.0.47 | 10.0.1.47 |
ネットワークの構成は下図のようになります。

Corosyncの設定
Corosyncは設定ファイル(/etc/corosync/corosync.conf)を定義して設定します。最低限の設定は次のようになります。
totem {
version: 2
cluster_name: cluster2
secauth: off
transport: knet
rrp_mode: passive
}
nodelist {
node {
name: node1
ring0_addr: 10.0.0.46
ring1_addr: 10.0.1.46
nodeid: 1
}
node {
name: node2
ring0_addr: 10.0.0.47
ring1_addr: 10.0.1.47
nodeid: 2
}
node {
name: node3
ring0_addr: 10.0.0.48
ring1_addr: 10.0.1.48
nodeid: 3
}
}
logging {
to_logfile: yes
logfile: /var/log/cluster/corosync.log
to_syslog: yes
}
quorum {
provider: corosync_votequorum
expected_votes: 3
}
Corosyncの設定はこちらのページで2ノード構成のCorosync ver 3.0の設定がありますので、比較してみて下さい。nodelist {}
にnode3
の設定が追加され、quorum {}
設定がexpected_votes: 3
に変わっているのが2ノード構成のポイントになります。
Corosyncの動作確認
設定が終わったら次のコマンドを実行してください。コマンドはnode1、node2、node3すべてのノードで実行します。
[root@node1 ~]# systemctl start corosync
Corosyncがちゃんと起動されたかはcorosync-cfgtool
で確認します。このように表示されれば問題ありません。
[root@node1 ~]# corosync-cfgtool -s
Printing link status.
Local node ID 1
LINK ID 0
addr = 10.0.0.46
status:
nodeid 1: localhost
nodeid 2: connected
nodeid 3: connected
LINK ID 1
addr = 10.0.1.46
status:
nodeid 1: localhost
nodeid 2: connected
nodeid 3: connected
nodeid2:、nodeid3がconnected
にならない場合は、node2、node3のCorosyncでエラーが発生していないか、ネットワークの設定が正しいか、ファイヤーウォールが疎通を邪魔していないか等を調べてみて下さい。
なお、以下の表示はnode2のcorosyncが停止している場合の表示例です。
[root@node1 ~]# corosync-cfgtool -s
Printing link status.
Local node ID 1
LINK ID 0
addr = 10.0.0.46
status:
nodeid 1: localhost
nodeid 2: disconnected
nodeid 3: connected
LINK ID 1
addr = 10.0.1.46
status:
nodeid 1: localhost
nodeid 2: disconnected
nodeid 3: connected
Pacemakerの起動と設定入力
systemctl
コマンドでPacemakerを起動します。
[root@node1 ~]# systemctl start pacemaker
このコマンドはnode1、node2、node3で実行します。なおPacemakerを起動すると自動的にCorosyncも起動するのですが、今回はCorosyncの動作確認のために、先にCorosyncを起動し動作確認するため別々に起動しています。
Pacemakerの関連プロセスが起動するので、psコマンドで確認してみて下さい。(fオプションをつけて実行します。)
[root@node1 ~]# ps axf
PID TTY STAT TIME COMMAND
2 ? S 0:00 [kthreadd]
4 ? S< 0:00 \_ [kworker/0:0H]
・・・・・・
8583 ? SLsl 0:09 /usr/sbin/corosync -f
8790 ? Ss 0:00 /usr/sbin/pacemakerd -f
8791 ? Ss 0:00 \_ /usr/libexec/pacemaker/pacemaker-based
8792 ? Ss 0:00 \_ /usr/libexec/pacemaker/pacemaker-fenced
8793 ? Ss 0:00 \_ /usr/libexec/pacemaker/pacemaker-execd
8794 ? Ss 0:00 \_ /usr/libexec/pacemaker/pacemaker-attrd
8795 ? Ss 0:00 \_ /usr/libexec/pacemaker/pacemaker-schedulerd
8796 ? Ss 0:00 \_ /usr/libexec/pacemaker/pacemaker-controld
また、crm_monでPacemakerの状態を確認すると、node1、node2、node3がOnlineになっていることが判ります。
[root@node1 ~]# crm_mon -frAD1
Cluster Summary:
* Stack: corosync
* Current DC: node1 (version 2.0.5.linbit-1.0.el7-ba59be712) - partition with quorum
* Last updated: Mon Jan 27 17:35:46 2025
* Last change: Mon Jan 27 17:35:42 2025 by hacluster via crmd on node1
* 3 nodes configured
* 0 resource instances configured
Node List:
* Online: [ node1 node2 node3 ]
Full List of Resources:
* No resources
Migration Summary:
3ノード構成のクラスタの動作を確認するため、Dummyリソースエージェントを使って
testリソースを定義します。crm configure edit
で次のように設定します。
node 1: node1
node 2: node2
node 3: node3
primitive test Dummy \
op start interval=0s timeout=30s \
op monitor interval=10s timeout=60s \
op stop interval=0s timeout=30s
property cib-bootstrap-options: \
stonith-enabled=false \
no-quorum-policy=stop \
have-watchdog=false \
cluster-infrastructure=corosync \
cluster-name=cluster2
node
情報やproperty
の情報は自動的に設定されるので、入力すべき情報は、primitive ~ timeout=30s
とstonith-enable=false
とno-quourum-poclicy=stop
になります。
設定を入力して保存すると、test
リソースが動き始めます。
[root@node1 ~]# crm_mon -frAD1
Cluster Summary:
* Stack: corosync
* Current DC: node1 (version 2.0.5.linbit-1.0.el7-ba59be712) - partition with quorum
* Last updated: Tue Jan 28 13:31:04 2025
* Last change: Mon Jan 27 17:59:24 2025 by hacluster via crmd on node1
* 3 nodes configured
* 1 resource instance configured
Node List:
* Online: [ node1 node2 node3 ]
Full List of Resources:
* test (ocf::heartbeat:Dummy): Started node1
Migration Summary:

test
リソースはnode1で起動してます。
Quorumのテスト
no-quorum-policy
の値で3ノードクラスタはどのように動作するかテストしてみます。
node1はeth1とeth2のネットワークI/Fでnode2、node3と通信しています。このネットワークをiptables
コマンドでふさぎ、node2、node3からnode1を隔離します。
node1で次のコマンドを実行します。
# eth1の通信を遮断
[root@node1 ~]# iptables -A INPUT -i eth1 -j DROP
[root@node1 ~]# iptables -A OUTPUT -o eth1 -j DROP
# eth2の通信を遮断
[root@node1 ~]# iptables -A INPUT -i eth2 -j DROP
[root@node1 ~]# iptables -A OUTPUT -o eth2 -j DROP
node1のeth1とeth2の通信が塞がれて、node2、node3と通信ができなくなります。

その結果node1のtest
リソースは停止して、node2にフェールオーバーします。これはno-quorum-policy
がstop
に設定されているからで、node1はクラスターメンバーが1台なのでノード数の過半数を下回ったので停止し、node2、node3のクラスターメンバーは2台なのでこちらでtest
リソースが起動しました。
node1でcrm_mon -frAD
を使ってでクラスターの状態を見ると次のようになります。
Cluster Summary:
* Stack: corosync
* Current DC: node1 (version 2.0.5.linbit-1.0.el7-ba59be712) - partition WITHO
UT quorum
* Last updated: Tue Jan 28 13:46:07 2025
* Last change: Mon Jan 27 17:58:54 2025 by root via cibadmin on node1
* 3 nodes configured
* 1 resource instance configured
Node List:
* Online: [ node1 ]
* OFFLINE: [ node2 node3 ]
Full List of Resources:
* test (ocf::heartbeat:Dummy): Stopped
Migration Summary:
node2でcrm_mon -frAD
を使ってクラスターの状態を見ると次のようになります。
Cluster Summary:
* Stack: corosync
* Current DC: node2 (version 2.0.5.linbit-1.0.el7-ba59be712) - partition with
quorum
* Last updated: Tue Jan 28 13:53:45 2025
* Last change: Mon Jan 27 17:59:24 2025 by hacluster via crmd on node1
* 3 nodes configured
* 1 resource instance configured
Node List:
* Online: [ node2 node3 ]
* OFFLINE: [ node1 ]
Full List of Resources:
* test (ocf::heartbeat:Dummy): Started node2
Migration Summary:

次にネットワークを元に戻して、node1へtest
リソースを戻します。
次のコマンドをnode1で実行してください。
[root@node1 ~]# iptables -D INPUT -i eth1 -j DROP
[root@node1 ~]# iptables -D OUTPUT -o eth1 -j DROP
[root@node1 ~]# iptables -D INPUT -i eth2 -j DROP
[root@node1 ~]# iptables -D OUTPUT -o eth2 -j DROP
[root@node1 ~]# crm resource move test node1
[root@node1 ~]# crm resource clear test
※crm resource move~
でリソースを移動した後には、必ずcrm resource clear~
を実行してください。
次にno-quorum-policy=ignore
を設定します。
[root@node1 ~]# crm configure property no-quorum-policy=ignore
設定後に、node1で次のコマンドを実行します。
# eth1の通信を遮断
[root@node1 ~]# iptables -A INPUT -i eth1 -j DROP
[root@node1 ~]# iptables -A OUTPUT -o eth1 -j DROP
# eth2の通信を遮断
[root@node1 ~]# iptables -A INPUT -i eth2 -j DROP
[root@node1 ~]# iptables -A OUTPUT -o eth2 -j DROP
eth1、eth2の通信が遮断され、通信ができなくなります。この状態でno-quorum-policy=ignore
が設定されているため、node1ではtest
リソースが動き続け、node2でもtest
リソースが起動します。この現象をスプリットブレインと呼び、サービスが2ノードで起動するため、データ損失のリスクが高まります。しかし、3ノード構成でQuorum設定を適切に利用することで、スプリットブレインの発生を防止できます。
