2017年2月21日火曜日

CLVMに挑戦(アクティベートフラグ編その3)

前回、アクティベートフラグの-aeについて実験したんだが、ちょっと期待した結果が得られなかった。

-aeは排他モードを意味していて、HAクラスタ等を使用する時に使えるオプションのはずだ。
通常はメインノードでのみアクティベーションしておいて、メインノードがダウンした時に、スタンバイノードでアクティベーションする。
常にいずれかのノードでのみアクティベーションする形になり、複数のノードで同時にアクティベーション出来ないように制御するのが排他モードのはずだ。

ところが、前回の実験では、メインノードが強制停止した場合に、スタンバイノードでアクティベーションすることが出来ない、という結果になった。

この状況から察するに、クラスタを構成するノードが欠けた場合の挙動が、きちんと設定できていないのではないか?と推測している。

というところで、CLVM(clvmd)は、他のサーバのclvmdと通信をしているはず、という予想ができる。clvmd同士の相互通信によって、共有ボリュームの状態や変更コマンドをやり取りしているのではないか?と考えられる。
ところが、clvmdのセットアップには、特に通信に関わる設定は施していない。
一体どういうことか?

どうやら、clvmdはそれ単独では、他のサーバ上のclvmdと通信をする機能は持っておらず、他のクラスタマネージャの機能を利用しているようだ。
manを見てみると、以下のような記載がある。
--ココから
-I cluster_manager
Selects the cluster manager to use for locking and internal com‐
munications. As it is quite possible to have multiple managers
available on the same system you might have to manually specify
this option to override the search.

By default, omit -I is equivalent to -Iauto. Clvmd will use the
first cluster manager that succeeds, and it checks them in a
predefined order cman, corosync, openais. The available man‐
agers will be listed by order as part of the clvmd -h output.
--ココまで
cman、corosync、openaisのいずれかの機能を利用しているようだ。
また、clvmd -hで何を使っているかが分かるらしい。

(gemini) $ clvmd -h
(一部略)
-I<cmgr> Cluster manager (default: auto)
Available cluster managers: corosync

何も設定していないとautoになり、現在使用可能なクラスタマネージャはcorosyncということになっている。(元々、gfs2のセットアップ時に、corosyncはセットアップしている。)

ということは、以下の図のような関係になっているのではないだろうか?と予想できる。


片方(例えばcancer)がダウンした場合、corosync同士の通信が出来なくなる。
corosync側の設定で、クラスタ構成ノードが欠けた場合の定義をしていれば、もしかしたら…という予想が出来る。

というわけで、corosyncの定義ファイルである、corosync.confのマニュアルを見てみる。
(gemini) $ man 5 corosync.conf
…イマイチ良くわからない。
が、マニュアルエントリの「SEE ALSO」のところに「votequorum(5)」が上がっている。参考情報だ。
voteは「投票」、quorumは「定足数」で、いずれもクラスタ分離(スプリットブレイン等)した時などに必要となるキーワードだ。
今回は、geminiとcancerの2ノードクラスタで、cancerを強制停止した状態なので、クラスタ分離とはちょっと異なるけど、もしかしたらこちらのマニュアルが関係あるかもしれない。

というわけで、そちらのマニュアルも見てみよう。
(gemini) $ man 5 votequorum

お!「SPECIAL FEATURES」の欄に、いきなり「two_node」という宣言の説明がある。
2ノードクラスタの場合に設定する特別なパラメータのようだ。
corosyncの基本ポリシーとしては、クラスタ稼働するためには「クラスタを構成するノード数 / 2 + 1」のノード数が生きている必要がある。
ところが、2ノードクラスタの場合、1台ダウンしたらその時点で条件を満たせなくなるため、2ノードであることを明確に宣言する、ということが必要なようだ。

サンプルに記載があるが、/etc/corosync/corosync.confのquorum{}宣言の中に、「two_node: 1」を追記すればいいようだ。

ただし、付帯事項があって、two_nodeを有効にした場合(1に設定した場合)、合わせてwait_for_allも設定されるようだ。
こちらは、構成されている全ノードが一度でも有効にならないと、クラスタ機能を有効にしない、というパラメータのようだ。
今はまだ「そういうパラメータがある」とだけ覚えておこう。

two_nodeパラメータの効果を確認するために、gemini/cancerの両方のノード上の/etc/corosync/corosync.confを書き換えて、OS毎再起動してみよう。
(もしかしたら、sudo systemctl daemon-reloadでもいいのかもしれないが。)

両方のノードが再起動してきたら、とりあえずLVMの状態から確認していく。
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
再起動直後なので、両方共アクティベートされている。

とりあえずディアクティベートする。
(gemini) $ sudo lvchange -a n vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs

前回の後半と同じ状況を再現してみる。
まずは、cancer側で排他モードでアクティベートする。
(cancer) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs

続いて、cancer側でマウントする。
(cancer) $ sudo systemctl start /mnt/ocfs2
(cancer) $ df /mnt/ocfs2

gemini側でディアクティベート出来ないことを確認する
(gemini) $ sudo lvchange -a n vg-ocfs2/lv-ocfs

cancerを強制的に停止させる。(KVMホスト側から実施する)
(sagittarius) $ virsh destroy cancer
(sagittarius) $ virsh list --all

生き残っているgemini側からLVのステータスを確認。
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
gemini側からは、ディアクティベートのままとして見える。

ココまでは前回と同じ結果だ。
ココで、gemini側でLVをアクティベートする。
(gemini) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
あっさりアクティベート出来る。

マウントして、中身を確認してみる。
(gemini) $ sudo systemctl start /mnt/ocfs2
(gemini) $ ls -l /mnt/ocfs2
ちゃんと中身が見える。

実際にI/Oしてみると、普通にI/O出来ることが分かる。

というわけで、2ノードクラスタの場合、corosync.confに「two_node: 1」という宣言が必要だったみたいだ。

この状態で、cancer側を起動して、ディスクの付け直し(geminiからcancerへ)が可能かも合わせて確認しておこう。
cancerの起動
(sagittarius) $ virsh start cancer

cancer側で当該ディスクの状態確認。
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
ディアクティベートのままだ。(gemini側で排他モードでアクティベートしているので、これは想定通り)

gemini側でアンマウント、ディアクティベート。
(gemini) $ sudo systemctl stop /mnt/ocfs2
(gemini) $ df /mnt/ocfs2
(gemini) $ sudo lvchange -a n vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs

cancer側で排他モードでアクティベート、マウント。
(cancer) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
(cancer) $ sudo systemctl start /mnt/ocfs2
(cancer) $ df /mnt/ocfs2
(cancer) $ ls -l /mnt/ocfs2
普通にマウント出来た。

なんとなくコレでいいような気がするが、もう1つ確認しておく必要がある。
corosync.confにtwo_node宣言を追加する過程で「合わせて、wait_for_allも設定される」と記載した。
このwait_for_allがどのような挙動を示すのか?必要なのか?を確認しておかないといけない。

次回はwait_for_allを確認する。(って、合わせてlast_man_standingやauto_tie_breakerも確認しないといけないっぽいが…)

0 件のコメント:

コメントを投稿