2019年5月4日土曜日

まずはpcsdの導入と初期セットアップ(18.04)

というわけで、18.04の構成(pisces/aries)を使って、NFSクラスタを構築する。

最初はpcsdの導入だ。
sudo apt-get update
sudo apt-get dist-upgrade
(必要に応じて再起動)
sudo apt-get install pcs
合わせて、pacemakerもインストールされる。

pcsdは自動起動にセットされた。

16.04の時と同様、haclusterアカウントが出来ているはずなので、パスワードを設定しておく。
sudo passwd hacluster

ついで、pisces/ariesと管理ノードのleoに、pisces/ariesのホスト名とIPアドレスを/etc/hostsに記載しておく。

sudo vi /etc/hosts
(127.0.1.1に自身のホスト名が定義されていると思うので、それは外しておくこと)
相互にpingを打って、名前解決出来ていることを確認しておこう。

gemini/cancerの時は、ブラウザからクラスタを組んだが、今回はコマンドで組んでみることにする。
sudo pcs cluster auth pisces aries -u hacluster
sudo pcs cluster setup --name nfs-cluster pisces aries --force
sudo pcs status
sudo pcs cluster start pisces aries
sudo pcs status

これでクラスタの構成は出来たが、corosync.serviceとpacemaker.serviceが自動起動になっていない。(pcs cluster setup に --start --enable のオプションを付与しておけば、自動起動に設定されると思うが、今回は敢えて設定しなかった。)
両方共自動起動にしておく。(pisces / ariesの両方で実施しておくこと)
sudo systemctl enable corosync.service
sudo systemctl enable pacemaker.service

これで、OS再起動させても自動的にクラスタが構成されるはずだ。
試しておくこと。

2019年5月2日木曜日

16.04でのgfs2のpacemaker化(一部諦め)

あーでもないこーでもない、と色々検証していった結果、Ubuntu16.04でgfs2をpacemaker管理下に置くのは、いくつか問題があって厳しいことが分かった。

今現在分かっているのは、
  • 2ノードで稼働
  • 片方のノードが死亡
  • 生きている方のノードをメンテナンスのために再起動
という3つの条件が重なった時に、クラスタが上がってこない(厳密には、clvmdリソースが上がってこない)ということ。

クラスタ製品の仕様として、「クラスタを構成するノード数のうち、過半数のノードが起動しない限り、クラスタは稼働させない(3ノードの場合は2台以上、4ノード・5ノードの場合は3台以上)」というのがある。
これはクラスタとしては当然の仕様だ。

2ノードの場合、この条件を満たすためには、2台が正常稼働する必要がある。
クラスタを組んでいるのに、1台も障害を受け付けない、というのはクラスタとしては片手落ちだ。

そこで、クラスタ製品は幾つかの対策を施している。
2ノードのみ特定の設定をし、片方がダウンしてもサービスを継続させる、という仕組みもその一つ。今回使用しているpacemakerの場合、corosync.confに記載する「two_node」というパラメータが該当する。
確かにこのパラメータを1に設定しておけば、片方のノードがダウンしてもサービスは継続実行可能だ。
ただし、これはクラスタ稼働中の話だ。
片系ダウンしている時に、生きている方のノードを再起動させた場合、「クラスタ稼働中」ではなく「クラスタを起動させる時」に該当する。
この時、もう片方のノード(死んでいる方のノード)がクラスタに参加するのを待ってしまうため、いつまで経ってもクラスタが上がってこない。

pcsコマンドにある cluster quorum unblock というのが「ノード数が過半数に達しなくても、サービスを稼働させる」というコマンドのようなのだが、16.04で試してみても期待した動きにならない。

他のクラスタ製品では、「quorum disk」という設定を施すことで、上記の状態を回避することが可能になっている。これは、2ノードの片系ダウンだけでなく、4ノードなどの「偶数台クラスタ」による「スプリットブレイン」にも対応している。
quorum diskは、クラスタを構成しているすべてのノードに接続している共有ディスクで、ほんの僅かなサイズ(数百MB程度?)のディスクであればいい。

