2017年2月28日火曜日

LVMの自動アクティベートを停止

前回の最後に、「OS起動時に当該LVOLが自動的にアクティベーションされないように設定する」って書いた。
これは、HAクラスタ等を組んでいる場合、共有ボリュームのアクティベーションはOS起動時ではなく、クラスタソフトの方で制御して欲しいからだ。
ただ、今回の構成・目的では、そちらの意味はあまり無い。
共有ファイルシステムを使用しているので、アクティベーションされるのなら共有モードでアクティベーションされて欲しいから、ちょっと使用目的は違う。
のだが、OS起動時の自動アクティベートを調べておきたい、というのが今回の目的。

てっきり、vgchange -aay / -aanというオプションで、自動アクティベートをOn/Off出来ると踏んでいたのだが、どうやら違うようだ。そもそも、-aanというオプションは存在しない模様。

vgchangeのマニュアルを読んでみると、-aay は /etc/lvm/lvm.confのactivation/auto_activation_volume_listに記載されているボリュームを、自動的にアクティベーションする、という意味のようだ。
/etc/fstabに記載されているエントリを一斉にマウントする、mount -a と同じような意味合いか。
逆に、activation/auto_activation_volume_list が未記載の場合は、全てのボリュームをアクティベートしてしまうようだ。

なるほど、システム起動時(OS起動時)にアクティベーションして欲しいボリュームを、activation/auto_activation_volume_list に記載して、アクティベーションして欲しくないボリュームを記載しないことで、OS起動時に自動アクティベートされないようになるようだ。

さっそく実験してみよう。

まずは、当該ボリュームをアンマウント・ディアクティベートしておく。
(gemini) $ sudo systemctl stop /mnt/ocfs2
(gemini) $ sudo systemctl stop /mnt/gfs2
(gemini) $ sudo vgchange -aln vg-ocfs2
(gemini) $ sudo vgchange -aln vg-gfs2
(gemini) $ sudo vgdisplay -v vg-ocfs2
(gemini) $ sudo vgdisplay -v vg-gfs2

一旦再起動して、vg-ocfs2/vg-gfs2が両方共アクティベートされるか確認だ。
(gemini) $ sudo shutdown -r now
(gemini) $ sudo vgdisplay -v vg-ocfs2
(gemini) $ sudo vgdisplay -v vg-gfs2
lvolがavailableになっているだろうか?

OSを構成するVGの名前を確認しておこう。
(gemini) $ sudo vgs
VG #PV #LV #SN Attr VSize VFree
gemini-vg 1 2 0 wz--n- 72.02g 32.00m
vg-gfs2 1 1 0 wz--nc 10.00g 5.00g
vg-ocfs2 1 1 0 wz--nc 10.00g 5.00g
geminiは、OSインストールメディアのお任せにしていたので、gemini-vgという名前のようだ。

