DRBD・Pacemaker構築:Rocky Linux 9・STONITH・2ノードHA
EdwardMoon
DRBDは2サーバーのブロックデバイスを複製し、Pacemaker・CorosyncはPrimary、ファイルシステム、仮想IP、サービスをどのノードで動かすか決めます。両方をPrimaryへ上げたりXFSを同時マウントしたりすると破損のおそれがあるため、Active/Passiveと単一の書き込み元を守ります。
従来のCentOS 7.9例はEOL、古いMaster/Slave用語、fencing省略のため、そのまま新規本番へ使えません。Rocky Linux 9系、DRBD 9、現在のPromoted/Unpromotedモデルで設計と検証を説明します。版とサポートされる組み合わせは配布元・LINBITの契約資料で再確認してください。

アーキテクチャと障害境界
| 層 | 役割 | 障害時の保護 |
|---|---|---|
| DRBD 9 | ブロックの同期複製 | Protocol C、単一Primary、複製状態の確認 |
| Corosync | メンバー管理、通信、quorum | 専用・冗長ネットワーク、qdevice検討 |
| Pacemaker | 配置、順序、復旧 | Promoted、colocation、order |
| STONITH | 隔離できないノードの電源・アクセス遮断 | 独立管理網と実fence試験 |
| Filesystem | DRBD上の単一writer XFS | Promotedだけでマウント |
| VIP・サービス | 入口とアプリケーション | FSの後に開始し、逆順に停止 |
| Backup | 削除、破損、ランサムウェアから復旧 | DRBDと分けた版管理バックアップと復元試験 |
本番でSTONITHを無効にするのは安全ではありません。通信断の相手が本当に停止したと証明できないと、両ノードがデータ所有権を主張します。データリソースを起動する前にfencingを構成・試験します。
構築前の要件
- OS、DRBD kernel module・utils、Pacemaker、Corosync、pcs、resource agentの対応を固定する。
- 正引き、逆引き、NTPを確認する。
- 複製、Corosync、サービス、BMC・fencing網の障害ドメインを可能な限り分ける。
- backing deviceの容量とsectorを確認し、FS・LVM署名がないことを確かめる。
- 専用fence agent、BMCアカウント、qdeviceまたは第三の判断点を用意する。
- RPO・RTOと、破損、split brain、サイト障害時の手動復旧を文書化する。
ノードとストレージを確認する
hostnamectl --static
timedatectl status
chronyc tracking
getent hosts ha1.example.com ha2.example.com
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,MODEL,SERIAL
sudo blkid /dev/vdb1
sudo wipefs --no-act /dev/vdb1
例は/dev/vdb1ですが、実環境ではWWID、multipath、LVM層を特定します。再起動で名前が変わらないか確認し、既存署名があれば中止します。wipefsの–no-actは照会だけで、この記事では実削除を自動化しません。
パッケージとresource agent
sudo dnf repolist
sudo dnf --showduplicates list drbd-utils kmod-drbd pacemaker corosync pcs resource-agents fence-agents-all
rpm -q drbd-utils pacemaker corosync pcs resource-agents
modinfo drbd | head
drbdadm --version
pcs --version
pcs resource standards
pcs resource providers ocf
pcs resource agents ocf:linbit
DRBDのパッケージ名とkmodの提供方法はリポジトリで異なります。RHEL互換性、Secure Boot署名、カーネル更新方針、サポート主体を確認し、検証済みの提供元だけを使います。ocf:linbit:drbdが実際に導入されるまでリソースを作りません。
DRBD複製リソース
Protocol Cは遠隔ディスクの書き込み確認後に完了を返す同期複製ですが、アプリケーションのfsyncやストレージキャッシュまで自動保証しません。両ノードのデータ経路と、電源断時の永続性を別途試験します。
shared secretの生成
umask 077
openssl rand -base64 32
# 出力は承認済みの秘密情報保管庫へ保存し、
# 両ノードのDRBD設定へ同じ値を配布します。
/etc/drbd.d/r0.resの例
resource r0 {
protocol C;
device /dev/drbd0;
disk /dev/vdb1;
meta-disk internal;
net {
cram-hmac-alg sha256;
shared-secret "REPLACE_WITH_GENERATED_SECRET";
}
on ha1.example.com {
node-id 0;
address ipv4 10.10.10.11:7789;
}
on ha2.example.com {
node-id 1;
address ipv4 10.10.10.12:7789;
}
}
rootだけが読める0600にし、構成管理の平文ログへsecretを残しません。REPLACEを実秘密値へ変更するまで進まないでください。複製相手からのTCP 7789だけを許可し、SELinuxとfirewalldを無効にしません。
メタデータ作成とデバイス起動
sudo chown root:root /etc/drbd.d/r0.res
sudo chmod 0600 /etc/drbd.d/r0.res
sudo drbdadm dump r0
sudo drbdadm create-md r0
sudo drbdadm up r0
sudo drbdadm status r0 --verbose
sudo cat /proc/drbd
create-mdはbacking deviceへDRBDメタデータを書きます。対象とバックアップを再確認して両ノードで実行します。既存データvolumeの変換には別の移行手順が必要です。
初期同期とファイルシステム作成
# 新規の空volumeに限り、承認された変更時間帯にha1だけで実行
sudo drbdadm primary --force r0
watch -n 2 sudo drbdadm status r0
# 両peerがUpToDateであることを確認してから新しいXFSを作成
sudo mkfs.xfs -L ha_data /dev/drbd0
sudo mkdir -p /srv/ha-data
sudo mount /dev/drbd0 /srv/ha-data
sudo touch /srv/ha-data/cluster-marker
sudo umount /srv/ha-data
sudo drbdadm secondary r0
mkfs.xfsは既存内容を破壊します。再利用volumeや、どちらかに保持するデータがある場合は実行しません。SourceとTargetを逆にすると正しいデータを空ブロックで上書きする場合があるため、新しい空デバイスであることを確認し、UpToDate/UpToDateまで待ちます。
クラスターとSTONITH
pcs認証とCorosync作成
# 両ノードでhaclusterのパスワードを対話的に設定
sudo passwd hacluster
# 片方で実行し、パスワードはプロンプトへ入力
sudo pcs host auth ha1.example.com ha2.example.com -u hacluster
sudo pcs cluster setup ha-drbd ha1.example.com ha2.example.com --start
sudo pcs cluster enable --all
sudo pcs cluster status
sudo pcs quorum status
sudo corosync-cfgtool -s
2ノードでは通信断時にどちらが生きているか相互に判断できません。第三の投票としてqdeviceを検討しますが、STONITHの代わりではありません。DRBD内部quorum・diskless tiebreakerを使う場合は、Pacemaker fencingとDRBD resource-level fencingを無計画に重ねず、対応資料に沿う一貫した設計を選びます。
Fence agentの確認と実試験
sudo pcs stonith list
sudo pcs stonith describe fence_ipmilan
sudo pcs stonith config
sudo pcs property config --all
# 実機のBMC・PDU・クラウド用fence agentとパラメーターで作成して確認
sudo pcs stonith config --full
sudo pcs stonith status
fence_ipmilanは例です。機器に合うagent、pcmk_host_map、独立管理アドレス、最小権限アカウントを使います。パスワードは履歴に書かず、agentが対応する安全な受渡方法を使ってください。
# 保守時間内にサービス影響と対象ノードを二重確認してから実行
sudo pcs stonith fence ha2.example.com
sudo pcs status --full
sudo journalctl -u pacemaker -u corosync --since '-10 min'
対象の電源が実際に切れたか、ストレージアクセスが遮断されたか、人が確認します。コマンド成功だけで判断せず、STONITHが失敗したままデータリソースを開始しないでください。
新しい空のクラスターでは、リソースと制約の作成中の自動開始を防ぐためmaintenance modeにします。既存稼働クラスターでは全リソースの管理に影響するため、そのまま実行しないでください。
sudo pcs property set maintenance-mode=true
sudo pcs property config
promotableリソース
DRBD agentとPromoted
sudo pcs resource create drbd_r0 ocf:linbit:drbd drbd_resource=r0 op monitor interval=15s role=Promoted op monitor interval=30s role=Unpromoted
sudo pcs resource promotable drbd_r0 promoted-max=1 promoted-node-max=1 clone-max=2 clone-node-max=1 notify=true
sudo pcs resource config drbd_r0
sudo pcs status --full
現在はMaster/Slaveの代わりにPromoted/Unpromotedを使います。promoted-max=1でPrimaryを同時に1つへ制限します。pcsが生成したリソース名とclone名を確認し、次の制約で正確に使います。
Filesystem・VIP・サービスのグループ
sudo pcs resource create fs_data ocf:heartbeat:Filesystem device=/dev/drbd0 directory=/srv/ha-data fstype=xfs op monitor interval=20s timeout=40s
sudo pcs resource create vip_app ocf:heartbeat:IPaddr2 ip=192.0.2.50 cidr_netmask=24 op monitor interval=20s
sudo pcs resource create app_service systemd:myapp op monitor interval=20s timeout=40s
sudo pcs resource group add app_group fs_data vip_app app_service
myappがクラスター外で自動起動しないよう両ノードのsystemd enableを整理します。IP、interface、Filesystemオプション、timeoutを実環境へ合わせます。XFSは1ノードだけでマウントする単一writerとして使い、dual-primaryへ拡張しません。
orderとcolocation
# pcs status/configで実際のpromotable clone名を確認して使用
sudo pcs constraint order promote drbd_r0-clone then start app_group
sudo pcs constraint colocation add app_group with promoted drbd_r0-clone INFINITY
sudo pcs constraint config --full
sudo pcs status --full
orderはPromoted後にグループを開始し、colocationはそのノードへ配置します。内部はFilesystem→VIP→サービスの順で開始し、逆順に止まります。名前と役割構文は使用中のpcs helpと生成CIBで確認します。
状態とデータの検証
リソース、order、colocation、fencingをすべて確認してから、新規演習クラスターのmaintenance modeを解除します。
sudo pcs constraint config --full
sudo pcs stonith status
sudo pcs property set maintenance-mode=false
sudo pcs status --full
正常状態の確認
sudo pcs status --full
sudo crm_mon -1Arf
sudo pcs resource config
sudo pcs constraint config --full
sudo drbdadm status r0 --verbose
findmnt /srv/ha-data
ip -brief address | grep '192.0.2.50'
curl --fail --silent --show-error http://192.0.2.50/healthz
| 検査 | 正常基準 | 異常時の確認 |
|---|---|---|
| DRBD role | 1台がPromoted/Primary、1台がUnpromoted/Secondary | 手動promote、制約、agentログ |
| disk state | 双方UpToDate | 複製網、backing device、resync |
| Filesystem | Promotedの1台だけでmount | colocation、order、systemd自動mount |
| STONITH | 双方が相手を実際に隔離できる | BMC電源、権限、管理網、timeout |
| quorum | 予定voteとqdeviceが正常 | Corosync link、wait_for_all、第三投票 |
| サービス | VIPとhealth応答 | FS準備、appログ、firewall |
フェイルオーバー試験
無闇にケーブルを抜く前に、正常なstandby切り替えで制約とアプリケーションを確認します。その後、承認済み計画に従い、プロセス失敗、ノード終了、Corosync断、複製網断、BMC失敗を個別に試験します。
sudo pcs node standby ha1.example.com
watch -n 2 sudo pcs status --full
curl --fail --silent --show-error http://192.0.2.50/healthz
ssh ha2.example.com 'findmnt /srv/ha-data; sudo drbdadm status r0'
sudo pcs node unstandby ha1.example.com
sudo pcs status --full
Pacemaker管理開始後は、手動drbdadm primary、mount、systemctl startで状態を変えないでください。CIBの期待と実際が乖離します。保守はstandbyかmaintenance modeを使い、完了後に全リソースの管理状態を確認します。
split brainへの対応
- サービスと自動復旧を止め、両ノードが同時に書けないよう物理的に隔離する。
- role、disk state、Pacemaker・Corosync・fenceログ、最終正常バックアップ時点を保全する。
- アプリケーション担当者とトランザクションを基準に正本を決める。
- LINBIT公式手順で選んだ破棄対象ノードだけをdiscardすることを、2名で確認する。
- 再同期後にFS、整合性、機能、バックアップを確認する。
- 複製網、quorum、STONITH、制約の根因を直し、同じ試験を繰り返す。
discard-my-dataは片側の全データを破棄する場合があるため、コピー実行用の例は示しません。正本選択とバックアップなしで進めず、使用中のDRBD 9の公式資料とサポート手順に従ってください。
証拠収集
sudo drbdadm status r0 --verbose
sudo drbdsetup status --statistics
sudo pcs status --full
sudo crm_mon -1Arf
sudo corosync-cfgtool -s
sudo pcs quorum status
sudo journalctl -u drbd -u pacemaker -u corosync --since '-30 min' --no-pager
運用チェックリスト
- CentOS 7の例から移り、対応OS・DRBD・Pacemakerを固定した。
- backing deviceをserial・WWIDで確認し、初期化前に二重確認した。
- 複製、Corosync、サービス、BMCの障害ドメインを分けた。
- STONITHを実試験し、stonith-enabledを無効にしていない。
- promoted-max=1で、XFSはPromotedの1台だけにある。
- FS・VIP・サービスのorderとcolocationを検証した。
- standby、ノード終了、リンク断、fence失敗の期待結果とRTOを記録した。
- 別の版管理バックアップを作り、隔離環境へ復元した。
公式資料と関連記事
- LINBIT DRBD 9ユーザーガイド
- ocf:linbit:drbd resource agent
- RHEL 9 Pacemaker開始とfencing
- RHEL 9クラスターquorum
- ClusterLabs Pacemaker Explained
- GlusterFSとDRBDの選択
- GlusterFS Replica 3構築とHeal
まとめ
2ノードHAの核心は迅速な再起動だけでなく、旧所有者を確実に隔離してから正しいデータを1か所だけで書くことです。Protocol C、単一Promoted、実動するSTONITH、quorum、FS・VIP・サービスの制約を併せて検証します。複製はバックアップではないため、障害試験と独立した復元試験まで完了して運用へ進みます。