偶数クラスタがちょうど半分に分離してしまった場合(ちょうど半数のノードから応答が無かった場合)、予め定義していたquorum diskにロックを仕掛け、ロックを取得することが出来たノード、及びそのノードと通信可能な方のノードの組でクラスタサービスを継続し、ロックを取得できずに切り離されてしまった組はクラスタから離れる、という仕様だ。
これによって、スプリットブレインに対応している。
ちょうど、quorum diskをロックすることによって、ノード数(投票数)が一つ増えたイメージになる。

pacemaker にも同様の仕組みがあると思っていたのだが、なかなかその情報が見つけられず、スプリットブレイン対策がイマイチ分からなかった、というのが先日までの状態。

で、もう一度調査したところ、RHEL6.xまでは、そのものズバリのquorum diskという設定があったようだ。
ところが、RHEL7.xになって、quorum diskが無くなり、quorum deviceという仕組みに置き換わっていた。

Ubuntu16.04のpacemakerで同様の仕組みを探してみたが、corosyncのバージョン違いからか、quorum diskもquorum deviceも設定が無い。
Ubuntu18.04の方を見てみたら、quorum deviceという設定はあるようだ。

この時点で、quorum diskを使用したスプリットブレイン対策は施せないことが分かったのだが、quorum deviceの方を調べてみたら、クラスタ構成ノードとは別に、サーバが1環境必要であることが分かった。
2ノードクラスタを組むのに、3台必要、ということだ。

ちなみに、quorum deviceというのは、スプリットブレインが発生した時に、どちらの組でサービスを継続させるかを決定する、調停役として存在させるみたいだ。
HPE社のクラスタソフトであるServiceGuard for Linuxでは、確か「quorum server」と呼ばれるものに相当するようだ。

とまぁ色々書いてきたが、今のホストOS(sagittarius/aquarius)の2台では、16.04のpacemakerどころか、18.04のpacemakerでも不都合が起きる。
とりあえず、動かすことはできるので、2台のいずれかが故障しないことを祈るか、もう1台手配して、quorum deviceとしてセットアップするか…。

gfs2を使用するためのクラスタだけでなく、nfsサーバもクラスタ化することを考えているので、現状ではかなり厳しい状態なのが判明。果たしてどうするか?

18.04でquorum diskが使えるといいんだが…。

とりあえず今後は、16.04でのgfs2クラスタは一旦放置し、18.04のnfsクラスタの方を少し調査してみることにする。

2019年4月29日月曜日

シングルノード状態でのgfs2

いろいろ試しているうちに、いくつかまだ設定がおかしいと思われるところが見つかった。
致命的なのは、
  • 片方のノード(例えばcancer)が障害で起動できない
  • 生き残っている方のノード(この場合gemini)を再起動させると、clvmリソースが正常に立ち上がって来ない→gfs2が利用できない
という状態だ。
しかも、この状態だとgeminiが再起動できない。(停止処理でハングしてしまう)

調べていったら、起動後にdlmは起動するが、clvmdがうまく起動できていないのだが、clvmdがdlmと通信を行い、dlmがエラーを返すことで、clvmdが起動に失敗する、という流れのよう。
dlmがシングルノードで稼働している(相方が死んでいるので、シングルで稼働させても問題はない)という状態をうまく認識できていないのが問題のよう。

やっぱりdlmがネックになるなー。

2019年4月13日土曜日

Windowsのnetkvm.sys

ちょっと検証から離れて…。
KVM環境の上には、Linux以外にもWindowsを動かしている。
特に、以前から使っていたWindows7をKVMに移行し、それをメインのWindows環境として使っていた。(移行は、Windows7が持つシステムバックアップを使用した。)
KVM環境に移行してからのWindows7、実は頻繁にクラッシュしてた。クラッシュも、頻繁に発生するかと思ったらしばらく発生しなかったりで、原因が全然つかめなかった。
物理環境から、仮想環境へ移行したことが原因だと思っていたんだが…。