続いて、/etc/lvm/lvm.confを以下のように書き換える。(今回は、vg-gfs2とvg-ocfs2で敢えて変えておく。vg-ocfs2を自動アクティベートされないようにしておく。)
(gemini) $ sudo vi /etc/lvm/lvm.conf
「activation {」で始まる行を探そう。
そのブロックの中に、auto_activation_volume_listの説明文がある。(こちらの環境では、1120行目あたりからだ。)
そのコメント文の下部(こちらの環境では、1156行目あたり)に、以下の行を追記しよう。
--ココから
auto_activation_volume_list = [ "gemini-vg", "vg-gfs2" ]
--ココまで

さて、これでイイのかな?
一旦、両ボリューム(vg-ocfs2/vg-gfs2)をディアクティベートしておく。
(gemini) $ sudo vgchange -aln vg-ocfs2
(gemini) $ sudo vgchange -aln vg-gfs2
(gemini) $ sudo vgdisplay -v vg-ocfs2
(gemini) $ sudo vgdisplay -v vg-gfs2

lvmの設定変更を反映させてみる。(これでいいのかな?)
(gemini) $ sudo systemctl daemon-reload

auto_activateを試してみる。
(gemini) $ sudo vgchange -aay

さてどうなったかな?
(gemini) $ sudo vgdisplay -v vg-ocfs2
(gemini) $ sudo vgdisplay -v vg-gfs2
お、狙ったとおり、vg-ocfs2はディアクティベートのまま、vg-gfs2はアクティベートされたぞ。

じゃ、OS起動時はどうだ?
(gemini) $ sudo vgchange -aln vg-gfs2
(gemini) $ sudo shutdown -r now
(gemini) $ sudo vgdisplay -v vg-ocfs2
(gemini) $ sudo vgdisplay -v vg-gfs2
期待したとおり、vg-ocfs2はディアクティベート、vg-gfs2はアクティベートだ。

これで、自動アクティベートの制御は分かった。
とりあえず、gemini/cancerともに、vg-ocfs2/vg-gfs2は自動アクティベートされないように設定しておこう。
(gemini) $ sudo vi /etc/lvm/lvm.conf
先程追記した行を書き換え。
--ココから
auto_activation_volume_list = [ "gemini-vg", "vg-gfs2" ]

auto_activation_volume_list = [ "gemini-vg" ]
--ココまで
(gemini) $ sudo systemctl daemon-reload

(cancer) $ sudo vgs
VG #PV #LV #SN Attr VSize VFree
cancer-vg 1 2 0 wz--n- 72.02g 32.00m
vg-gfs2 1 1 0 wz--nc 10.00g 5.00g
vg-ocfs2 1 1 0 wz--nc 10.00g 5.00g
OSのvgの名前はcancer-vgのようだ。

(cancer) $ sudo vi /etc/lvm/lvm.conf
1156行目付近に以下の行を追記。
--ココから
auto_activation_volume_list = [ "cancer-vg" ]
--ココまで
(cancer) $ sudo systemctl daemon-reload

さて今回はココまで。
次は、クラスタマーク付き(vgchange -cy)のvgに対してvgdisplayを実行したら表示される「Shared」の意味を調べてみよう。
(正直なところ、結論が出せるか自信がない。)

2017年2月26日日曜日

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

さて前回までで、CLVMのexclusive(排他)モードが使えるようになった。

今回は、shared(共有)モードの検証だ。
(というか、これが、今CLVMを使用したい最大の理由…)

sharedモードにすることで、以下のことが出来るんじゃないかと期待している。
  • 複数のノードで同時にアクティベート(これはCLVMじゃなくても出来るけど…)
  • VGの構成変更が、関連する全てのノードに自動通知(共有モードじゃなくて、クラスタマークで実現されているんじゃないかな?)
  • 全てのノードで受け入れられるVG構成変更でないと、変更がNGになる
  • ノード単位でアクティベート・ディアクティベート
目的は、複数のノードで仮想ディスク領域や仮想マシン定義領域を共有し、KVMを動かす、だ。
はっきり言って、これを実行するために、
  • 共有ファイルシステム(ocfs2/gfs2)
  • 共有ボリュームマネージャ(CLVM)
を検証していた。

というわけで、まずは準備だ。
前回停止しっぱなしのcancerの起動。(KVMホストから)
(sagittarius) $ virsh start cancer
(sagittarius) $ virsh list --all

両ノードで、ファイルシステムアンマウントとディアクティベート。
(gemini) $ sudo systemctl stop /mnt/ocfs2
(cancer) $ sudo systemctl stop /mnt/ocfs2
(gemini) $ sudo lvchange -a n vg-ocfs2/lv-ocfs
(gemini) $ sudo lvchange -aen vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(gemini) $ sudo vgdisplay vg-ocfs2
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo vgdisplay vg-ocfs2

ここから本番。
共有アクティベートしてみる。
(gemini) $ sudo lvchange -asy vg-ocfs2/lv-ocfs
(gemini) $ sudo vgdisplay vg-ocfs2
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
両ノードでアクティベートされている。

ちょっとノード単位のアクティベート・ディアクティベートを試してみよう。
(gemini) $ sudo lvchange -aln vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
geminiだけディアクティベートされた。

(gemini) $ sudo lvchange -aly vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
両ノードでアクティベート状態だ。

(gemini) $ sudo lvchange -an vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
両ノードでディアクティベート。

(gemini) $ sudo lvchange -aly vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
gemini側だけアクティベート。

(cancer) $ sudo lvchange -aly vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
cancer側でもアクティベートされた。(両ノードでアクティベート)

両ノードでマウントしてみる。
(gemini) $ sudo systemctl start /mnt/ocfs2
(cancer) $ sudo systemctl start /mnt/ocfs2
(gemini) $ df /mnt/ocfs2
(cancer) $ df /mnt/ocfs2
マウント出来る。
う~ん。なんか、sharedモードって、普通の(モードフラグを付けない)場合と同じ挙動だなぁ。

ちょっと、sharedモードとexcusiveモードの競合を試してみよう。
sharedモードでアクティベートされていたら、exclusiveモードではアクティベート出来ないはずだ。
まずはcancer側でアンマウント、ディアクティベート。
(cancer) $ sudo systemctl stop /mnt/ocfs2
(cancer) $ df /mnt/ocfs2
(cancer) $ sudo lvchange -aln vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
gemini側でも状態を確認しておこう。(マウントしているので、ディアクティベートはされていないはず。)
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs

cancer側でexclusiveモードでアクティベート。
(cancer) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
Error locking on node 40a83789: Volume is busy on another node
やっぱりエラーになった。予想通り。

とりあえず、cancer側でアクティベートとマウントしておこう。
(cancer) $ sudo lvchange -asy vg-ocfs2/lv-ocfs
(-asyでも-alyでも同じようだ…)
(cancer) $ sudo systemctl start /mnt/ocfs2
(cancer) $ df /mnt/ocfs2

さて、続いてCLVMで期待している機能の確認だ。
geminiにのみディスクを追加し、gemini/cancer両方で共有しているvg(vg-gfs2/vg-ocfs2)に対し、そのディスクで拡張処理をしてみたいと思う。
ここでは、エラーになって拡張できない結果になるのを期待している。

まずは、KVMホストからvirt-managerを起動し、geminiに10GB程度のディスクを追加しよう。(接続方式はvirt-io形式にした)
追加出来たら、gemini側でデバイスの確認だ。
(gemini) $ dmesg
あれ?dmesgではデバイス名が分からない?
(gemini) $ ls -l /dev/vd*
/dev/vddというデバイスが追加されている。これが新しく足したデバイスだろう。
(gemini) $ lsblk
vddは何も使用されていないディスクだ。

さて、こいつをvg-ocfs2に拡張してみよう。
まずはパーティションの作成。(パーティションを作る必要は無いんだけどね。)
(gemini) $ sudo parted /dev/vdd print
(gemini) $ sudo parted /dev/vdd mklabel gpt
(gemini) $ sudo parted /dev/vdd print
(gemini) $ sudo parted /dev/vdd mkpart primary 0% 100%
(gemini) $ sudo parted /dev/vdd print
(gemini) $ sudo parted /dev/vdd set 1 lvm on
(gemini) $ sudo parted /dev/vdd print

続いて、pvの作成
(gemini) $ sudo pvcreate /dev/vdd1

で、vg-ocfs2に今作成したpvを追加してみる。
まずはテストモードで実行。
(gemini) $ sudo vgextend -t vg-ocfs2 /dev/vdd1
あれ?出来てしもーた。
まさか…
(gemini) $ sudo vgextend vg-ocfs2 /dev/vdd1
出来ちゃったよ…???
(gemini) $ sudo vgdisplay -v vg-ocfs2
確かに、vdb1とvdd1で構成されているし、容量も約20GBある…。

これだと、cancer側でどう見えるんだ…?
(cancer) $ sudo vgdisplay -v vg-ocfs2
おっと、なるほど。見えないデバイスが使われている、ということでgemini側では/dev/vdd1と表示されているところが「unknown device」と表示されるのか。

ちょっとこれではマズイなぁ。
いや、違うか…。今回はcancerを起動しっぱなしで、gemini側を操作したので、gemini/cancer間でディスクの状態を相互確認してくれると思っていたんだけど、よく考えてみたら、必ずクラスタノードが全て生きている、とは限らないのか。
その状態でも、生きているノードにディスクを拡張する、というアクションが起きないとは限らない。
であれば、今回cancerがダウンしていても、gemini側で操作が完結出来ないといけないか。

とすれば、vg拡張後、必要な各ノードで全てvgdisplayを実行して、各ノードがディスクを正しく認識しているか確認する、という手作業が必要だ、ということだな。

壊れることを覚悟して、ofs2のlvol(vg-ocfs2/lv-ocfs)を、新しく追加したpv(/dev/vdd1)に拡張してみよう。
(gemini) $ sudo lvextend -L+1G -v vg-ocfs2/lv-ocfs /dev/vdd1
Finding volume group vg-ocfs2
Archiving volume group "vg-ocfs2" metadata (seqno 4).
Extending logical volume vg-ocfs2/lv-ocfs to 6.00 GiB
Size of logical volume vg-ocfs2/lv-ocfs changed from 5.00 GiB (1280 extents) to 6.00 GiB (1536 extents).
Error locking on node 40a83789: Aborting. LV lv-ocfs is now incomplete and '--activationmode partial' was not specified.
Failed to lock logical volume vg-ocfs2/lv-ocfs.
おっと!エラーになったぞ!
そうか、VGレベルではエラーにならず、LVレベルでエラーになるのか。

ここで更に実験だ。
対向ノードであるcancerで/dev/vdd1が見えていないから、そのlvolの拡張に失敗したわけだけど、cancerがダウンしていたらどうなんだろうか?
というわけで、cancerを停止してみる。
普通にシャットダウンでいいぞ。
(cancer) $ sudo shutdown -h now

cancerが停止したら、gemini側で先程と同様、LVを拡張してみる。
(gemini) $ sudo lvextend -L+1G -v vg-ocfs2/lv-ocfs /dev/vdd1
今度は成功したようだ。
確認してみよう。
(gemini) $ sudo vgdisplay -v vg-ocfs2
lv-ocfsは6GBまで拡張されていて、/dev/vdd1もPEを消費している。

ふむ。この状態でcancerを起動、当該ボリュームをアクティベートしようとしたら、当然エラーになるはずだよな。
cancerの起動(KVMホストから)
(sagittarius) $ virsh start cancer
(sagittarius) $ virsh list --all

cancerで当該LVMの状態確認。
(cancer) $ sudo vgdisplay -v vg-ocfs2
先程と同様、pvが1つ見えない状態だ。
lvolもアクティベートされていない。

んじゃぁ、lvolアクティベート(エラーになるはず。)
(cancer) $ sudo lvchange -asy vg-ocfs2/lv-ocfs
Couldn't find device with uuid 9Vn0Br-4wpP-gYLm-YOfe-6SK8-B6qx-H2D0n4.
Error locking on node 40a83789: Refusing activation of partial LV vg-ocfs2/lv-ocfs. Use '--activationmode partial' to override.
エラーになったな。ん?「Use '--activationmode partial'」というアドバイスも出た。
なるほど、何らかの要因で、lvolを構成するボリュームが足りない場合、--activationmode partialというオプションを使うことも可能か。
だけどこの場合、
  • ミラーlvolが片肺運転
  • raid5で構成されたlvolで、1つだけpvが見えない場合
等に使用するオプションだろう。今回のパターンでは、使用しても意味がない。

では、cancerからは見えないディスクを、cancer側にも見せたらどうなるんだろうか?
KVMホストのvirt-managerから、geminiに追加したディスクを、cancer側にも接続してみよう。(ワーニングが出るが無視してOK)

さっそく、cancerで確認だ。
(cancer) $ sudo lvchange -asy vg-ocfs2/lv-ocfs
Error locking on node 40a83789: Refusing activation of partial LV vg-ocfs2/lv-ocfs. Use '--activationmode partial' to override.
あれ?エラーになった。

LVM構成情報が同期取れてないんじゃないかな?
ディスク関係を再度チェック。
(cancer) $ dmesg
(cancer) $ ls -l /dev/vd*
(cancer) $ lsblk
(cancer) $ sudo vgscan -v

もう一度アクテイベート
(cancer) $ sudo lvchange -asy vg-ocfs2/lv-ocfs
出来た。

どうやら、共有化(クラスタ化)することで出て来る制約は、vgレベルで制御かかるかと思ったんだけど、lvレベルで制御がかかるのね。
個人的にはちょっと遅い気がするけど、そういうもの、と思って運用していけばいいだけか。

もう少し実験していく。今度は両ノードが生きている状態で、lvの縮小とpvの削除だ。
cancer側でマウント出来ていないはずなので、先にマウントしておく。
(cancer) $ sudo systemctl start /mnt/ocfs2
(cancer) $ df /mnt/ocfs2

続いて、lvの縮小。(ファイルシステム自体は拡張していないので、ファイルシステム操作は今回不要だ。)
(gemini) $ sudo lvreduce -L-1G vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
lvdisplayの出力結果のうち、Segumentsが2から1に減っているはずだ。
これは、「いくつのPVにまたがっているか?」という情報で、今まではこのlvolは/dev/vdb1と/dev/vdd1の両方にまたがっていた。
これが、/dev/vdb1のみに縮小されたため、Segmentsも1になった、というわけだ。
もし、Segmentsが2のままだったら、pvmoveコマンド等で、使用している領域を/dev/vdb1に集め直さないと行けない。
今回は/dev/vdb1に集まったので、pvmoveは不要だ。

次は、vg-ocfs2から/dev/vdd1を切り離す。
念のため、/dev/vdd1の領域が未使用なのを確認する。
(gemini) $ sudo pvdisplay /dev/vdd1
(cancer) $ sudo pvdisplay /dev/vdd1
Total PEとFree PEの値が同じで、Allocated PEが0なら、このPVはどのLVにも割当たってない、ということだ。

というわけで、vg-ocfs2から/dev/vdd1を切り離そう。
テストモードから。
(gemini) $ sudo vgreduce -t -v vg-ocfs2 /dev/vdd1
問題無さそうだ。
では実際に実行。
(gemini) $ sudo vgreduce -v vg-ocfs2 /dev/vdd1

成功したか確認してみよう。
(gemini) $ sudo vgdisplay -v vg-ocfs2
(gemini) $ sudo pvdisplay -v /dev/vdd1
cancer側にも反映されているか確認。
(cancer) $ sudo vgdisplay -v vg-ocfs2
(cancer) $ sudo pvdisplay -v /dev/vdd1
切り離し成功。

とりあえず、このディスクは一旦使わないので、切り落としてしまおう。
PV情報の削除。
(gemini) $ sudo pvremove /dev/vdd1
(gemini) $ sudo pvdisplay /dev/vdd1
(cancer) $ sudo pvdisplay /dev/vdd1

パーティションの削除。
(gemini) $ sudo parted /dev/vdd print
(gemini) $ sudo parted /dev/vdd rm 1
(gemini) $ sudo parted /dev/vdd print

(cancer) $ sudo partprobe /dev/vdd
(cancer) $ sudo parted /dev/vdd print
(cancer) $ ls -l /dev/vdd*

ディスクデバイスの削除。(virtioデバイスの場合の記述。virtioではなく、仮想SCSIの場合は、この辺りに記載しているので参考に。)
(gemini) $ ls -l /sys/block/vdd/device
virtio6へのシンボリックリンクであることを確認。
(gemini) $ sudo bash -c "echo virtio6 > /sys/bus/virtio/drivers/virtio_blk/unbind"
(gemini) $ ls -l /dev/vdd*
(gemini) $ lsblk
vddが無くなったはずだ。

同様にcancerも。
(cancer) $ ls -l /sys/block/vdd/device
こちらもvirtio6だ。
(cancer) $ sudo bash -c "echo virtio6 > /sys/bus/virtio/drivers/virtio_blk/unbind"
(cancer) $ ls -l /dev/vdd*

両OSからデバイスを削除したら、KVMホストからもvirt-managerを使って、当該ディスクを外しておこう。

今回、がっつり長くなってしまった。
Shared関係を一気に書いてしまったからだ。

ただ、ずっと気になっている点がある。
clusterマークを付与したvgに対し、vgdisplayを実行すると、Clusterdはyesと出るが、Sharedがnoのまま。
これ、何のフラグなんだろうか?
結構重要なポイントな気がしてならない。

次回はまず、OS起動時に当該LVOLが自動的にアクティベーションされないように設定するのを目指し、その次に、このvgdisplayのSharedステータスを調査したい。

ここまでやったら、CLVM関連はオシマイかな?

2017年2月23日木曜日

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

前回、2ノードクラスタで片系ダウンした時のLVMの操作問題が解決出来た、かのように見える。
でも実際は、まだ問題を抱えている。

以下の手順を実施してみるとその問題に直面する。
  1. 両ノード(gemini/cancer)起動。
  2. geminiでファイルシステムマウント。
  3. cancerを強制停止。(障害を想定)
  4. cancerがダウンしている状態で、geminiを再起動。
  5. geminiで必要に応じてファイルシステムマウント。
3番までは前回の作業と同じ。
ただ、実際にはcancerの障害が修復しきれないうちに、geminiをメンテナンスで再起動(4)させないといけない、ということは想定できる。
この時、gemini再起動後に正しくファイルシステムマウントが出来ない(5)と思われる。

実際にやってみよう。
まずは両ノード起動していること。
続いて、gemini側でファイルシステムをマウントする。
(cancer) $ sudo systemctl stop /mnt/ocfs2
(cancer) $ sudo lvchange -an vg-ocfs2/lv-ocfs
(gemini) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
(gemini) $ sudo systemctl start /mnt/ocfs2
(gemini) $ df /mnt/ocfs2

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

geminiでディスク状態を確認
(gemini) $ df /mnt/ocfs2
(gemini) $ ls -l /mnt/ocfs2
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs

(メンテナンスを想定して)geminiを再起動
(gemini) $ sudo systemctl stop /mnt/ocfs2
(gemini) $ sudo lvchange -a n vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(gemini) $ sudo shutdown -r now

geminiでファイルシステムを使用する
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
ここでハングしてしまう。

このタイミングでは、geminiで当該ディスクが利用できる状態、というのが理想だが、現実はこのような状態。(cancerを起動させれば、geminiでディスクを利用することが出来る。)
これでは、とても不便だ。

で、このあたりを制御するcorosyncパラメータが、wait_for_allだと考えられる。

とりあえず、復帰させるためにcancerを起動させよう。(KVMホスト側から)
(sagittarius) $ virsh start cancer
(sagittarius) $ virsh list --all

とりあえずgeminiでディスクを使っている状態にする。
(cancer) $ sudo lvchange -a n vg-ocfs2/lv-ocfs
(gemini) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
(gemini) $ sudo systemctl start /mnt/ocfs2
(gemini) $ df /mnt/ocfs2

さて、じゃぁcorosyncのwait_for_allについて確認してみよう。
まずはman。
(gemini) $ man 5 votequorum
これを見てみると、以下のことが分かる。
  • デフォルトは0
  • two_nodeを1に設定すると、wait_for_allも自動的に1に設定される。
    (ただし、別途0にすることは可能。)
  • wait_for_allが1になっている場合、全てのノードが同時に稼働状態にならないと、corosyncが稼動状態にならない。
    (wait_for_allが0の場合は、稼動状態のノード数が、ノード全数の過半数に到達した段階でcorosyncが稼働状態になる。)
2ノードクラスタの場合、2ノードとも稼動状態にならないとサービス開始出来ないようだ。
スプリットブレイン発生時等を考えれば、この仕様は正しいと思うけど、これではちょっと運用し辛い。

今回はHAクラスタではなく、使うリソースは共有ファイルシステムだけなので、「両方のノードで同時にサービスが起動して、ファイルシステムが壊れてしまう」等のトラブルは考えなくていい、はず。

であれば、wait_for_allの機能は不要なので、0に変えてみたらどうだろうか…。
どうせ実験環境なので、試してみよう。
両ノード、とりあえずアンマウントとファイルシステムのディアクティベートを実施。
(gemini) $ sudo systemctl stop /mnt/ocfs2
(cancer) $ sudo systemctl stop /mnt/ocfs2
(gemini) $ sudo lvchange -a n vg-ocfs2/lv-ocfs
(cancer) $ sudo lvchange -a n vg-ocfs2/lv-ocfs

/etc/corosync/corosync.confを修正
(gemini) $ sudo vi /etc/corosync/corosync.conf
「quorum{}」の中、「two_node: 1」を追記した下に、「wait_for_all: 0」を追記する。
(cancer) $ sudo vi /etc/corosync/corosync.conf
geminiと同様の変更を施す。

設定読み直し。(これで反映されるのかなぁ?)
(gemini) $ sudo systemctl daemon-reload
(cancer) $ sudo systemctl daemon-reload

上で実施したことを試してみよう。
gemini側でファイルシステムをマウントする。
(cancer) $ sudo systemctl stop /mnt/ocfs2
(cancer) $ sudo lvchange -an vg-ocfs2/lv-ocfs
(gemini) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
(gemini) $ sudo systemctl start /mnt/ocfs2
(gemini) $ df /mnt/ocfs2

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

geminiでディスク状態を確認
(gemini) $ df /mnt/ocfs2
(gemini) $ ls -l /mnt/ocfs2
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs

(メンテナンスを想定して)geminiを再起動
(gemini) $ sudo systemctl stop /mnt/ocfs2
(gemini) $ sudo lvchange -a n vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(gemini) $ sudo shutdown -r now

geminiでファイルシステムを使用する
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
先程はここでハングしてしまったが、今回は問題なく見える。
この時点ではアクティベートされているが、これは
  • 当該lvolは他のノードは掴んでいない
  • OS(gemini)は起動時にこのlvolをアクティベートする
の2つの状態のため。(2番目の件は別途検討予定)

とりあえず、排他モードでアクティベートし直して、普通にI/O出来るか確認。
(gemini) $ sudo lvchange -a n vg-ocfs2/lv-ocfs
(gemini) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
(gemini) $ sudo systemctl start /mnt/ocfs2
(gemini) $ df /mnt/ocfs2
(gemini) $ ls -l /mnt/ocfs2
内容確認出来るので、適当にI/Oしておこう。

問題無さそう。

2ノードクラスタ&排他制御が必要の場合は、この実装か?
ただ、auto_tie_breakerとauto_tie_breaker_nodeというパラメータも気になる。
調べておきたいけど、後回しでいいかなぁ?

後回しにして、アクティベートフラグのs(-asy/-asn)を実験しよう。

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も確認しないといけないっぽいが…)

