高可用性(HA)クラスタの運用において、DRBDのステータス変化をリアルタイムかつ正確に把握することは、システムの信頼性を担保する上で極めて重要です。

これまで、多くの現場では /var/log/messages などの syslog に出力されるテキストを grep 等でパターンマッチングし、障害を検知する手法が取られてきました。しかし、DRBD 9 の時代において、このアナログな監視手法はすでに限界を迎えています。
本記事では、syslog監視が抱えるリスクを解説するとともに、LINBIT社が公式に推奨するモダンな監視手法 drbdsetup events2 の圧倒的な優位性と、実機ログに基づく具体的な実装ガイドをご紹介します。
1.syslog監視が抱える問題点
syslogに出力されるメッセージは、本来「人間が読んでトラブルシューティングするためのもの」です。そのため、以下のような致命的なリスクをはらんでいます。
- フォーマットの予告なしの変更: ソフトウェアのバージョンアップに伴い、エラーメッセージの文言や出力形式が変わることは日常茶飯事です。正規表現に依存した監視スクリプトは、ある日突然機能しなくなります。
- 複雑なパース処理: DRBD 9からマルチピア(多対多)接続がサポートされたことで、ログには「どのノードに対する、どのリソースのメッセージか」が複雑に混ざり合うようになりました。これを正確に切り分けるのは至難の業です。
これらのリスクを排除し、安全にクラスタを自動制御するために用意されたのが drbdsetup events2 コマンドです。
2.drbdsetup events2 の優位性
drbdsetup events2 は、DRBDの内部ステータスの変化をリアルタイムにストリーミング出力するコマンドです。最大の強みは、その出力が「機械可読(Machine Readable)」である点にあります。
- 厳格なフォーマット: 出力はすべて
オブジェクト種別 名前 状態キー:値という一貫したルールに従います。 - 正確なタイムスタンプ:
--timestampsオプションを付与することで、ミリ秒単位での状態遷移を正確に記録できます。 - スコアの可視化: HAクラスタマネージャ(Pacemaker等)がフェイルオーバーの判断基準とする
promotion_score(昇格適格性スコア)の増減をダイレクトに取得できます。
複雑な正規表現はもう必要ありません。「特定の状態キーと値」が含まれているかを判定するだけで、極めて堅牢な監視スクリプトを作成できます。
3. 完全解剖:events2 の出力フォーマットと全パターン
drbdsetup events2 の出力は、スクリプトでの解析(パース)を前提とした極めて規則的なフォーマットで構成されています。すべての行は例外なく、以下の構文に従って出力されます。
【基本構文】 <イベント種別> <オブジェクト種別> <識別キー> <状態キー>:<値> ...
この規則さえ理解しておけば、監視スクリプトで迷うことはありません。それぞれの要素に入る全パターンを解説します。
① イベント種別(Event Type)
行の先頭には、どのようなアクションが発生したかを示す単語が入ります。
exists: 監視開始時に出力される、現在の全ステータスの初期ダンプです。(最後にexists -が出力されるとダンプ完了を意味します)change: 状態が変化した瞬間にリアルタイムで出力されます。監視スクリプトで主に捕捉するのはこの行です。call: スプリットブレイン検知時など、DRBDが内部のヘルパースクリプトを呼び出した際に出力されます。response: 呼び出したヘルパースクリプトの実行が完了した際に出力されます(例:status:0)。destroy: リソースが削除された際などに出力されます。
② オブジェクト種別(Object Type)
DRBD 9の内部アーキテクチャに合わせて、どのコンポーネントでイベントが発生したかを示します。
resource: リソース全体の情報(昇格スコアpromotion_scoreや、ノードの役割roleなど)device: ローカルのディスク・ボリューム情報(ディスク状態diskなど)connection: 対向ノードとのDRBDプロトコルレベルの接続状態(ネットワーク状態connectionなど)peer-device: 対向ノードのディスク情報や同期状態(レプリケーション状態replicationなど)path: TCP/IPレベルの物理的な経路情報(TCPパスの確立establishedなど)helper: 実行されたヘルパースクリプトに関する情報
③ 識別キー(Identifiers)
「どのリソースの、どのノードの話か」を特定するためのキーです。主に以下のようなものが付与されます。
name:r0(リソース名)volume:0(ボリューム番号)peer-node-id:1 conn-name:node2(対向ノードのIDと名前)
④ 状態キーと値(State Key:Value)
実際に変化したステータスが キー:値 の形式で出力されます。ここが監視のキートリガーとなります。
- 接続の監視に使うキー:
connection:Connected,connection:NetworkFailure,connection:Connectingなど - ディスクの監視に使うキー:
disk:UpToDate,disk:Diskless,disk:Failedなど - 役割の監視に使うキー:
role:Primary,role:Secondary - フェイルオーバー制御に使うキー:
promotion_score:10102(この数値の変動で健全性を判断します)
【実際の出力例の読み解き方】
change connection name:r0 peer-node-id:1 conn-name:node2 connection:NetworkFailure role:Unknown
この1行を見るだけで、プログラムは「状態変化(change) が、対向ノードとの接続(connection) において発生。リソースは r0 で対向ノードは node2。状態は NetworkFailure (切断) になり、相手の役割は Unknown (不明) になった」と完璧に解釈できるのです。
4.【実践コード】Bashで作るシンプルな状態監視スクリプト
複雑な正規表現はもう必要ありません。「特定の状態キーと値」が含まれているかを判定するだけで、極めて堅牢な監視スクリプトを作成できます。
以下は、events2 のストリームを読み込み、主要な障害を検知してアラートを上げるシンプルなBashスクリプトの例です。
Bash
#!/bin/bash
RESOURCE="r0"
echo "DRBDリソース '${RESOURCE}' の監視を開始します..."
# events2の出力を1行ずつリアルタイムに読み込む
drbdsetup events2 ${RESOURCE} | while read -r line; do
# 1. ネットワーク断の検知
if [[ "$line" == *"change connection"* && "$line" == *"connection:NetworkFailure"* ]]; then
echo "[ALERT] $(date '+%Y/%m/%d %H:%M:%S') ネットワーク断 (NetworkFailure) を検知しました!"
fi
# 2. ローカルディスク喪失の検知
if [[ "$line" == *"change device"* && "$line" == *"disk:Diskless"* ]]; then
echo "[ALERT] $(date '+%Y/%m/%d %H:%M:%S') ローカルディスクの喪失 (Diskless) を検知しました!"
fi
# 3. 通信復旧の検知
if [[ "$line" == *"change connection"* && "$line" == *"connection:Connected"* ]]; then
echo "[INFO] $(date '+%Y/%m/%d %H:%M:%S') 対向ノードとの通信が復旧 (Connected) しました。"
fi
done
5.実機ログで見る!障害発生から復旧までのDRBDの動き
それでは、実際に検証環境で障害を発生させた際、events2 がどのようなミリ秒単位のドラマを記録するのか見ていきましょう。
シナリオA:ネットワーク断(サイレント障害の検知)
対向ノードへのパケットが完全に消失(100%ロス)した状態をシミュレートしました。
# 初期状態(正常)
2026-06-08T07:16:55.062063+09:00 exists connection name:r0 peer-node-id:1 conn-name:node2 connection:Connected
# 約17秒後:障害の自発的検知
2026-06-08T07:17:12.295510+09:00 change connection name:r0 peer-node-id:1 conn-name:node2 connection:NetworkFailure role:Unknown
2026-06-08T07:17:12.312132+09:00 change connection name:r0 peer-node-id:1 conn-name:node2 connection:Connecting
解説: パケットロスが発生しても、DRBDは瞬時のネットワークバタつきを許容するため、内部の生存確認タイマー(ping-int)が切れるまで待機します。タイムアウトを迎えた瞬間、自発的に connection:NetworkFailure を発報し、再接続を試みる Connecting 状態へと遷移していることが分かります。
シナリオB:ローカルディスク障害による「スコア逆転」
Primaryノードのローカルディスクが物理的に切り離された(Detach)ケースです。
# Node1(Primary)でディスクが失われた瞬間
2026-06-08T07:44:31.333122+09:00 change resource name:r0 may_promote:no promotion_score:1
2026-06-08T07:44:31.374305+09:00 change device name:r0 volume:0 minor:0 backing_dev:none disk:Diskless
解説: 注目すべきは promotion_score:1 への急落です。自身のディスクを喪失したDRBDは、即座に自身の昇格適格性を最低レベルに下げます。これにより、健全なディスクを持つ対向ノード(スコア10101)との間で「スコアの逆転」が発生し、クラスタマネージャは安全にフェイルオーバーを決断できます。
シナリオC:スプリットブレインの検知と自衛機能
両系がPrimary化してデータが分岐する「スプリットブレイン」に陥った後、ネットワークが復旧した際の挙動です。
# ネットワーク復旧直後の衝突と自衛
2026-06-08T07:56:04.496348+09:00 change path name:r0 ... established:yes
2026-06-08T07:56:06.554795+09:00 change connection name:r0 ... connection:BrokenPipe
2026-06-08T07:56:06.566001+09:00 change path name:r0 ... established:no
解説: TCPパスは確立(established:yes)しますが、直後のプロトコル通信で互いのデータ世代識別子(UUID)の不一致を検知します。DRBDはデータ破壊(サイレントコラプション)を防ぐため、意図的に通信を拒絶し BrokenPipe で接続をリセットします。DRBDの強力なデータ保護機能が働いている証拠です。
# 一方のデータを破棄(--discard-my-data)して解決を図った瞬間
2026-06-08T08:00:00.096422+09:00 change device name:r0 ... disk:Inconsistent
2026-06-08T08:00:00.096422+09:00 change peer-device name:r0 ... replication:SyncTarget done:0.00
その後、管理者が一方のデータ破棄を実行すると、即座にディスクが Inconsistent となり、同期を受ける側(SyncTarget)へと状態遷移して自動復旧が始まるプロセスが克明に記録されています。
6.まとめ
DRBDのアーキテクチャが進化し続ける中、システムの運用保守もそれに合わせてモダンな手法へとアップデートする必要があります。
drbdsetup events2 は、インフラエンジニアに「推測」ではなく「確実な事実(データ)」を提供してくれます。まずは開発環境やステージング環境で上記のBashスクリプトを走らせ、障害発生時の圧倒的なレスポンスの速さと確実性をぜひ体感してみてください。