で、先日このWindows7をWindows10にアップグレードしたが、Windows10にしてからはもっとクラッシュ頻度が高まり、ほとんど使い物にならない状態だった。

が、Windows10になってから、クラッシュ時に表示される画面で、netkvm.sysというのが原因だということが分かった。
これは、Virtio NIC用のドライバだ。
調べてみると、このnetkvm.sys、非常に不安定らしい。いや、パラメータチューニングを適切に施せば、安定稼働するのかもしれないが…。

ただ、パラメータチューニングも時間がかかるし、チューニング中にもクラッシュしかねない。
なので、Virtio NICはやめて、rtl8139の完全仮想化デバイスに変えた。
変えてから数日しか経ってないが、非常に安定している。速度は出ないかもしれないが、こちらの方が快適だ。
とりあえず、netkvm.sysが安定するまでは、rtl8139を使用することにする。

2019年3月21日木曜日

corosync.confの追記

構成見直しの前に、/etc/corosync/corosync.confに2行ほど追加した。

追加したのは、quorumセクション。
追加前には provider: corosync_votequorum というエントリだけが存在していると思う。
そこに、
wait_for_all: 0
auto_tie_breaker: 1
の2行を追加した。

ホントは two_node: 1 というエントリも追加したいんだが、ノードを切り離して1ノード状態にすると、two_node: 1 というエントリも消えてしまう。
イマイチ良くわからない。

いずれにせよ、上で追加した2行は障害発生時の処理に関わるので、追加しておく。

クラスタ用LVMとファイルシステム作成(gfs2用)

フェンシングが全然わからず、すげー時間がかかった…。

というわけで、今度はgemini/cancerで共有しているディスクに、LVM構成とgfs2ファイルシステムを作成する。
この辺の内容で既に検証してるけど、今一度整理しよう。
当時の手順、間違いもあるから。

あと、サービスの導入やら起動やらを変更しているので、gemini/cancerとも再起動しておいた方が良いかな。
(gemini) $ sudo systemctl reboot
(cancer) $ sudo systemctl reboot
(gemini) $ systemctl status lvm2-cluster-activation.service
(cancer) $ systemctl status lvm2-cluster-activation.service

起動出来てなかった。
(gemini) $ sudo cp -pi /lib/systemd/system/lvm2-cluster-activation.service \
              /etc/systemd/system/lvm2-cluster-activation.service
(cancer) $ sudo cp -pi /lib/systemd/system/lvm2-cluster-activation.service \
              /etc/systemd/system/lvm2-cluster-activation.service
(gemini) $ sudo vi /etc/systemd/system/lvm2-cluster-activation.service
--以下のように修正
After=lvm2-clvmd.service lvm2-cmirrord.service

#After=lvm2-clvmd.service lvm2-cmirrord.service
After=lvm2-clvmd.service
--ココまで
cancerも同様に修正しておく。

修正終わったら反映。
(gemini) $ sudo systemctl daemon-reload
(cancer) $ sudo systemctl daemon-reload
(gemini) $ systemctl status lvm2-cluster-activation.service
(cancer) $ systemctl status lvm2-cluster-activation.service

これで起動してみる。
(gemini) $ sudo systemctl start lvm2-cluster-activation.service
やっぱり起動しない…。


まずは、VGの作成。
同じ仮想ディスクをgemini/cancerの両方に接続しており、いずれも/dev/vdbとして見えている。
(gemini) $ lsblk
(cancer) $ lsblk
これを使って作成していく。
(gemini) $ sudo pvcreate /dev/vdb
(gemini) $ sudo vgcreate vg-gfs2 /dev/vdb
(gemini) $ sudo vgdisplay vg-gfs2
(gemini) $ sudo lvcreate -L 10G -n lv-gfs2 vg-gfs2
(gemini) $ sudo vgdisplay -v vg-gfs2
(cancer) $ sudo vgdisplay -v vg-gfs2
なぜか、意図的にクラスタマークを付与(vgchange -c y)しなくても、クラスタマークが付与された。