2017年2月20日月曜日

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

さて、検証していく過程で、何度かOS再起動が発生する可能性がある。
その都度、OSが共有ボリュームを自動マウントしようとすると、ちょっと不都合が生じる恐れがある。

まずはgemini/cancerの両ノードで、ボリュームの自動マウントが行われないようにしておこう。

まずはgemini/cancerで、アンマウントしておく。
(gemini) $ df
(gemini) $ sudo systemctl stop /mnt/gfs2
(gemini) $ sudo systemctl stop /mnt/ocfs2
(gemini) $ df

(cancer) $ df
(cancer) $ sudo systemctl stop /mnt/gfs2
(cancer) $ sudo systemctl stop /mnt/ocfs2
(cancer) $ df

続いて、両方のVGのディアクティベート(これは片方のノードで実施すればOK)
(gemini) $ sudo vgchange -a n vg-ocfs2
(gemini) $ sudo vgchange -a n vg-gfs2

続いて、OS起動時に自動マウントされないように手を加える。
(gemini) $ sudo vi /etc/fstab
/mnt/ocfs2と/mnt/gfs2のマウントオプションに、noautoを付与する。
--ココから
/dev/mapper/vg--ocfs2-lv--ocfs /mnt/ocfs2 ocfs2 _netdev,x-systemd.requires=o2cb.service 0 0
/dev/mapper/vg--gfs2-lv--gfs /mnt/gfs2 gfs2 _netdev,x-systemd.requires=dlm.service 0 0
↓この2行にnoautoを付与
/dev/mapper/vg--ocfs2-lv--ocfs /mnt/ocfs2 ocfs2 noauto,_netdev,x-systemd.requires=o2cb.service 0 0
/dev/mapper/vg--gfs2-lv--gfs /mnt/gfs2 gfs2 noauto,_netdev,x-systemd.requires=dlm.service 0 0
--ココまで

