クラスター内のすべてのノードからアクセスできる共有ストレージを用いた合意システムで、共有ストレージを介してノードの情報交換を行います。各ノードは自ノード情報を定期的に共有ストレージに書き込み、また定期的に他ノードが書き込んだノード情報を読み込みます。この共有ストレージに書き込まれたノード情報を QWK オブジェクトと呼びます。QWK オブジェクトはクラスターを構成するノード数だけ必要です。
Quorum チェックでは、共有ストレージにアクセスできることで Quorum チェック成功と判断します。また、Witness チェックでは、障害が疑われるノードの QWK オブジェクトを確認し、一定期間内に更新されていると障害なし、更新が止まっていれば障害が発生していると判断します。なお、実装上は、Quorum チェック時に Witness チェックも実施しています。
なお、Quorum モードに storage を選んだ場合、後述の Witness モードも storage を選択しなければなりません。
本モードは2ノードのクラスターから動作可能で、最大4ノードまでサポートされます。別途、クラスターを構成するノード数分の QWK オブジェクトを格納するための共有ストレージが必要です。なお共有ストレージにアクセスできなくなると、リソースの起動に影響します。すべてのノードから常時アクセス可能な共有ストレージを選定してください。
利用可能な共有ストレージ
Quorum/Witness 機能の目的であるスプリットブレイン回避を確実なものにするために、Quorum 分割(例:ノード A の QWK オブジェクトにアクセス可能であるが、ノード B の QWK オブジェクトにアクセス不能)が発生しない構成としなければなりません。そのため、クラスター内のすべての QWK オブジェクトが同一共有ストレージ上の同一種のブロックデバイス・レギュラーファイル・EFS または S3 オブジェクトに配置されていることを条件とします。
利用可能な共有ストレージは以下の通りです。/etc/default/LifeKeeper 設定ファイルの QWK_STORAGE_TYPE で指定します。
block | 共有ストレージに物理ストレージやRDM(物理互換)、iSCSI(VM 内イニシエーター)を使う場合、1つのQWK オブジェクトは以下のいずれかに配置してください。 (a) 1 QWK オブジェクト = 1 パーティション (b) 1 QWK オブジェクト = 1 LU (a) の場合、複数のホストが1つの LU に書き込みを行いますので、パーティションの LU 内のオフセットは 4K(ストレージ装置のセクターサイズ)でアラインしてください。また、他用途のパーティションを混在させないでください。 |
共有ストレージにVMDKを使う場合、1つのQWK オブジェクトは以下に配置してください。 1 QWK オブジェクト = 1 VMDK パーティションは作成しないでください。また、ファイルシステムを作成する必要はありません。 thick (eager zeroed) |
|
file (または EFS) | 共有ストレージにNFS (または EFS) を使う場合、1つのQWK オブジェクトは以下に配置してください。 1 QWK オブジェクト = NFS (または EFS) ファイルシステム内の 1 レギュラーファイル EFSを使用した場合も、/etc/fstabにファイルシステム情報の記述が必要です。一方でパラメーターはNFSとEFSで体系が異なり、以下に記載のオプションはNFSにのみ適用されます。 NFSサーバーの export オプションは以下の通り設定してください。 rw,no_root_squash,sync,no_wdelay NFSの mount オプションは以下の通り設定してください。 soft,timeo=20,retrans=1,noac OS再起動後、自動でマウントするように /etc/fstab 等の設定を行ってください。 EFS の設定については、こちらの AWS の記事 を参照してください。 |
aws_s3 | 共有ストレージに Amazon Simple Storage Service (S3) 、または Amazon S3互換のオブジェクトストレージを使う場合、1つのQWKオブジェクトは1つのS3オブジェクトとして配置してください。 1 QWKオブジェクト = 1 S3オブジェクト LifeKeeperが動作しているインスタンスのリージョンと別のリージョンのS3を利用してください。これは、同一リージョンのS3を利用した場合にAZ (Availability Zone)間の接続が分断されると、複数AZにレプリケーションが配置されているS3も同時に分断し、S3への一貫性のあるアクセスが期待できなくなるためです。 クラスターを構成するすべてのノードで、 rootユーザーがS3オブジェクトにアクセスできるように以下の権限を付与してください。詳細は AWS CLI のドキュメント や各プラットフォームのオブジェクトストレージのドキュメントを参照してください。
インターネットに接続できない環境から別リージョンのAmazon S3にアクセスする場合、またはAmazon S3互換のオブジェクトストレージにアクセスする場合はエンドポイントおよびリージョンの指定が必要です。リージョンを指定すると、上記のs3:GetBucketLocation権限は不要です。詳細は「Quorumパラメータ一覧 」のQWK_STORAGE_OBJECT_<ホスト名>を参照してください。 注記: 設定ファイル /etc/default/LifeKeeper のパラメーター PATH にAWS CLI実行ファイルのパスが設定されていない場合、PATHにAWS CLI実行ファイルのパスを追加してください。 Amazon S3互換のオブジェクトストレージを使う場合は 利用可能なAmazon S3互換のオブジェクトストレージ をご覧ください。 |
1 QWK オブジェクトのサイズは4096バイトです。
自ノード QWK オブジェクトに対しては read / write を行います。他ノードの QWK オブジェクトに対しては read のみ行います。適切にアクセス権限を設定してください(Persistent Reservation などのアクセス権制限を伴う場合は要注意)。
storage モードの設定
/etc/default/LifeKeeper 設定ファイルで QUORUM_MODE と WITNESS_MODE の設定を storage に設定してください。また、他に以下の設定があります。詳細は「Quorumパラメータ一覧 」を参照してください。
- QWK_STORAGE_TYPE
- QWK_STORAGE_HBEATTIME
- QWK_STORAGE_NUMHBEATS
- QWK_STORAGE_OBJECT_<ホスト名>
- HTTP_PROXY, HTTPS_PROXY, NO_PROXY
storage モードの使用手順
本モードで使用する場合は、初期化が必要です。以下の手順に従って初期化してください。
- クラスターを構成するすべてのサーバーをセットアップして、他のサーバーとネットワーク通信ができることを確認します。
- クラスターを構成するすべてのサーバーに LifeKeeper をインストールします。その際、setup コマンドで「Use Quorum / Witness functions」を有効にして、Quorum/Witness パッケージもインストールしてください。
- すべてのノード間にコミュニケーションパスを作成します。
- すべてのノードで /etc/default/LifeKeeper 設定ファイルを編集し、storage モードの設定を行います。
- すべてのノードで
qwk_storage_init
コマンドを実行します。このコマンドは、すべてのノードで QWK オブジェクトの初期化が終わるまで待ち状態になります。このコマンドがすべてのノードで終了すると、storage モードとして Quorum/Witness 機能が利用できる状態となります。
初期化後にクラスターを構成するノードの追加・削除をする、または /etc/default/LifeKeeper 設定ファイルのパラメーターを変更する場合、再初期化が必要です。以下の手順に従って再初期化してください。
- すべてのノードで
qwk_storage_exit
コマンドを実行します。 - ノードを削除する場合、削除するノードと他すべてのノード間のコミュニケーションパスを削除します。
ノードを追加する場合、追加するノードと他すべてのノード間にコミュニケーションパスを作成します。 - すべてのノードで /etc/default/LifeKeeper 設定ファイルを再設定します。
- すべてのノードで
qwk_storage_init
コマンドを実行します。
storage モードの期待される動作(標準の設定を仮定)
ノード A(リソースはサービス状態)、ノード B(リソースは待機状態)の2ノード構成のクラスターの振る舞いについて示します。
なお、ノード障害に関するリソースの状態を変更し得るイベントは以下の3つです。
- COMM_DOWN イベント
ノード間のコミュニケーションパスが全て切断した時に呼び出されるイベント。
- COMM_UP イベント
COMM_DOWN 状態からコミュニケーションパスが復旧した際に呼び出されるイベント。
- LCM_AVAIL イベント
LCM の初期化が終わった時に呼び出されるイベントで、LifeKeeper 起動時に1度だけ呼び出される。起動時に他のノードとコミュニケーションパス通信ができる場合は、必ず COMM_UP イベントの処理より前に LCM_AVAIL イベントの処理が行われる。
シナリオ1
ノード A とノード B の間のコミュニケーションパス通信に障害が発生(ノード A とノード B とも共有ストレージにアクセス可能)
この場合、以下のように動作します。
- ノード A とノード B は、COMM_DOWN イベントの処理を開始します。ただし、全く同時とは限りません。
- 両方のノードは Quorum チェックを実行し、両方共自身が Quorum を持っていると判断します(共有ストレージアクセスが可能であるため)。
- 各ノードは、通信できなくなったノードの QWK オブジェクトの更新を確認します(Witness チェック)。ノード A とノード B は共に稼働しているため定期的に QWK オブジェクトを更新され、Witness チェックでその更新を確認します。
- Witness チェックの結果、他方のノードがまだ生存しているためフェイルオーバー処理は発生しません。リソースはノード A でサービス状態のままになります。
シナリオ2
ノード A に障害が発生してノード A が停止
この場合、ノード B は以下の動作をします。
- ノード A との COMM_DOWN イベントの処理を開始します。
- 共有ストレージにアクセス可能であるので、Quorum を持っていると判断します。
- ノード A の QWK オブジェクトの更新が停止していることを確認します(Witness チェック)。
- Witness チェックの結果、ノード A で障害が発生していると判断したため通常のフェイルオーバー処理を開始します。これにより保護対象のリソースはノード B でサービス中になります。
リソースがノード B でサービス中に、通信可能かつ共有ストレージにアクセス可能な状態でノード A のサーバーが電源 ON
この場合、ノード A は LCM_AVAIL イベントを処理します。ノード A は、Quorum を持っていると判断し、ノード B でリソースがサービス中のためリソースを起動させません。
また、その直後に、COMM_UP イベントが各ノードで発生しします。各ノードの COMM_UP イベントの処理では、Quorum を持っていると判断し、またノード B でリソースがサービス中のためリソースは起動させません。
リソースがノード B でサービス中に、通信不能かつ共有ストレージにアクセス可能な状態でノード A のサーバーが電源 ON
この場合、ノード A は LCM_AVAIL イベントを処理します。ノード A は、Quorum を持っていると判断し、通信できないノード B に障害が発生しているか確認するためノード B の QWK オブジェクトの更新を確認します。ノード B は稼働しているため、QWK オブジェクトは定期的に更新されます。ノード A では QWK オブジェクトの更新を確認し、ノード B が生存しているが通信できないためにリソースは起動させません。
ノード B はノード A と通信できないので何もしません。
シナリオ3
ノード A のネットワークに障害が発生(ノード A は稼働しているが、他のノードや共有ストレージにアクセス不能)
この場合、ノード A は以下の動作をします。
- ノード B との COMM_DOWN イベントの処理を開始します。
- 共有ストレージにアクセス不能であるため、Quorum を持っていないと判断します。
- 直ちに 強制停止します(QUORUM_LOSS_ACTION のデフォルト「fastkill」の振る舞い)。
また、ノード B は以下の動作をします。
- ノード A との COMM_DOWN イベントの処理を開始します。
- 共有ストレージにアクセス可能であるため、Quorum を持っていると判断します。
- ノード A の QWK オブジェクトの更新が停止していることを確認します(Witness チェック)。
- Witness チェックの結果、ノード A で障害が発生していると判断したため通常のフェイルオーバー処理を開始します。これにより保護対象のリソースはノード B でサービス中になります。
リソースがノード B でサービス中に、共有ストレージにアクセス可能な状態でノード A のサーバーが電源 ON
シナリオ2と同じです。
リソースがノード B でサービス中に、共有ストレージにアクセス不能な状態でノード A のサーバーが電源 ON
この場合、ノード A は LCM_AVAIL イベントを処理します。ノード A は、Quorum を持っていないと判断し、リソースを起動させません。
ノード B とのコミュニケーションパス通信が可能であれば、その後に COMM_UP イベントが発生します。しかし、Quorum を持っていないので、ノード A ではリソースを起動させません。
このトピックへフィードバック