さて、LVまで作成できたので、今度はファイルシステムだ。
(gemini) $ sudo mkfs.gfs2 -j2 -p lock_dlm -t gfs2-cluster:fs-gfs2 /dev/vg-gfs2/lv-gfs2
-tオプションは、「クラスタ名」+「:」+「任意の名前」だ。
-jオプションはジャーナル数で、同時にマウントするノード数以上の数字を指定する必要がある。
(gemini) $ sudo tunegfs2 -l /dev/vg-gfs2/lv-gfs2
(cancer) $ sudo tunegfs2 -l /dev/vg-gfs2/lv-gfs2

マウントできるのかな…?
(gemini) $ sudo mkdir /mnt/test
(gemini) $ sudo mount /dev/vg-gfs2/lv-gfs2 /mnt/test
(gemini) $ df /mnt/test
(cancer) $ sudo mkdir /mnt/test
(cancer) $ sudo mount /dev/vg-gfs2/lv-gfs2 /mnt/test
(cancer) $ df /mnt/test
マウントは出来た…。

読み書きテスト
(gemini) $ sudo bash -c "echo \"This is a test\" > /mnt/test/hoge"
(cancer) $ cat /mnt/test/hoge
出来た…。
lvm2-cluster-activation.service は必要無いのか?

一旦再起動して、再度マウントしてみるか…。
(gemini) $ sudo umount /mnt/test
(cancer) $ sudo umount /mnt/test
(gemini) $ sudo systemctl reboot
(cancer) $ sudo systemctl reboot
(gemini) $ sudo mount /dev/vg-gfs2/lv-gfs2 /mnt/test
(cancer) $ sudo mount /dev/vg-gfs2/lv-gfs2 /mnt/test
(gemini) $ cat /mnt/test/hoge
(cancer) $ cat /mnt/test/hoge
(gemini) $ sudo umount /mnt/test
(cancer) $ sudo umount /mnt/test

確認ができたら、リソースを作成する。
(gemini) $ sudo pcs resource create cluster-gfs Filesystem \
    device="/dev/vg-gfs2/lv-gfs2" \
    directory="/mnt/test" \
    fstype="gfs2" \
    op monitor interval=10s on-fail=fence clone interleave=true
(gemini) $ sudo pcs resource show cluster-gfs
(cancer) $ sudo pcs resource show cluster-gfs
できてる。

(gemini) $ df
(cancer) $ df
両方ともマウントされている。

これでいいのか…?
おっと、リソースの起動順と、起動するノードを定義してなかった。
clvmdより後に起動させる必要があるため、それに従って設定する。
(gemini) $ sudo pcs constraint order start clvmd-clone then cluster-gfs-clone
(gemini) $ sudo pcs constraint colocation add cluster-gfs-clone with clvmd-clone
(gemini) $ sudo pcs constraint show cluster-gfs-clone
(cancer) $ sudo pcs constraint show cluster-gfs-clone

これでいいのだろうか?
一旦再起動仕掛けてみる。
(gemini) $ sudo systemctl reboot
(cancer) $ sudo systemctl reboot
片方ずつ落としたらどうなる?
(gemini) $ sudo systemctl poweroff
(cancer) $ cat /mnt/test/hoge

どうやら上手く行っているようだ。
ちょっと時間がかかって、全体の流れがわかりにくくなったので、次回はgemini/cancerを作り直して、もう一度ゼロから実施してみることとする。

2019年2月16日土曜日

げ、stonith(fence)の設定が先だ(gfs2用)

RedHat社のサイトをよくよく読んでみると、「クラスターにはフェンシングを設定する必要があります」って書いてあった。
「いつフェンシング設定するんだろう?」って思ってたんだけど、実は先に設定する必要があったのね。

というわけで、fenceの設定を。