(cancer) $ sudo vi /etc/fstab
geminiと同じように修正する。

systemdに変更結果を反映させる。
(gemini) $ sudo systemctl daemon-reload
(cancer) $ sudo systemctl daemon-reload

両ノードを再起動して、マウントされていないかを確認する。
(gemini) $ sudo shutdown -r now
(cancer) $ sudo shutdown -r now

(gemini) $ df
(cancer) $ df

さて、どのようなアクティベートフラグがあるかを確認、という流れだけど、その前に1つ、再起動直後のvg-ocfs2とvg-gfs2の状態を確認しておきたい。
どちらのノードからでも構わない。
(gemini) $ sudo vgdisplay vg-ocfs2
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs

(gemini) $ sudo vgdisplay vg-gfs2
(gemini) $ sudo lvdisplay vg-gfs2/lv-gfs

lvdisplayの出力結果のうち、「LV Status」が、どちらのVGもavailableになっていると思う。
これはOS起動時に、当該LVがアクティベートされた、ということだ。
さて、これはいいことなのだろうか?
一応、現在の挙動はこのようになっている、と言う点は覚えておこう。

で、いよいよアクティベートフラグの確認だ。
lvchangeのmanを見ると、アクティベートに関しては以下のようになっている。
[-a|--activate [a][e|s|l]{y|n}]

また、vgchangeのmanはどうかと言うと…
[-a|--activate   [a|e|s|l]   {y|n}]

微妙に記述は違うが、似たような感じだ。

lvchangeの方のオプション表記は
  • aの有無
  • e/s/lのいずれかもしくは無し
  • yかnのいずれか
のパターンのようだ。
ちょっと複雑だぞ…。(2*4*2=16パターンか?)
でも、マニュアルエントリ上は、以下のパターンしか記載が無いな。
  • -a [y|n]
  • -aa [y|n]
  • -ae [y|n]
  • -as [y|n]
  • -al [y|n]
vgchangeのマニュアルエントリも同じようだ。

マニュアルを見る限り、以下のような感じになっている。
  • -a [y|n]
    activationする、解除する
  • -aay
    autoactivationする
    このオプションは、-aanについて言及されてない。なんだ?
  • -ae[y|n]
    exclusiveモード(排他モード)でactivationする、解除する
  • -as[y|n]
    sharedモード(共有モード)でactivationする、解除する
  • -al[y|n]
    当該のノードでのみactivationする、解除する
で、-a、-ae、-asは全てのノードに影響する、ということのようだ。
このあたりは、vgchangeも同じになっている。

一つずつ試してみよう。
まずは、gemini/cancerどちらでもactivateされていることを確認する。
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
「LV Status」が「available」なのを確認。

gemini側でdeactivateする。
(gemini) $ sudo lvchange -a n vg-ocfs2/lv-ocfs

gemini/cancerでステータスを確認する。
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
「LV Status」が「NOT available」になったのが確認できたはずだ。

このまま、-aaを確認してみよう。
ただ、autoactivateに関しては、/etc/lvm/lvm.confに記載があるはずなので、コマンドで実行するとなると、どのような変化が現れるか…。
まずは、/etc/lvm/lvm.confをコピっておこう。
(gemini) $ cp -i /etc/lvm/lvm.conf ~/lvm.conf
(cancer) $ cp -i /etc/lvm/lvm.conf ~/lvm.conf

続いて、gemini側で-aaを実行してみる。
(gemini) $ sudo lvchange -aay vg-ocfs2/lv-ocfs

ステータスの確認
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
gemini側は「LV Status」が「available」になった。でもcancer側は「NOT available」のままだ。
違いが分からない…。

(gemini) $ diff ~/lvm.conf /etc/lvm/lvm.conf
(cancer) $ diff ~/lvm.conf /etc/lvm/lvm.conf
差分は無い。

とりあえず、gemini側で-aanをやってみる。
(gemini) $ sudo lvchange -aan vg-ocfs2/lv-ocfs
Invalid argument for --activate: an
Error during parsing of command line.
お?エラーになった。-aanってオプションは無いのか?

gemini側だけactivationされてしまったので、一旦deactivateしておく。
(gemini) $ sudo lvchange -an vg-ocfs2/lv-ocfs

-aayについてはちょっと良く分からなかったので一旦保留。

続いて、-aeだ。
(gemini) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
これも、gemini側はavailableに変化、cancer側はNOT availableのまま、だ。

排他モードなら、cancer側ではアクティベーション出来ないはずだ。
(cancer) $ sudo lvchange -a y vg-ocfs2/lv-ocfs
Error locking on node UNKNOWN 1084766088: Device or resource busy
Error locking on node 40a83789: Volume is busy on another node
予想通り。

(cancer) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
Error locking on node 40a83789: Volume is busy on another node
こちらも予想通り。

(cancer) $ sudo lvchange -aay vg-ocfs2/lv-ocfs
Error locking on node 40a83789: Volume is busy on another node
同じだ。

cancer側でdeactivate出来るのか?
(cancer) $ sudo lvchange -a n vg-ocfs2/lv-ocfs
あれ?通った。

