CentOS6.5でDRBD8.4を使ってみる - vol.5 スプリットブレイン編1

# しおり

[CentOS6.5でDRBD8.4を使ってみる - vol.0 準備編](http://qiita.com/takehironet/items/4d26198798fb4b7454f8)
[CentOS6.5でDRBD8.4を使ってみる - vol.1 インストール編](http://qiita.com/takehironet/items/c90cd89fb621e570571f)
[CentOS6.5でDRBD8.4を使ってみる - vol.2 Corosync設定編](http://qiita.com/takehironet/items/61a3da51af3b32957872)
[CentOS6.5でDRBD8.4を使ってみる - vol.3 DRBD初期設定編](http://qiita.com/takehironet/items/13518725ee7c694efe90)
[CentOS6.5でDRBD8.4を使ってみる - vol.4 CRM設定編](http://qiita.com/takehironet/items/486bcdfe5609c67d5148)
[CentOS6.5でDRBD8.4を使ってみる - vol.5 スプリットブレイン編1](http://qiita.com/takehironet/items/9c572035bed953e28c16)

# スプリットブレインとは

ここまでの設定だけではスプリットブレインが簡単に生じてしまいます。
スプリットブレインとは、クラスタが分断された時に、アクティブもしくはマスターのノードが複数存在してしまう状態のことを言います。
この状態のクラスタにデータの更新を行うと、データの不整合を起こします(例えばデータベースやファイルのアップロードなど)。

PacemakerとDRBDを組み合わせた場合、2種類のスプリットブレインが存在します。

## Pacemakerのスプリットブレイン

Pacemakerの死活監視用LANケーブル(インターコネクト)を引き抜いたり、ファイアウォールでハートビートを遮断すると発生します。

お互いに状況がわからなくなるので、それぞれがリソースの起動や昇格処理を行います。
共有ディスクをPacemakerでマウントさせている場合には、同じボリュームを同時にマウントしてしまい、クラスタファイルシステムを使用していない場合には、ファイルシステムが壊れます。

## DRBDのスプリットブレイン

DRBDのデータ同期用LANケーブルを引き抜いたり、ファイアウォールでDRBDの通信を遮断すると発生します。

明示的に設定を行っていない場合、DRBDは同時に複数の `Primary` ノードを持てませんが、スプリットブレインになると、対向ノードが見えなくなるので昇格が可能になります。

この状態でファイルに更新が掛かると、変更されたファイルの抽出や変更内容を調査して地道にマージをしていくか、どちらかの変更内容を破棄してしまうか、という選択をして復旧を行います。


# スプリットブレインを防止する策

スプリットブレインを防止する策はいくつかあります。

## フェンシング

代表的な方法はフェンシング(fence)です。
Corosyncをインストールしたあと `property stonith-enabled=false` としていますが、これはフェンシングの実装であるSTONITHを無効にしています。
これを `property stonith-enabled=true` とするとSTONITHが有効になり、STONITHの設定を行えば利用可能です。

STONITHは対向ノードの電源を強制的に切断することで、認識できなくなったノードを強制的にクラスタから離脱させます。
主に、相手のIPMIボードに働きかけて電源を切ったり再起動したりさせます。

その他には、対向ノードへのアクセス経路を遮断する方法もあり、ネットワークスイッチで対向ノードが接続されているポートを Administratively Down に設定します。
相打ちを防ぐために、対向ノードが管理コンソールにログイン出来ないように設定する必要もあります。

ここまでの方法は、物理的に特別な機器が必要です。
IPMIを備えないマザーボードを使っている場合や、管理コンソールにtelnetやSSHで接続できないネットワークスイッチを使っている場合には利用できません。

(libvirtによる管理をされているゲストでHAクラスタを構成している場合には、対向ノードのlibvirtに接続して強制的にシャットダウンさせることができます)

## クオーラム

3ノード以上のクラスタの場合、クオーラムという方法も有効です。

一言で言えば、多数決です。
3ノードのうち1台が認識できなくなった場合、1:2になりますから、2ノード存在するほうが指揮権を得ます。

DRBD 8.xでは2ノードが原則ですから、ここでは詳細を割愛します。

## その他の安価な代替策

安価にとれる対策は2つあります。

1つ目は、HAクラスタで管理されるリソースは、仮想IPアドレス(フローティングIPアドレス)を用いてサービス提供している場合がほとんどだと考えられますので、これを利用します。

2つ目は、ネットワークの到達性を利用します。
Pingを打って返答があれば、アクセス経路があるものとみなします(Pingターゲットが1つ以上必要)。

2つ目のPingを利用した方法を単独で用いると、単純にインターコネクトが失われた場合には両方のノードがPingの返答を得られますので、効果はありません。
したがって、1つ目の方法もしくは、1つ目の方法と2つ目の方法の組み合わせをとります。

ここではこの代替策を設定して効果を確認してゆきます。


# スプリットブレインを起こす前の状態を確認

スプリットブレインを敢えて発生させて、状態を確認します。
今回のスプリットブレインの組み合わせはおおまかには3通りです。

1. DRBDのみ
2. Pacemakerのみ
3. DRBDとPacemakerの両方

まず現状を確認しておきます。

`crm_mon -Af` の結果です。

```plain:crm_mon
============
Last updated: Wed Sep  3 03:09:12 2014
Stack: openais
Current DC: drbd1 - partition with quorum
Version: 1.0.13-a83fae5
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ drbd1 drbd2 ]

 Master/Slave Set: ms-drbd
     Masters: [ drbd1 ]
     Slaves: [ drbd2 ]
filesystem      (ocf::heartbeat:Filesystem):    Started drbd1

Node Attributes:
* Node drbd1:
    + master-drbd:0                     : 10000
* Node drbd2:
    + master-drbd:1                     : 10000

Migration summary:
* Node drbd1:
* Node drbd2:
```

drbd1とdrbd2がオンラインで、DRBDはdrbd1がマスター、ファイルシステムはdrbd1でマウントが成功しています。
DRBDのデータは両方とも最新( `UpToDate` )になっており、どちらもマスターになる資格を有しています(スコアが `10000` )。

drbd1における `cat /proc/drbc` の結果です。

```plain:/proc/drbd
version: 8.4.5 (api:1/proto:86-101)
GIT-hash: 1d360bde0e095d495786eaeb2a1ac76888e4db96 build by mockbuild@Build64R6, 2014-08-17 19:26:04
 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:4 nr:0 dw:4 dr:678 al:1 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
```

この状態を基本に各パターンを確認していきます。