まずは、fence-agentsをインストールする。
(gemini) $ sudo apt-get install fence-agents
(cancer) $ sudo apt-get install fence-agents

で、フェンシングを設定するんだけど、どのフェンスデバイスがいいのか…。
(gemini) $ sudo pcs stonith list
gemini / cancer は kvm/libvirt で動かしているので、fence_virsh を使用するのがスジなんだけど…。
そもそも、今検証している gemini / cancer 環境は、物理マシン(sagittarius / aquarius)で正しく gfs2 を使用するための環境なので、物理マシンで使えるフェンスデバイスにする必要がある。
よく見てみたら、fence_scsi というタイプがある。これを使ってみよう。

とりあえず、gemini/cancer 両ノードで共有する1GBのディスクを追加しておく。
これをストレージフェンシングデバイスとして使用してみたい。

OSの再起動等をこなして、/dev/vdc として確認できたら、ストレージフェンシングデバイスを設定してみる。(できるのか?)
と思ったけど、ディスクデバイス側にpersistent reservationの機能が必要みたいで、virtoio 及び scsi passthrough では対応していないっぽい…。

となると、iSCSIデバイスを作ってみるのが正解か。
過去の記事などを参考に、gemini/cancerに1GBの共有iSCSI-LUNが接続されるようにしておく。
合わせて、/dev/vdc は解除しておこう。

で、色々試していってるんだが、どうやら /var/run/cluster/fence_scsi.key と /var/run/cluster/fence_scsi.dev という2つのファイルが必要っぽい。
ただ、/var/run は tmpfs なので、ココのファイルはOS再起動で消えてしまう。
自動で作ってくれる仕組みがあると思うんだが…。

とりあえず fence_scsi のフェンシングデバイスを作成する。
×(gemini) $ sudo pcs stonith create scsi-fence fence_scsi action=off devices=/dev/sda verbose meta provides=unfencing
(gemini) $ sudo pcs stonith create scsi-fence fence_scsi pcmk_host_list="gemini cancer" devices=/dev/sda verbose meta provides=unfencing
meta設定(provides=unfencing)は必要のようだ。

gemini で実行すれば、cancer 側からも確認できる。
(cancer) $ sudo pcs stonith show
 scsi-fence     (stonith:fence_scsi):   Stopped

デバイスとして指定した /dev/sda で、fence_scsi の情報を見てみる。
$ sudo fence_scsi -d /dev/sda -n gemini -o status -v
(略)
0   PR generation=0x0, there are NO registered reservation keys
No registration for key 2b4d0000 on device /dev/sda
Status: OFF

Status は OFF で、 PR の欄を見ると鍵情報が登録されていない。

gemini、cancer の両ノードで、鍵を登録してみる。
(gemini) $ sudo fence_scsi -o on -d /dev/sda -n gemini
(cancer) $ sudo fence_scsi -o on -d /dev/sda -n cancer

(gemini) $ sudo fence_scsi -d /dev/sda -n gemini -o status -v
0   PR generation=0x2, 2 registered reservation keys follow:
    0x2b4d0000
    0x2b4d0001
Status: ON

鍵情報が登録されて、Status が ON になった。

(gemini) $ sudo pcs stonith show
でも、まだ pacemaker 的には stop のままだ。

cleanup すればいいのだろうか…。
(gemini) $ sudo pcs stonith cleanup scsi-fence

実際には、色々試しているうちに動くところまで確認できた。
動き出したのはいいが、cancerで動いている。
(gemini) $ sudo pcs stonith show
 scsi-fence     (stonith:fence_scsi):   Started cancer

これはもしかして…。各ノードごとにフェンスの設定を入れて、自ノードでのみ稼働するように設定する必要があるのだろうか…。
#fence_virsh などはそのように定義する。2ノードクラスタなら良いのだが、3ノード以上のクラスタの場合はどうするんだろうか…?

やっぱりイマイチ分からん。
とりあえずこのまま進めていくか。