(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
おっと、「NOT available」になった。

この状態でcancer側で排他モードは使えるのか?
(cancer) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
出来た。

う~む。排他モードでアクティベートした場合、他のノードではアクティベート出来ないが、強制的にディアクティベートすることは可能なのかな?
(gemini側でマウント等していなかったので…。もしgemini側でマウントされていたらどうなるのだろうか?)

というわけで、cancer側でアクティベートされているので、そのままマウントして、gemini側でディアクティベートしかけてみよう。
(cancer) $ sudo systemctl start /mnt/ocfs2
(cancer) $ df /mnt/ocfs2
(gemini) $ sudo lvchange -a n vg-ocfs2/lv-ocfs
Error locking on node 40a83789: Logical volume vg-ocfs2/lv-ocfs contains a filesystem in use.
なるほど、ファイルシステムを使用しているよ、ということでディアクティベート出来ないのか。

この状態でcancerが強制的にダウンしてしまった場合はどうなんだろう?
KVMホスト側で、cancerを強制的に止めてみる。
(sagittarius) $ virsh destroy cancer
(sagittarius) $ virsh list --all
止まった。

gemini側で仕掛けてみる。
(gemini) $ sudo lvchange -a n vg-ocfs2/lv-ocfs
あれ?反応が無い。ハングした模様…。
とりあえず、もう1セッション開いて、lvchangeのプロセスをkillしておいた。

じゃぁアクティベートは出来るんかいな?
(gemini) $ sudo lvchange -aey vg-ocfs2/lv-ocfs
ダメだな…。
もう一回killしておく。

そもそも、通常のアクティベートは?
(gemini) $ sudo lvchange -a y vg-ocfs2/lv-ocfs
これもダメか…。

じゃぁローカルアクティベートは?
(gemini) $ sudo lvchange -aly vg-ocfs2/lv-ocfs
これもダメ…。

う~ん。これはちょっとマズいねぇ。
排他モードは解除できるのか?
(gemini) $ sudo lvchange -aen vg-ocfs2/lv-ocfs
これもダメ。

っていうか、LVのステータスすら確認できなくなっちゃった。
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs

これだと、HAクラスタでアクティブノードがダウンした時、速やかにスタンバイノードでサービス再開出来ないなぁ。

もう少し調査を進めるにしても、一旦元に戻しておきたいので、cancerを起動して復帰したか確認しよう。
(sagittarius) $ virsh start cancer
(gemini) $ sudo lvdisplay vg-ocfs2/lv-ocfs
(cancer) $ sudo lvdisplay vg-ocfs2/lv-ocfs
「LV Status」が「available」になっているのが確認できた。

長くなったので一旦ココで切る。

2017年2月18日土曜日

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

LVMはその仕様上、活性化(アクティベート)・非活性化(ディアクティベート)という概念がある。
論理ボリュームを作成しても、アクティベートしないとその論理ボリュームにI/O出来ない、という仕様だ。
LinuxのLVM2では、VGごとアクティベート・ディアクティベートする方法(vgchange -a)の他に、LV(Logical Volume)単位でアクティベート・ディアクティベートする方法(lvchange -a)もある。

Hewlett Packard Enterprise社が販売しているHP-UXというOSでは、LVMのVGにクラスタマークを付与(vgchange -c y)すると、通常のアクティベート(vgchange -a y)が出来なくなり、排他モードという形でしかアクティベート(vgchange -a e)出来なくなる。
また、クラスタマークが付与されている場合、クラスタリングソフトであるServiceGuardが起動していないと、排他モードでもアクティベート出来なくなる。

HAクラスタを構築した場合、複数のノード(サーバ)で同じディスクボリュームをアクティベート出来てしまうと、複数のサーバから同時書き込みが出来ることになる。
それにより、ボリュームの中身が破壊されてしまう可能性があり、ミッションクリティカルな用途ではそのようなリスクは到底許容できない。
HP-UXの場合、そのようなリスクを回避するために、クラスタマークが付与されているVGは、常にひとつのノードでしかアクティベート出来ない仕様になっている。
恐らく、IBM社のAIXでも、同様の仕組みが備わっていると思われる。

サーバA、サーバBが同一の共有ボリュームを持っていた場合、サーバAでそのボリュームをアクティベート、I/Oしていたとして、そのサーバAが障害でダウンした後は、サーバBでそのボリュームをアクティベート、I/Oする、という感じだ。

ただ、時代は既に変わっていて、Oracle社のOracleDB RACのように、「同一ボリュームに対し、複数のサーバが協調しながらI/Oを行う」という要件も出てきた。
そのため、現在のHP-UXのLVMは多分、クラスタマークの付与・アクティベーションのオプションの組み合わせで、複数のノードでアクティベート出来る仕様になっているはずだ。

さて、振り返ってLinux(Ubuntu)はどうか、というと…。
これまで試してきた通り、クラスタマークの有無に関わらず、複数のノード(今回はgemini/cancerの2ノード)で同時にアクティベート出来た。
逆に言うと、「VG/LVの排他制御」が働いていない状態だ。

きっとこれは、本来の使い方とは異なると思う。

そこで、クラスタマークの付与とアクティベートのオプション(フラグ)について再確認しよう、というのが今回から。

実際には次回記事からこの辺りを実験・検証していきたいと思う。

共有FSマウント変更

前回、CLVMが動くところまではナントカしたけど、よく考えてみたらcancer側でファイルシステムマウント関連の設定を施してなかった。

ココとかココとかココとかだ。

これらgeminiに適用した変更内容を、cancer側にも適用しておく必要がある。

というわけで以下の通り。
まずはファイルシステム(/mnt/ocfs2と/mnt/gfs2)がマウントされていないことを確認。
(cancer) $ df
多分、マウントされていないと思うけど、現時点でマウントされていたら、アンマウントしておく必要がある。もしアンマウントに失敗したら、強制再起動しないといけない。

fstabにマウントエントリを書く
(cancer) $ sudo vi /etc/fstab
以下の行を追記する
--ココから
/dev/mapper/vg--ocfs2-lv--ocfs /mnt/ocfs2 ocfs2 _netdev,x-systemd.requires=o2cb.service 0 0
/dev/mapper/vg--gfs2-lv--gfs /mnt/gfs2 gfs2 _netdev,x-systemd.requires=dlm.service 0 0
--ココまで

書き終わったら、設定をsystemdに反映させる。
(cancer) $ sudo systemctl daemon-reload

反映が終わったら、マウント出来るか確認。
(cancer) $ df
(cancer) $ sudo systemctl start /mnt/ocfs2
(cancer) $ sudo systemctl start /mnt/gfs2
(cancer) $ df

マウント出来たのが確認できたら、一応OSを再起動して、再起動後に自動マウントされるか確認。
(cancer) $ sudo shutdown -r now
(cancer) $ df

これでオシマイかと思ったけど、ocfs2の領域がマウントされていない。
gemini側でアクティベートされているのが原因かと思い、色々試してみたんだが、ちょっと原因が不明。

一度、gemini側でアンマウント、ディアクティベート、アクティベート、マウント、の流れを行ったら、cancer側でも問題なくマウント出来るようになった。
もしかしたら、CLVM関連を操作していく過程で、情報の同期が上手く行かなかったのかもしれない。
(gemini) $ df
(gemini) $ sudo systemctl stop /mnt/ocfs2
(gemini) $ sudo vgchange -a n vg-ocfs2
(gemini) $ sudo vgchange -a y vg-ocfs2
(gemini) $ sudo systemctl stop /mnt/ocfs2
(gemini) $ df

本来なら、LVM→CLVM→ファイルシステムという順に作成(操作)していくのを、今回はVG→ファイルシステム→CLVMという順に操作していったため、何か不具合が生じたんじゃないかと。

気になるのなら、gemini/cancerともに停止して、完全停止後に両方を起動して、マウントされるか確認しておいた方がいいかな。

今後、色々実験していく中で、同じような症状が出るかもしれないが、その時にまた考えることにしよう。

2017年2月17日金曜日

CLVMに挑戦(その2)

前回(厳密には前々回)、やっとgeminiでCLVMが動くようになった。多分…。

で、同じボリュームを共有しているcancer側でも同じようにCLVMを稼働させないと意味がない。
また、geminiでCLVMを動かす過程でバタバタして、情報がきれいに纏まらなかったので、cancerで設定を施すついでに整理しておく。

まずはインストール
(cancer) $ sudo apt-get update
(cancer) $ sudo apt-get --simulate install clvm
(cancer) $ sudo apt-get install clvm

LVMの設定情報更新
(cancer) $ ls -l /etc/lvm/
(cancer) $ sudo lvmconf --enable-cluster
(cancer) $ ls -l /etc/lvm/
このタイミングで、lvm.conf.lvmconfoldが出来るのか…。
(cancer) $ sudo diff /etc/lvm/lvm.conf.lvmconfold \
/etc/lvm/lvm.conf
差分結果
--ココから
683c683
< locking_type = 1
---
> locking_type = 3
852c852
< use_lvmetad = 1
---
> use_lvmetad = 0
--ココまで

(cancer) $ sudo lvmconfig --type diff
出力
--ココから
global {
locking_type=3
use_lvmetad=0
}
devices {
cache_dir="/run/lvm"
issue_discards=1
}
--ココまで

謎のダミーファイル(とダミーディレクトリ)作成
(cancer) $ ls -ld /etc/cluster
ディレクトリは無いはず。
(cancer) $ sudo mkdir /etc/cluster
(cancer) $ sudo touch /etc/cluster/cluster.conf
(cancer) $ ls -l /etc/cluster

systemd用設定ファイル「lvm2-cluster-activation.service」の修正
(cancer) $ cd /lib/systemd/system
(cancer) $ sudo cp -pi lvm2-cluster-activation.service \
lvm2-cluster-activation.service.orig
(cancer) $ ls -l lvm2-cluster-activation*

(cancer) $ sudo vi lvm2-cluster-activation.service
以下のように修正
--ココから
After=lvm2-clvmd.service lvm2-cmirrord.service
↓(コメント化して、lvm2-cmirrord.serviceを削除した行を作成)
#After=lvm2-clvmd.service lvm2-cmirrord.service
After=lvm2-clvmd.service

EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
↓(コメント化)
#EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
--ココまで

(cancer) $ diff lvm2-cluster-activation.service.orig \
lvm2-cluster-activation.service
差分結果
--ココから
4c4,5
< After=lvm2-clvmd.service lvm2-cmirrord.service
---
> #After=lvm2-clvmd.service lvm2-cmirrord.service
> After=lvm2-clvmd.service
12c13
< EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
---
> #EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
--差分結果ココまで

続いて、「lvm2-clvmd.service」の修正
(cancer) $ sudo cp -pi lvm2-clvmd.service \
lvm2-clvmd.service.orig
(cancer) $ ls -l lvm2-clvmd*

(cancer) $ sudo vi lvm2-clvmd.service
以下のように修正
--ココから
EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
↓(コメント化)
#EnvironmentFile=-${prefix}/etc/sysconfig/clvmd

ExecStart=/sbin/clvmd $CLVMD_OPTS
↓(この行はコメントにし、パスを/usr/sbin/clvmdにした行を作成
#ExecStart=/sbin/clvmd $CLVMD_OPTS
ExecStart=/usr/sbin/clvmd $CLVMD_OPTS
--ココまで

(cancer) $ diff lvm2-clvmd.service.orig \
lvm2-clvmd.service
差分結果
--ココから
16,17c16,18
< EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
< ExecStart=/sbin/clvmd $CLVMD_OPTS
---
> #EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
> #ExecStart=/sbin/clvmd $CLVMD_OPTS
> ExecStart=/usr/sbin/clvmd $CLVMD_OPTS
--差分結果ココまで

サービス定義読み直し
(cancer) $ sudo systemctl daemon-reload
(cancer) $ ps -ef | grep clvmd
あれ…?この流れでいいのかと思ったけど、やっぱりダメだった。

というわけで、コマンド追加
(cancer) $ sudo lvmconf --enable-cluster --services --startstopservices
(cancer) $ ps -ef | grep clvmd
これで成功かな?
もしかしたら、前の方の sudo lvmconf --enable-cluster は実施不要かもしれない。

起動(起動確認)
(cancer) $ systemctl status lvm2-cluster-activation.service
(cancer) $ systemctl status lvm2-clvmd.service

クラスタマークの確認(既にgeminiでクラスタマークを付与しているはず)
(cancer) $ sudo vgdisplay vg-ocfs2
「Clustered yes」の文字が出て来るのが確認できる。

cancer側でクラスタマークを付与して、gemini側で確認
(cancer) $ sudo vgchange -c y vg-gfs2
(cancer) $ sudo vgdisplay vg-gfs2
(gemini) $ sudo vgdisplay vg-gfs2
gemini側でも「Clusterd yes」になっているのが確認できる。

とりあえずこれでうまく行ったはず。
ただ、ファイルシステムマウント関係(ココとかココとかココとか)が、まだcancerに反映できていないので、次回はそれを実施。

その後、クラスタマークがついているvgにpv追加したりな予定。
いや、その前にVGのアクティベーション時のオプション(-ayや-aay、-aey等)を確認した方がいいな…。

networking.service停止

ちょっと前のお話。

詳細は把握してないんだけど、ネットワークをOpenvswitchで管理するようにしたら、networking.serviceが起動しない状態になった。
これ、正しい状態だと思う。(ネットワークの管理がnetworkingサービスじゃなくなったってことで。)
なので、networking.serviceは停止しておいた方がいいだろう。

(sagittarius) $ systemctl status networking.service
(sagittarius) $ sudo systemctl stop networking.service
(sagittarius) $ sudo systemctl disable networking.service
(sagittarius) $ systemctl status networking.service

(aquarius) $ systemctl status networking.service
(aquarius) $ sudo systemctl stop networking.service
(aquarius) $ sudo systemctl disable networking.service
(aquarius) $ systemctl status networking.service

KVMホスト2台分だけ実施したけど、KVMゲストでも必要に応じて停止しておこう。
ただ何となく、ネットワークインターフェースを増やしたり、管理方法変えていくと、networking.serviceもまた起動しないといけない気がする…。
--2017/04/20追記ココから--
ココで対処しているけど、実際は networking.service を停止させるのではなく、 /etc/default/networking ファイルを書き換えて対応するのが正のようだ。
--2017/04/20追記ココまで--

2017年2月16日木曜日

CLVMに挑戦(その1)

というわけで、CLVM(Clustered Logical Volume Manager)に挑戦だ。

クラスタ環境で、ボリュームマネージャにLVMを用いるのなら、CLVMを使用するのがほぼ必須。
今までは使わずに済ませてたけど、流石に避けて通るわけにはいかない。

というわけで、とりあえずインストールしてみる。
(gemini) $ sudo apt-get update
(gemini) $ apt-cache search clvm
(gemini) $ sudo apt-get --simulate install clvm
(gemini) $ sudo apt-get install clvm

インストールしたら、どんなファイルが導入されたか確認してみよう。
(gemini) $ dpkg -L clvm
う~ん。ちょっと良くわからないな。

ただ、systemd用のサービスユニットは導入されたので、ちょっと確認を。
(gemini) $ systemctl status clvm
おや、inactiveだ。

だったらスタートしてみるか。
(gemini) $ systemctl is-active clvm
(gemini) $ systemctl is-enabled clvm
(gemini) $ sudo systemctl start clvm
(gemini) $ systemctl status clvm
起動は成功したっぽいな。

さて、設定をいじる前に、マニュアルエントリを読んでおくか。
(gemini) $ man clvmd
…ヨクワカラン…

色々ググってみると、単にVGにクラスタマークを付ける(vgchange -c y)だけでいいとか何とか…。
だったらまず、clvm未導入なcancerの方で実施してみるか。
(cancer) $ sudo vgchange -c y vg-ocfs2
LVM cluster daemon (clvmd) is not running. Make volume group "vg-ocfs2" clustered anyway? [y/n]:
ほう。clvmdが稼働していないよ、と警告が出るのね。
とりあえずnで抜けてしまおう。

んじゃぁ、先程clvmを導入し起動させたgeminiの方ではどうだろう?
(gemini) $ sudo vgchange -c y vg-ocfs2
LVM cluster daemon (clvmd) is not running. Make volume group "vg-ocfs2" clustered anyway? [y/n]:
…あれ?
(gemini) $ ps -ef | grep clvmd
確かに上がってきてない…起動できてなかったか?

(gemini) $ systemctl status clvm
よく見てみたら「 * clvmd: cluster not configured. Aborting.」って出てるぢゃん。
設定を施してないから、起動できてないよってことか。

じゃぁ何を設定すれば…?

なんか、clvmに関するコマンドが幾つかあることが分かった。
1つはlvmconfig、もう1つはlvmconf。似たような名前だ…。
前者はlvmの設定を変更するコマンド、後者はlvmの設定情報を確認するコマンドのようだ。

って、lvmの設定情報って、/etc/lvm/lvm.confじゃないのかな?
ちょっと叩いてみよう。
(gemini) $ sudo lvmconfig
なんか、設定情報がズラズラと出てきたぞ。

ちょっとファイルに出してみよう。普通にリダイレクトしてもいいんだろうけど、なんかファイルに出力するオプションもあるぞ。
(gemini) $ sudo lvmconfig -f lvmconfig.out
(gemini) $ sudo chmod 666 lvmconfig.out
(gemini) $ cat lvmconfig.out

これ、既存の /etc/lvm/lvm.conf との差は何だろう?
(gemini) $ grep -v '^\s*#' /etc/lvm/lvm.conf | grep -v '^\s*$' > lvmconfig.current
(gemini) $ diff -w -c lvmconfig.current lvmconfig.out
って単純diffじゃ差異が激しすぎる…。

というわけで、テキストファイルを手で差分取ってみた。
結果、ほとんど同じだった。
明確な違いは…
/etc/lvm/lvm.conf
global {
umask = 077
}
lvmconfigの出力
global {
umask=63
}
だけだった。
って、8進数077って、10進数で63だな。ってことは表記の違いだけで、中身は同じか。

ってことは、起動時に/etc/lvm/lvm.confが読み込まれて、その設定をメモリ中にキャッシュしていて、それをlvmconfigコマンドで出力するってことか。

対してlvmconfは設定を変更するコマンド。
これはオンラインでも(システム稼働中でも)変更可能なのかな?
もしそうなら、
  • 稼働中に変更するのならlvmconfコマンド
  • 変更結果が問題なければ、lvmconfigコマンドで/etc/lvm/lvm.confへ出力
  • 次回再起動時は/etc/lvm/lvm.confが読み込まれるので、変更結果が反映される
ということだろうか。

対してlvmconfコマンド。
これのman( man lvmconf )を見ると、いきなり「--enable-cluster」というオプションが出て来る。
これじゃないか?
さっそくやってみよう。
(gemini) $ sudo lvmconf --enable-cluster
あっさり実行できた。
設定の差異はどうなったかな?
(gemini) $ sudo lvmconfig -f lvmconfig.out2
(gemini) $ sudo chmod 666 lvmconfig.out2
(gemini) $ diff lvmconfig.out lvmconfig.out2
出た出た。
global {} の中の
locking_typeが1から3に変化。
use_lvmetadが1から0に変化。

実はずっと、この2つのパラメータをいじる必要がある、と考えていたんだ。
狙ったとおりだ。

実はこの後、色々悩んで再起動等を行っていたので、いつ変化したのか分からないんだけど、/etc/lvm/lvm.confが書き換わっていた。
変更内容は、lvmconfig --type diff で出力されたのと同じだ。
もしかしたら、lvmconfで/etc/lvm/lvm.confも書き換わるのかもしれない。
後ほど、cancer側も同様に変更するので、その時に確認してみたい。

さて、これでvgにクラスタマークは付けられるのかな?
(gemini) $ sudo vgchange -c y vg-ocfs2
あれ?やっぱりワーニングが出た。
あ~もしかしたら、設定変更後に反映処理が必要なのかも。

(gemini) $ sudo lvmconfig --type diff
あ、やっぱりそうだ。
「現在の設定内容と、新しい設定内容」の差が出た。
と思ったけど、diffオプションは「デフォルト値と現在の設定値の差」だ。ってことは反映済みか?
うん?上述のlocking_typeとuse_lvmetadの他に、devices{}のcache_dirとissue_discardsが出てきたな。

lvmconfのマニュアルに、「--services」というオプションと「--startstopservices」というオプションが載っている。
イマイチ違いが分からないけど、クラスタ関連の設定を施した場合は、多分「--startstopservices」の方じゃないかな?
試しに、「--services」の方を実行してみる。
(gemini) $ sudo lvmconf --services
む?使い方が違う…。
(gemini) $ sudo lvmconf --startstopservices
こっちは、--servicesと一緒じゃないとアカンよ、ということらしい。
(gemini) $ sudo lvmconf --services --startstopservices
やっぱりアカンやん…。

じゃぁこうかな?
(gemini) $ sudo lvmconf --enable-cluster --services
出来た…のか?
いや、まだのようだ。
となるとこうか?
(gemini) $ sudo lvmconf --enable-cluster --services --startstopservices
むぅ。なんかエラーになった。

(gemini) $ systemctl status lvm2-clvmd.service
やっぱりコケてるな。
何かが足りないんやな…。

ちょっとマテよ…。lvm2-clvmd.serviceの他に、clvm.serviceというユニットもあるぞ?
(gemini) $ systemctl | grep clvm
これ、systemd-sysv-generatorによって作成されたユニット…ってことは、/etc/init.dの下にあるのか。
ちょいと見てみよう。
(gemini) $ cat /etc/init.d/clvm
これを見てみると、/etc/cluster/cluster.confファイルが無いと何もせずに終了している。
が…そのファイルを使っていない…?

う~む。これ、pacemakerとかで使うファイルじゃないのか?
ヨクワカランので、空ファイルを作ってみよう。
(gemini) $ ls -ld /etc/cluster
(gemini) $ sudo mkdir /etc/cluster
(gemini) $ ls -ld /etc/cluster
(gemini) $ sudo touch /etc/cluster/cluster.conf
(gemini) $ ls -l /etc/cluster

これで試してみる…。
(gemini) $ sudo systemctl start clvm.service
(gemini) $ systemctl status clvm.service
う~ん。これでいいのかなぁ?
clvmはエラーは無くなった。(active (exited)というステータスなので、正しい状態には思えないが…)

(gemini) $ sudo systemctl start lvm2-clvmd.service
エラーメッセージをよく見てみたら「unit lvm2-clvmd.service may be requested by dependency only」とのこと。
これってもしかして、依存関係のあるunitからの起動しか受け付けてない?

(gemini) $ sudo systemctl start lvm2-cluster-activation.service
こちらのエラーメッセージを見てみたら…「A dependency job for lvm2-cluster-activation.service failed.」って。へ?依存関係がおかしい?

というわけでファイルを見てみる…。
(gemini) $ cat /lib/systemd/system/lvm2-cluster-activation.service
う~ん。「After」宣言に「lvm2-cmirrord.service」が入っているな…。
まさか、このサービスが必要なのか?

でもインストールされてない…。

探してみたけど、lvm2-cmirrord.serviceに相当するパッケージはUbuntu16.04には存在していないようだ。
あまり考えたくは無いけど、もしかしたらパッケージングのミスかもしれない。

更に、/lib/systemd/system/lvm2-clvmd.service、/lib/systemd/system/lvm2-cluster-activation.serviceのいずれにも、${prefix}/etc/sysconfig/clvmdという環境定義ファイルの指定があるが…どこにもそんなファイルは無い。

それらしいファイルを持ったパッケージも見つからず。

他にも、lvm2-clvmd.serviceの方は、/sbin/clvmdというのを呼び出す設定になっているけど、そのようなファイルは実際には無く、/usr/sbin/clvmdが多分正しいんじゃないかな?

こうまでくると、なんとなくパッケージングミスだと思う。
Ubuntu Japaneseにでも報告しておいた方がいいな…。

それはさておき、とりあえずやっつけでclvmdが動くようにする。

(gemini) $ cd /lib/systemd/system
まずは2つの.servicesファイルのバックアップ
(gemini) $ sudo cp -pi lvm2-cluster-activation.service \
lvm2-cluster-activation.service.orig
(gemini) $ sudo cp -pi lvm2-clvmd.service \
lvm2-clvmd.service.orig
一つずつ修正。
(gemini) $ sudo vi lvm2-cluster-activation.service
--ココから
After=lvm2-clvmd.service lvm2-cmirrord.service
↓(コメント化して、lvm2-cmirrord.serviceを削除した行を作成)
#After=lvm2-clvmd.service lvm2-cmirrord.service
After=lvm2-clvmd.service

EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
↓(コメント化)
#EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
--ココまで

(gemini) $ sudo diff lvm2-cluster-activation.service.orig \
lvm2-cluster-activation.service
--出力結果
4c4,5
< After=lvm2-clvmd.service lvm2-cmirrord.service
---
> #After=lvm2-clvmd.service lvm2-cmirrord.service
> After=lvm2-clvmd.service
12c13
< EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
---
> #EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
--出力結果ココまで

(gemini) $ sudo vi lvm2-clvmd.service
--ココから
EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
↓(コメント化)
#EnvironmentFile=-${prefix}/etc/sysconfig/clvmd

ExecStart=/sbin/clvmd $CLVMD_OPTS
↓(この行はコメントにし、パスを/usr/sbin/clvmdにした行を作成
#ExecStart=/sbin/clvmd $CLVMD_OPTS
ExecStart=/usr/sbin/clvmd $CLVMD_OPTS
--ココまで
(gemini) $ sudo diff lvm2-clvmd.service.orig \
lvm2-clvmd.service
--出力ココから
16,17c16,18
< EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
< ExecStart=/sbin/clvmd $CLVMD_OPTS
---
> #EnvironmentFile=-${prefix}/etc/sysconfig/clvmd
> #ExecStart=/sbin/clvmd $CLVMD_OPTS
> ExecStart=/usr/sbin/clvmd $CLVMD_OPTS
--出力ココまで

サービス定義読み直し
(gemini) $ sudo systemctl daemon-reload

起動してみる
(gemini) $ sudo systemctl start lvm2-cluster-activation.service
(gemini) $ systemctl status lvm2-cluster-activation.service
(gemini) $ systemctl status lvm2-clvmd.service
どうやら無事に起動したっぽい。

今度こそ、クラスタマークを付けてみる。
(gemini) $ sudo vgchange -c y vg-ocfs2
成功した。
(gemini) $ sudo vgdisplay vg-ocfs2
「Clusterd yes」という文字が見える。

多分、これで大丈夫じゃないかな?
今度は、これまで実施してきた内容を、対向のcancer側にも施して、CLVMが機能するかどうか試してみる。

2017年2月10日金曜日

ファイルシステムマウント変更(/etc/fstab変更)

前回までで、gfs2をマウントする流れが理解できて設定方法も分かった。
はずなんだけど、1つ漏れていた。

/etc/fstabを書き換えた後、OS再起動させずに反映させるにはどうすれば?だ。

/etc/fstabを書き換えてOS再起動させると、/run/systemd/generatorに反映される。
これをOS再起動させずに反映させる方法だ。

で、調べてみたら、systemd.generatorのマニュアルエントリ(man systemd.generator)に書いてあった。
ちゃんと読めよ…。

/etc/fstabを書き換えたら
$ sudo systemctl daemon-reload
だ。
これで/run/systemd/generatorに反映される。
ついでに、ファイルシステムのマウントも、
$ sudo systemctl start /mnt/gfs2
という具合に、マウントポイントを指定すればマウントしてくれる。
(アンマウントは systemctl stop だ)

なんだ、すげー簡単じゃん…。

ちなみに今回のocfs2/gfs2に対応する/etc/fstabエントリは以下だ。
--ココから
/dev/mapper/vg--ocfs2-lv--ocfs /mnt/ocfs2 ocfs2 _netdev,x-systemd.requires=o2cb.service 0 0
/dev/mapper/vg--gfs2-lv--gfs /mnt/gfs2 gfs2 _netdev,x-systemd.requires=dlm.service 0 0
--ココまで
この2行を/etc/fstabに追記した後、
(gemini) $ sudo systemctl daemon-reload
を実行
(gemini) $ ls -l /run/systemd/generator
でエントリが出来ている(mnt-gfs2.mount と mnt-ocfs2.mount)のを確認して
(gemini) $ sudo systemctl start /mnt/ocfs2
(gemini) $ sudo systemctl start /mnt/gfs2
でマウント、
(gemini) $ grep -e /mnt/ocfs2 -e /mnt/gfs2 /etc/mtab
でマウントされているのを確認。

これでOKだ。
(OS再起動後は自動でマウントされるはずだぞ。)

ファイルシステム関連はこれにてオシマイ。
次こそCLVMの調査だ。

--2017/04/14追記
fstabのエントリはnoautoを付与しておくようにした。
自動マウントされると、ちょっと不便だった。(ボリュームアクティベートが失敗しているのにマウントしようとしたり…)
--2017/04/14追記終了

gfs2マウントについて(その2:手動マウント)

gfs2のファイルシステムを自動的にマウントする方法については、前回で確立できた。

gfs2の仕組み上、自動マウントで設定しておけば何も問題ない気がするけど、一応手動マウントについても確認してみた。

/etc/fstabにエントリが無い環境でgfs2をマウントした場合、シャットダウン前にアンマウントしておく必要がある、という点はこれまでと同じ。
今回は、/etc/fstabにnoautoでエントリを書いていた場合、だ。
具体的には、/etc/fstabのエントリが以下のようにnoautoを付けている状態。
/dev/mapper/vg--gfs2-lv--gfs /mnt/gfs2 gfs2 noauto,_netdev,x-systemd.requires=dlm.service 0 0

結論から言えば、問題なしだ。
手動マウント→シャットダウン

手動マウント→手動アンマウント→シャットダウン
も問題ない。

更に言えば、マウントは
$ sudo mount /mnt/gfs2
でも
$ sudo systemctl start mnt-gfs2.mount
でもどちらでもいい。

アンマウントも全く同じで、
$ sudo umount /mnt/gfs2
でも
$ sudo systemctl stop mnt-gfs2.mount
でもどちらでもいい。

mount/umountコマンドを直接呼び出した場合でも、systemctlのステータスは変化してくれるので、systemctlコマンドを使用した場合と同じ結果になる。
何の心配もいらない。
前後に
$ systemctl status mnt-gfs2.mount
$ grep /mnt/gfs2 /etc/mtab
を叩いて確認してみるといい。

というわけで、gfs2ファイルシステムを使用するのなら、/etc/fstabにきちんと記載すること、という結論。

gfs2マウントについて(その1:自動マウント)

前回の記事で「gfs2がアンマウントされない」って記載した。
(実際には、ocfs2がアンマウントされない、と勘違いしていたが、実体はgfs2の方がアンマウントされない、だった。)

で、調べていくうちに、「手作業でmountした場合、シャットダウンする前に手作業でumountしないとダメだよ」というところまで分かった。

確かに、umountしておけばシャットダウン処理でハングすることもない。

だったら/etc/fstabに記載してあったらどうなんだ?ということで/etc/fstabに記載してみたが…起動時にマウントされない。
--/etc/fstabへの追記内容
/dev/mapper/vg--gfs2-lv--gfs /mnt/gfs2 gfs2 _netdev 0 0
--追記ココまで

起動時に自動マウントされないが、/etc/fstabへの記載があるので手作業でマウントは出来る。
(gemini) $ sudo mount -a
もしくは
(gemini) $ sudo mount /mnt/gfs2
ただ、この状態でシャットダウンすると、やはりハングする。

どうしたものか…と調査を続けていったら、systemdにmnt-gfs2.mountというユニットが追加されていることが発覚。
どうやら、/etc/fstabから自動生成されている模様。
そして、これがマウント処理を行おうとして失敗している。

(gemini) $ systemctl status mnt-gfs2.mount
(gemini) $ journalctl -l --unit=mnt-gfs2.mount
(gemini) $ journalctl -o cat --unit=mnt-gfs2.mount
3つ目のコマンドで確認できるのは「mount: mount /dev/mapper/vg--gfs2-lv--gfs on /mnt/gfs2 failed: 通信端点が接続されていません」というメッセージだ。
これ、dlmの設定が出来ていない時にgfs2領域をmountしようとした時のメッセージじゃないか?
ってことは、dlmの起動処理が終わらないうちに、mountコマンドが走り出したってことじゃないだろうか?

このユニットの詳細を見てみたい。
(gemini) $ systemctl show mnt-gfs2.mount
(gemini) $ systemctl --no-pager show mnt-gfs2.mount | less
After宣言を見てみると、確かにdlm.serviceは前提として定義されていない。
でもこれ、設定を変えようにも変え方が分からない。

(gemini) $ systemctl show -p FragmentPath mnt-gfs2.mount
これを見る限り、/run/systemd/generator/mnt-gfs2.mountが設定ファイルなのだが…。
(gemini) $ cat /run/systemd/generator/mnt-gfs2.mount
確かに設定ファイルなのだが、このファイル自体、tmpfs上に作成されていて、OSブート時に自動的に生成されるもののようだ。

ということで、予めこのファイルをイジっておく、というわけにはいかない。

このファイル自体は、systemd-fstab-generatorというツールが作成しているようだ。
manを見てみるが…
(gemini) $ man systemd-fstab-generator
あまり詳しくは書かれていない。

が、systemd.mountも参照しろ、と書かれていた。
こちらも参照してみる。
(gemini) $ man systemd.mount
む?何かヒントっぽいことが書かれているぞ!?
x-systemd.requires=
というエントリだ。

う~ん。良くわからないがfstabを書き換えてみよう。
(gemini) $ sudo vi /etc/fstab
--ココから
/dev/mapper/vg--gfs2-lv--gfs /mnt/gfs2 gfs2 _netdev 0 0

/dev/mapper/vg--gfs2-lv--gfs /mnt/gfs2 gfs2 _netdev,x-systemd.requires=dlm.service 0 0
--ココまで

再起動(gfs2領域はアンマウントしておくこと)
(gemini) $ sudo shutdown -r now

どうだろうか…
(gemini) $ grep gfs2 /etc/mtab
マウントされてる!

自動作成された設定は…?
(gemini) $ cat /run/systemd/generator/mnt-gfs2.mount
お!AfterとRequiresの定義が追加されて、それぞれdlm.serviceが指定されている!
どうやら期待通りの動きをしてくれたみたいだ。

さて、問題はシャットダウンだが…。
このまま再起動してみる。
(gemini) $ sudo shutdown -r now
普通に再起動出来た…。

これで起動時にマウントする設定が出来たよ…。

--2017/04/14追記
ちょっと不安定な部分があったので、/etc/fstabの中の/mnt/gfs2のマウントエントリ、noautoオプションを付けて、起動時に自動マウントされないようにしておく。
/dev/mapper/vg--gfs2-lv--gfs /mnt/gfs2 gfs2 noauto,_netdev,x-systemd.requires=dlm.service 0 0
こんな感じ
--2017/04/14追記終了

2017年2月9日木曜日

ocfs2アンマウントされず

ここまで検証して、一度OS(gemini/cancer)を再起動しようとしたんだけど…。
なんかocfs2の領域がアンマウントされずにシャットダウンされへんくなった…。
これはちょっと不便なので、後で確認しよう…。
(仮想マシン上に作っているので、仮想マシンを強制的に停止させればなんとかなる)

2017/02/10追記
勘違いだった。ocfs2がマウントされているのは問題ないようで、gfs2がマウントされているとシャットダウンが上手くいかない。
もう少し調べないと…。。

共有ファイルシステム(corosync&dlm&gfs2その3)

さて、geminiの方は環境が整ったと思うので、それに合わせてcancerも設定しよう。

ファイルシステム作成等はgemini側で行っているので、cancerのみで実施すべき部分だけ書いておいた。
ほぼほぼ、geminiと同じ作業を行えばいい。
(cancer) $ sudo apt-get update
(cancer) $ sudo apt-get install gfs2-utils
(cancer) $ sudo tunegfs2 -l /dev/vg-gfs2/lv-gfs
(cancer) $ sudo mkdir /mnt/gfs2

(cancer) $ sudo apt-get update
(cancer) $ sudo apt-get install corosync
(cancer) $ sudo cp -pi /etc/corosync/corosync.conf \
/etc/corosync/corosync.conf.orig
(cancer) $ sudo vi /etc/corosync/corosync.conf
以下のように修正・追記していく。(geminiの時と同じだ)
totem {
cluster_name: debian

cluster_name: mycluster

interface {
bindnetaddr: 127.0.0.1

bindnetaddr: 192.168.55.0
}
}
(cancer) $ diff /etc/corosync/corosync.conf.orig \
/etc/corosync/corosync.conf
(cancer) $ systemctl status corosync
(cancer) $ sudo systemctl restart corosync
(cancer) $ systemctl status corosync

(cancer) $ sudo apt-get update
(cancer) $ sudo apt-get install dlm

(cancer) $ ls -l /dev/misc
あ…あれ…?geminiの時は/dev/miscができなかったのに、cancerの時は自動で作成された…。
OS再起動いらないな…。
(cancer) $ systemctl status dlm

(cancer) $ sudo mkdir /etc/dlm
(cancer) $ sudo bash -c "/usr/sbin/dlm_tool dump_config > /etc/dlm/dlm.conf"
(cancer) $ sudo vi /etc/dlm/dlm.conf
--以下の内容
enable_quorum_lockspace=1
↓この行を以下のように書き換え(geminiの時と同じ)
enable_quorum_lockspace=0
--ココまで

(cancer) $ sudo systemctl restart dlm
(cancer) $ sudo systemctl status dlm

(cancer) $ sudo mount -t gfs2 /dev/vg-gfs2/lv-gfs /mnt/gfs2
(cancer) $ df /mnt/gfs2
(cancer) $ grep gfs2 /etc/mtab

(cancer) $ dlm_tool ls -n
(cancer) $ dlm_tool status

(cancer) $ sudo touch /mnt/gfs2/test
(cancer) $ sudo bash -c "echo hogehoge >> /mnt/gfs2/test"
(cancer) $ sudo bash -c "echo fugafuga >> /mnt/gfs2/test"
(cancer) $ cat /mnt/gfs2/test
(cancer) $ sudo rm /mnt/gfs2/test

あっさり終了。

そしたら、ocfs2の時と同じテストを実施してみる。
(gemini) $ ls -ld /mnt/gfs2
(gemini) $ sudo chmod 777 /mnt/gfs2
(gemini) $ ls -ld /mnt/gfs2
(cancer) $ ls -ld /mnt/gfs2

(gemini) $ cp /etc/hosts /mnt/gfs2/
(gemini) $ ls -l /mnt/gfs2
(cancer) $ ls -l /mnt/gfs2
問題なく両方から参照出来る。

(gemini) $ cat /mnt/gfs2/hosts
(cancer) $ cat /mnt/gfs2/hosts
問題ない。

(gemini) $ vi /mnt/gfs2/hosts
(cancer) $ vi /mnt/gfs2/hosts
ocfs2の時と同じで、後から実行したcancerの方が、「スワップファイルが既に存在しているよ」という警告が出た。

というわけで、cancer側でまず強制的に開いて、geminiの方で更新して保存終了、cancer側でも更新保存してみる。
ocfs2の時とまったく同じ挙動。

次のテスト。
(gemini) $ rm /mnt/gfs2/hosts
(gemini) $ ls -l /mnt/gfs2/hosts
(cancer) $ ls -l /mnt/gfs2/hosts

(gemini) $ dd if=/dev/urandom of=/mnt/gfs2/randomio bs=1M count=1024
(cancer) $ dd if=/dev/urandom of=/mnt/gfs2/randomio bs=1M count=1024
あれ?ocfs2の時は、2ノード同時に始めて同時に終わったと思ったけど、今回のgfs2だとcancerの方が少し終わるの遅かったぞ?
何か違いがあるのかな?いや、何度かテストしてみたら、ほぼ同じタイミングで終わる。

やはり、ロックはflock等を使ってアプリケーションレイヤーで対応する、ということなのかもしれないな。

ちなみに、ocfs2とgfs2でどちらが速いのか?ってことで、簡単にI/O性能を測ってみたけど、ほとんど差が出なかった。
もっと厳密に計測すれば、それぞれの特徴が分かるんだろうけど…。

んで…。
実はocfs2にせよgfs2にせよ、ボリュームマネージャにLVMを用いるのなら、LVMもクラスタ対応のCLVMを使用するべきだった。
次回はCLVMに挑戦してみるよー。