2017年3月29日水曜日

ダメだ…

--2017/04/20追記ココから--
ここで出ている問題は、前回分に追記した内容で解消したっぽい。
なので、無駄な記事になってしまった。
--2017/04/20追記ココまで--

corosyncが上手く動いてくれない件、geminiもcancerもかなりイジってしまった。
かなり混乱しているので、一度gemini/cancerともに作り直した方がいいかな…。

2017年3月28日火曜日

corosyncの謎

--2017/04/20追記ココから--
ここで出ている問題は、前回分に追記した内容で解消したっぽい。
なので、無駄な記事になってしまった。
--2017/04/20追記ココまで--

corosyncの起動に失敗する流れ、少し分かってきた。
(corosyncがコケて、dlmも引き摺られてコケてるようだ。)

以下のような流れっぽい。
  1. lo(127.0.0.1)がUp
  2. corosync起動(まだOpenvSwitchの192.168.55.xxは未起動)
  3. corosyncが何故か127.0.0.1にbind
  4. dlmもcorosyncに接続
  5. OpenvSwitchの192.168.55.xxが起動
  6. corosyncが192.168.55.xxにもbind
  7. corosync、127.0.0.1へのbindと整合性が合わずコケる
  8. dlmもcorosyncに引き摺られてコケる
だ。
そのため、corosync起動よりOpenvSwitchを先に起動したらいいはずなんだが、これが上手く行かないんだよなぁ…。
また、corosync.confで192.168.55.xxにbind指定しているはずなのに、127.0.0.1にbindしてしまうのも問題だ。ドコの設定がおかしいんだろう…?

ずっと調査してるんだけど、遅々として進まず。

2017年3月14日火曜日

iSCSIボリュームのLVMが有効化されるまで(その3:多分完結)

--2017/04/20追記ココから--
ここで出ている問題は、前回分に追記した内容で解消したっぽい。
なので、無駄な記事になってしまった。
--2017/04/20追記ココまで--

悩んで悩んで悩んで、どうやら見当違いのところを調査していたらしい…。

まず、ネットワーク設定のディレクトリに、geminiを作成した時の設定情報が残っていた。
そのファイルがまず不要だったので削除する。
(gemini/cancerを作る時の基本的な手順は省略してしまっているが、ココのタイミングで作ったと思われるファイルだ…。)
(gemini) $ cd /etc/network/interfaces.d
(gemini) $ ls -l ens3
(gemini) $ sudo cat ens3
(gemini) $ sudo rm ens3
(gemini) $ ls -l

それから、ココココではOpenvSwitchのブリッジにIPアドレスを付与しているように見えるが、どうやらこれは正しく無いようだ。
実際にはやはり、NICやNICから作るbondingに対して、IPを付与するようだ。
(確かに、違和感はあった。)

というわけで、ブリッジのIP定義ファイルとNICのIP定義ファイルを書き換える。
まずは、NICのIP定義ファイル。
(gemini) $ sudo vi 0110.ens3
--以下のように行を追加&修正
auto ens3
allow-br-external
iface ens3 inet manual
ovs_bridge br-external
ovs_type   OVSPort
↓(下線行を追加&修正)
auto ens3
allow-br-external ens3
iface ens3 inet static
address 192.168.55.136
network 192.168.55.0
netmask 255.255.255.0
broadcast 192.168.55.255
gateway 192.168.55.1
ovs_bridge br-external
ovs_type OVSPort

dns-nameservers 192.168.55.1
--ココまで

続いて、ブリッジのIP定義ファイル
(gemini) $ sudo vi 0010.br-external
--以下のように修正&行削除
auto br-external
allow-ovs br-external
iface br-external inet static
address 192.168.55.136
network 192.168.55.0
netmask 255.255.255.0
broadcast 192.168.55.255
gateway 192.168.55.1
ovs_type OVSBridge
ovs_ports ens3

dns-nameservers 192.168.55.1

auto br-external
allow-ovs br-external
iface br-external inet manual
ovs_type OVSBridge
ovs_ports ens3
--ココまで

更に、ココの最後に無効化したnetworking.serviceはやはり必要なようなので、有効化しておく。
(gemini) $ systemctl is-enabled networking.service
(gemini) $ sudo systemctl enable networking.service
(少し時間かかってエラーになるかもしれないけど我慢だ)
(gemini) $ systemctl is-enabled networking.service

そうしたら再起動してみる。
(gemini) $ sudo shutdown -r now

起動してきたら確認。
(gemini) $ systemctl status
Failedが無くなった!

(gemini) $ sudo vgs
ちゃんと表示される…。

(gemini) $ sudo iscsiadm -m session
ログインできてる。

そうか…OpenvSwitchの設定をミスってただけなのか…。
やっと、長いこと悩んでいた原因が分かって修正方法も分かった…。

次回は、これにそってaquariusの修正を行う。

--2017/03/24追記
根本的に間違えていた。今はまだ調査を続行しているけど、↑の設定は根本的に誤り。
まだ対応方法は不明だけど、↑のやり方は間違いなので、元に戻しておいた方がいい。

iSCSIボリュームのLVMが有効化されるまで(その2)

--2017/04/20追記ココから--
ここで出ている問題は、前回分に追記した内容で解消したっぽい。
なので、無駄な記事になってしまった。
--2017/04/20追記ココまで--

未だ解決出来ていないのだが、前回からの再起動後、systemdの状態をよく見てみたら、corosync.serviceの起動にも失敗している。
はて?cancerの方はどうだ?
(cancer) $ sudo shutdown -r now
(cancer) $ systemctl status corosync.service
問題なく起動している。
なんとまぁ…geminiに対する変更処理で、corosyncにまで影響が出てしまった。
これは要調査だな…。

ってどうやら、dlm.serviceも正常起動しなくなってるぞ。
これは大ダメージだ。

とりあえず状態の整理。
  • /etc/libvirt等のKVM用ファイルシステムは未マウント
  • NAS領域も未マウント
  • vg確認・操作系オペレーションはハング(vgs)
  • iSCSIターゲットへのログインは成功(iscsadm -m session)
  • ブロックデバイスは認識済み(lsblk)
  • corosync.serviceはfailed
  • dlm.serviceはinactive
  • clvm.serviceはinactive(これはcancerも)
  • multipathは認識済み
となると、corosync.serviceから確認してみるか。

(gemini) $ cat /lib/systemd/system/corosync.service
要件として、network-online.targetが入っている。
ステータスは…
(gemini) $ systemctl status network-online.target
activeだ。
条件は…
(gemini) $ cat /lib/systemd/system/network-online.target
前提条件としてnetwork.targetが入っている。
ステータスは当然…
(gemini) $ systemctl status network.target
activeだ。

う~ん。corosync.serviceが起動していないのは何故だろう?
試しに起動してみる。
(gemini) $ sudo systemctl start corosync.service
(gemini) $ systemctl status corosync.service
む?activeになったぞ…?

もう一度再起動して、再現確認だ。
(gemini) $ sudo shutdown -r now
(gemini) $ systemctl status corosync.service

あれ?今度は
  • iSCSIターゲットへのログインは、片方失敗(gemini単独用ターゲットへのログイン失敗)
  • corosync.serviceは起動状態
  • dlm.serviceも起動状態
  • clvmはinactive
になった。(その他の状態は一緒。)

………色々調べてたら、どうやらOpenvSwitchの設定がおかしいようだ………
ヘルプに書かれている設定方法じゃダメっぽい………

整理して書き直す…。

2017年3月11日土曜日

iSCSIボリュームのLVMが有効化されるまで(その1)

--2017/04/20追記ココから--
ここで出ている問題は、前回分に追記した内容で解消したっぽい。
なので、無駄な記事になってしまった。
--2017/04/20追記ココまで--

前回の調査で、どうやらOS起動時のファイルシステム(iSCSIボリュームで作成したLVM領域のファイルシステム)マウント、OS停止時のファイルシステムアンマウントの流れがおかしいのでは?というのが予想出来た。

そもそもこの領域、iSCSI領域であり、OpenvSwitch上の仮想スイッチを経由してiSCSIターゲットへ接続している。
(サーバとして使うのなら、iSCSIターゲットへの接続は独立したネットワークを用い、OpenvSwitchを経由しない構成にするべきだと思うのだが、自宅PCレベルでは複数NICや複数N/Wを使いまわすのは面倒だ…)

そのため、OS起動からファイルシステムマウントまでは、以下の流れにならないといけないと思う。(CIFSマウントのタイミングもついでに書いておいた。)

停止はこの逆になるはず。

根本的なところで、OpenvSwitchが起動した後に、iSCSIのLVM関連が動き出さないといけないのだが、どうやら起動処理ではこの順番が守られていないように見える。
また、停止時もこの逆になっていないように見える。

これを追いかけてみよう。
まずは再起動をして、サービス起動が上手く行っていないものを探す。
(gemini) $ sudo shutdown -r now
(gemini) $ systemctl -a status
今のgeminiは、以下のような状態になっている。
● gemini
State: starting
Jobs: 3 queued
Failed: 1 units
(略)
● dev-mapper-vg\x2d\x2dkvm\x2dlv\x2d\x2detc\x2d\x2dlibvirt.device
Loaded: loaded
Active: inactive (dead)
(略)
● dev-mapper-vg\x2d\x2dkvm\x2dlv\x2d\x2dvar\x2d\x2dlib\x2d\x2dlibvirt.device
Loaded: loaded
Active: inactive (dead)
(以降省略)
みたいな感じだ。

なんか、表示が上手く行っていないが、
dev-mapper-vg--kvm-lv--etc--libvirt.device
とかのようだ。
末尾が.deviceとなっているunitは、deviceタイプと呼ばれる代物。
実体は何処にあるかと言うと…無い…。
どういうことだろ…。deviceタイプはチェックしなくていいのかな?

一応、確認はしてみる。
(gemini) $ systemctl status dev-mapper-vg\\x2d\\x2dkvm\\x2dlv\\x2d\\x2detc\\x2d\\xwdlibvirt.device
Timed out waiting for device dev-mapper-vg…
う~ん。どうやら、デバイス(vg)へのアクセスがタイムアウトを起こした、ということらしいな。
ということは、vg構成情報が読み取れる状態になるところ(iSCSIログイン?)に問題があるのか?

systemdのユニットは、service/deviceの他に、mount/target等があるようだ。
ということで、一応mountも確認してみるか。
mount関連はココにも書いた通り、/run/systemd/generaterの下に自動生成される。

試しに、etc-libvirt.mountとmnt-iso\x2dos.mountを見てみると、以下のようなエントリが見える。
Before=remote-fs.target
これは、自分自身(etc-libvirt.mountとかmnt-iso\x2dos.mountとか)よりも後に、remote-fs.targetを起動する、という設定。
前提条件を書いているのではなく、後続条件を書いていることになる。

ちなみに、remote-fs.targetは、今の自分の環境には2つ存在してる。
/etc/systemd/system/multi-user.target.wants/remote-fs.target
/lib/systemd/system/remote-fs.target
が、実体は後者で、前者はシンボリックリンクだ。

前者はSysV init方式で言うところのrunlevelを制御するところの関係なので、今回はちょっと無視する。

後者を確認しよう(前者はシンボリックリンクなので、どちらを確認しても同じなのだが…)。
以下の3行が気になる。
After=remote-fs-pre.target
DefaultDependencies=no
Conflicts=shutdown.target

これを見ると、remote-fs.targetは、remote-fs-pre.targetの処理が終わってからでないと起動しないらしい。
また、shutdown.targetとConflictsになっているため、shutdown.targetと同時起動はしない。
DefaultDependenciesは…ちょっと良くわからない。標準的な依存関係を暗黙的に有効にするかどうか?で、noに設定されているので、幾つかの標準的な依存関係は無視される?

remote-fs-pre.targetも同じディレクトリにあるので、こちらもついでに確認する。
特に何かが書いてあるわけではない。
RefuseManualStart=yes
ってのがあるが…これがyesなので、ユーザの手作業による起動・停止は出来ないようだ。

これらをまとめてみると、以下のフローになるのかな?


さて、ココを調べてもしょうがない。
もっと上位で問題が起きていて、ファイルシステムマウントまで辿り着いていない、というのが現実だ。

とは言え、etc-libvirt.mountを見ても前提条件が書かれていない。
ステータスを見てみると…
(gemini) $ systemctl status etc-libvirt.mount
Dependency failed for /etc/libvirt.
となっていて、Dependency(依存)の失敗が原因となっている。

一体どういうことなんだろう…。

やはり、iSCSIログインに問題があるのだろうか?
と思って、NAS装置の管理画面からiSCSIターゲットを見てみたら、一応ログインされているようだ。

iSCSIログインに関するsystemd unitは何だろうな…
(gemini) $ systemctl | grep -i iscsi
iscsid.serviceのようだ。ステータスはrunningだから問題無い。
(gemini) $ systemctl status iscsid.service
cannot make a connection to....
あれ?なんかエラーっぽいメッセージが出てるな…大丈夫か?

一応、iscsid.serviceを再起動してみるか…。
(gemini) $ sudo systemctl restart iscsid.service
(gemini) $ systemctl status iscsid.service
おや?先程のエラーっぽいメッセージは出なくなった。

でも、vg情報は取得されてないぞ…。
む?もう1つ、open-iscsi.serviceってあるけど…これ…は?
(gemini) $ systemctl status open-iscsi.service

正常に動いているっぽいけど、一応再起動してみる…。
(gemini) $ sudo systemctl restart open-iscsi.service

ログイン済みのiSCSI targetからログアウト→再度ログイン、という流れになるはずなんだけど、syslogを見てみたらログアウトに1分30秒かかってタイムアウトした。
その後、再ログインしてデバイス認識はスムーズに行っている。

もしかして、これでvg認識されたかな?
(gemini) $ sudo pvdisplay /dev/sda1
ダメだ。ハングする。
他にも問題を抱えているのか…。

iSCSIイニシエータのエラーっぽいメッセージが消えたから、今度はLVM関連のサービスを確認してみるか。
(gemini) $ systemctl status | grep lvm2
lvm2-activation-net.serviceというのがあるな。

これの内容は…おや?これも自動生成関係っぽいな。
(gemini) $ man lvm2-activation-generator
lvm.confでlvmetadが無効化されている場合に、このlvm2-activation-generatorによってユニットが生成され、LVMボリュームがアクティベートされる、と。

gemini/cancerは、CLVMを使用する関係で、lvmetadを無効化している。
となると、今のaquarius/sagittariusとは条件が違うか…。まぁaquarius/sagittariusも将来的にはlvmetadを停止することになりそうだから、調べておくか。

どうやら、/run/systemd/generatorに、
lvm2-activation-early.service
lvm2-activation-net.service
lvm2-activation.service
という3つのユニットが作成されているっぽい。
これが関係あるかもしれない。

1つずつ確認してみよう。
まず3つのユニットのExecStartだけど、全て同じで
ExecStart=/sbin/lvm vgchange -aay --ignoreskippedcluster
になっている。
つまり、lvm.confのauto_activation_volume_listに記載されているlvolのうち、Clusterマークが付いているボリュームを無視して、残り全てをアクティベーションさせるということか。
これだと、既にPVが認識できていることが前提条件になりそうだな…。

3つのユニットの依存関係を見てみると…。
lvm2-activation-early.service
After=systemd-udev-settle.service
Before=cryptsetup.target
Before=local-fs-pre.target shutdown.target
Wants=systemd-udev-settle.service

lvm2-activation-net.service
After=lvm2-activation.service iscsi.service fcoe.service
Before=remote-fs-pre.target shutdown.target

lvm2-activation.service
After= lvm2-activation-early.service cryptsetup.target
Before=local-fs-pre.target shutdown.target
Wants=systemd-udev-settle.service

After/Before/Wantsが定義されている。
これらの依存関係を整理すると…

こんな感じだろうか…。

これ、1つずつ実行してみる。(最後のshutdown.targetは実行しちゃダメだよ)
(gemini) $ sudo systemctl restart systemd-udev-settle.service
(gemini) $ sudo systemctl restart lvm2-activation-early.service
あれ…?ココでハングした…?
--以下は想定していたコマンド。上でハングしたので実施せず。
(gemini) $ sudo systemctl restart cryptsetup.target
(gemini) $ sudo systemctl restart lvm2-activation.service
(gemini) $ sudo systemctl restart iscsi.service
(gemini) $ sudo systemctl restart lvm2-activation-net.service
--ココまで

う~ん。なんだろう…?
ちょっと調査を続けていたら、ココで設定したgemini/cancer共用のiSCSIターゲットへの自動ログインがOffになってた。(geminiだけ。)
たんなる作業ミスなのか、一連の作業の中で自動的に解除されたのかは不明。

とりあえず、「iSCSIを利用しようその1」等に従って、自動ログインを実施するように設定。

この状態で一度再起動をしてみるが、まだ解決できず。
とりあえず、調査は継続するけど、今回はここまで。

2017年3月7日火曜日

実はちょっと問題が

今のウチの構成は、KVMホストとして使っている物理マシンが2台ある。
Intel NUCを使った弁当箱サイズのaquariusと、いわゆる自作マシンのミドルタワーサイズのsagittariusだ。

このマシンにUbuntu16.04を導入し、iSCSIイニシエータ、OpenvSwitch、KVM等を導入して運用している。

で、このマシン、実はシャットダウンやリブートで詰まる事象が起きている。
ファイルシステムアンマウント・ボリュームディアクティベートあたりで発生しているようで、多分「gfs2マウントについて(その1:自動マウント)」辺りと似たような問題だと睨んでいる。

ただ、仮想マシンではなく物理マシンのため、今までは見て見ぬふりをしていた。
再起動を伴う設定変更・確認は、物理マシンを相手にする場合は、物理マシンの直ぐ側にいないとリスキーなので。

ただ、仮想マシンでiSCSIが利用できることも確認できたので、仮想マシンで現象の再現、対応方法の確立をしようと思う。

とりあえず、gemini/cancer上でKVMを動かしたいので、一旦停止してgemini/cancerのCPU定義と割当メモリを変更する。
まずは停止。
(gemini) $ sudo shutdown -h now
(cancer) $ sudo shutdown -h now

停止しているのを確認して、両仮想マシンを編集。
(sagittarius) $ virsh list --all
(sagittarius) $ virsh edit gemini
(sagittarius) $ virsh edit cancer
gemini/cancerともに同じ修正を施す。
--ココから
4~5行目付近
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
↓(割当サイズを4GBにする)
<memory unit='KiB'>4194304</memory>
<currentMemory unit='KiB'>4194304</currentMemory>

17~18行目付近
<cpu mode='custom' match='exact'>
<model fallback='allow'>core2duo</model>
↓(CPUモデルをhost-modelに)
<cpu mode='host-model'>
<model fallback='allow'/>
--ココまで

ココまで出来たらgemini/cancerともに起動する。
(sagittarius) $ virsh start gemini
(sagittarius) $ virsh start cancer

後は、過去の内容を参照しながら作り込んでいく。(とりあえずgeminiに対してのみ更新。)
ざっとコマンド羅列。
(gemini) $ sudo apt-get update
(gemini) $ sudo apt-get install qemu-kvm
(gemini) $ sudo shutdown -r now

(gemini) $ grep kvm /etc/group
(gemini) $ id
(gemini) $ sudo adduser (自分のユーザ名) kvm
(gemini) $ grep kvm /etc/group
(一旦exitで抜けて、再度ログイン)
(gemini) $ id

(gemini) $ lsmod | grep kvm

(gemini) $ sudo apt-get install virtinst
(gemini) $ sudo apt-get install libosinfo-bin

再ログイン
(gemini) $ virsh list --all
(gemini) $ sudo apt-get install virt-manager
(gemini) $ sudo apt-get install fonts-ipafont

(gemini) $ sudo apt-get install openvswitch-switch
(gemini) $ sudo ovs-vsctl show
(gemini) $ sudo ovs-vsctl list-br
(gemini) $ sudo ovs-vsctl add-br br-external
(gemini) $ sudo ovs-vsctl show
(gemini) $ sudo ovs-vsctl list-br

(gemini) $ sudo vi /etc/network/interfaces.d/0110.ens3
ファイルの新規作成
--ココから--
auto ens3
allow-br-external
iface ens3 inet manual
ovs_bridge br-external
ovs_type OVSPort
--ココまで--

(gemini) $ sudo vi /etc/network/interfaces.d/0010.br-external
ファイルの新規作成
--ココから--
auto br-external
allow-ovs br-external
iface br-external inet static
address 192.168.55.136
network 192.168.55.0
netmask 255.255.255.0
broadcast 192.168.55.255
gateway 192.168.55.1
ovs_type OVSBridge
ovs_ports ens3

dns-nameservers 192.168.55.1
--ココまで--

--2017/04/14追記
ネットワークセッションが切れてしまうので、コンソールで作業しよう。
(gemini) $ sudo ifdown ens3
(gemini) $ sudo rm /etc/network/interfaces.d/ens3
(gemini) $ sudo ovs-vsctl add-port br-external ens3
(gemini) $ sudo ovs-vsctl show
(gemini) $ sudo ifup ens3
(gemini) $ sudo ifup br-external
--2017/04/14追記ココまで

--2017/04/20追記
このまま再起動させると、 OpenvSwitch/corosync/dlm/lvm2-cluster-activation の起動関連が上手く行かず、ハングしてしまう。
  1. OpenvSwitchが完全に起動
  2. corosync起動
  3. dlm起動
  4. lvm2-cluster-activation起動
の順で起動して欲しいのだが、OpenvSwitchの起動処理が完全に終わる前にcorosyncが起動してしまい、その後の起動処理が不安定になってしまう。

そのため、起動順の制御と、OpenvSwitchの起動時に、少しsleepを置くことにする。
(gemini) $ cd /lib/systemd/system
(gemini) $ sudo cp -pi corosync.service corosync.service.orig
(gemini) $ sudo cp -pi openvswitch-switch.service openvswitch-switch.service.orig

(gemini) $ sudo vi corosync.service
--ココから
Requires=network-online.target
After=network-online.target
(前提条件に openvswitch-switch.service を追加する)
Requires=network-online.target openvswitch-switch.service
After=network-online.target openvswitch-switch.service
--ココまで

(gemini) $ sudo vi openvswitch-switch.service
--ココから
ExecStart=/bin/true
(何も実行しない処理を、6秒待機に変更する)
ExecStart=/bin/sleep 6
--ココまで

変更内容を取り込む。
(gemini) $ sudo systemctl daemon-reload
(gemini) $ cd
--2017/04/20追記ココまで

(gemini) $ sudo shutdown -r now
(gemini) $ ip address show
(gemini) $ dig www.blogger.com
(gemini) $ sudo ovs-vsctl show

(gemini) $ virsh net-list --all
(gemini) $ vi ovsbridge.xml
ファイルの新規作成
--ここから
<network>
<name>ovsbridge</name>
<forward mode='bridge'/>
<bridge name='br-external'/>
<virtualport type='openvswitch'/>
</network>
--ここまで
(gemini) $ virsh net-define ovsbridge.xml
(gemini) $ virsh net-list --all

(gemini) $ virsh net-autostart ovsbridge
(gemini) $ virsh net-list --all

(gemini) $ virsh net-start ovsbridge
(gemini) $ virsh net-list --all

(gemini) $ sudo apt-get install ovmf
-------------------------------------------------------------
がーっと作ってしまったが、iSCSIのボリューム以外はだいたいホストOSと同じになったはず。
この状態で再起動が上手くいくか確認。
(gemini) $ sudo shutdown -r now
特に問題無さそうだ。

iSCSIストレージ装置で、新しくiSCSIターゲットを作成、100GBのLUNを新たに繋いで、geminiにのみ接続させておく。
/dev/sdb として認識された。

そのディスクを、ホストOSと同じように領域確保&ファイルシステム作成する。
(gemini) $ sudo parted /dev/sdb print
(gemini) $ sudo parted /dev/sdb mklabel gpt
(gemini) $ sudo parted /dev/sdb mkpart primary ext4 0% 100%
(gemini) $ sudo parted /dev/sdb toggle 1 lvm
(gemini) $ sudo parted /dev/sdb print

(gemini) $ sudo pvcreate /dev/sdb1
(gemini) $ sudo vgcreate vg-kvm /dev/sdb1
(gemini) $ sudo vgchange -c n vg-kvm
(gemini) $ sudo vgdisplay -v vg-kvm

(gemini) $ sudo lvcreate -L 32M -n lv-etc-libvirt vg-kvm
(gemini) $ sudo lvcreate -L 50G -n lv-var-lib-libvirt vg-kvm
(gemini) $ sudo lvcreate -L 2G -n lv-var-log-libvirt vg-kvm

(gemini) $ sudo mkfs.ext4 /dev/vg-kvm/lv-etc-libvirt
(gemini) $ sudo mkfs.ext4 /dev/vg-kvm/lv-var-lib-libvirt
(gemini) $ sudo mkfs.ext4 /dev/vg-kvm/lv-var-log-libvirt

続いて、中身のコピー。
(gemini) $ sudo mkdir /tmp/libvirt

(gemini) $ sudo mount /dev/vg-kvm/lv-etc-libvirt /tmp/libvirt
(gemini) $ df /tmp/libvirt
(gemini) $ sudo -i
(gemini) # cd /etc
(gemini) # tar cSf - libvirt | ( cd /tmp ; tar xSf - )
(gemini) # ls -l /tmp/libvirt
(gemini) # ls -ld /tmp/libvirt /etc/libvirt
(gemini) # exit
(gemini) $ sudo umount /tmp/libvirt
(gemini) $ sudo rm -rf /etc/libvirt
(gemini) $ sudo mkdir /etc/libvirt
(gemini) $ sudo mount /dev/vg-kvm/lv-etc-libvirt /etc/libvirt
(gemini) $ df /etc/libvirt

(gemini) $ sudo mount /dev/vg-kvm/lv-var-lib-libvirt /tmp/libvirt
(gemini) $ df /tmp/libvirt
(gemini) $ sudo -i
(gemini) # cd /var/lib
(gemini) # tar cSf - libvirt | ( cd /tmp ; tar xSf - )
(gemini) # ls -l /tmp/libvirt
(gemini) # ls -ld /tmp/libvirt /var/lib/libvirt
(gemini) # exit
(gemini) $ sudo umount /tmp/libvirt
(gemini) $ sudo rm -rf /var/lib/libvirt
(gemini) $ sudo mkdir /var/lib/libvirt
(gemini) $ sudo mount /dev/vg-kvm/lv-var-lib-libvirt /var/lib/libvirt
(gemini) $ df /var/lib/libvirt

(gemini) $ sudo mount /dev/vg-kvm/lv-var-log-libvirt /tmp/libvirt
(gemini) $ df /tmp/libvirt
(gemini) $ sudo -i
(gemini) # cd /var/log
(gemini) # tar cSf - libvirt | ( cd /tmp ; tar xSf - )
(gemini) # ls -l /tmp/libvirt
(gemini) # ls -ld /tmp/libvirt /var/log/libvirt
(gemini) # exit
(gemini) $ sudo umount /tmp/libvirt
(gemini) $ sudo rm -rf /var/log/libvirt
(gemini) $ sudo mkdir /var/log/libvirt
(gemini) $ sudo mount /dev/vg-kvm/lv-var-log-libvirt /var/log/libvirt
(gemini) $ df /var/log/libvirt

(gemini) $ sudo rmdir /tmp/libvirt

fstabを更新
(gemini) $ sudo vi /etc/fstab
以下の行を追加
--ココから
/dev/mapper/vg--kvm-lv--etc--libvirt /etc/libvirt ext4 _netdev 0 0
/dev/mapper/vg--kvm-lv--var--lib--libvirt /var/lib/libvirt ext4 _netdev 0 0
/dev/mapper/vg--kvm-lv--var--log--libvirt /var/log/libvirt ext4 _netdev 0 0
--ココまで

(gemini) $ sudo umount /etc/libvirt
(gemini) $ sudo umount /var/log/libvirt
(gemini) $ sudo umount /var/lib/libvirt
(gemini) $ sudo mount -a
(gemini) $ df

自動アクティベート対象にする。
(gemini) $ sudo vi /etc/lvm/lvm.conf
--ココから
1156行目付近
auto_activation_volume_list = [ "gemini-vg" ]
↓項目追加
auto_activation_volume_list = [ "gemini-vg", "vg-kvm" ]
--ココまで

もう1つ、KVMホストは実はcifsマウントもしている。
(OSのisoメディアを配置するディスクはcifsにした。これなら別のWindowsマシンからも利用が可能だからだ。)
cifsマウント用のパッケージの導入
(gemini) $ sudo apt-get install cifs-utils

そのマウントポイントを作成する。
(gemini) $ sudo mkdir /mnt/iso-os

fstabに追記する。
(gemini) $ sudo vi /etc/fstab
以下の行を追記
--ココから
//(cifsのIPアドレス)/(cifsのディレクトリ) /mnt/iso-os cifs guest,_netdev 0 0
--ココまで

マウント確認
(gemini) $ sudo mount /mnt/iso-os
(gemini) $ df /mnt/iso-os
(gemini) $ sudo umount /mnt/iso-os

再起動してマウント状態の確認
(gemini) $ sudo shutdown -r now
(gemini) $ df

これでgeminiは、KVMホストのaquarius/sagittariusとほぼ同じ環境になったはずだ。

あれ…何度再起動しかけても、KVMホストマシンで発生している現象が起きない…な…。

そういえば、ココでnetworking.serviceを無効にしてたんだった。
それも適用してみよう。
(gemini) $ sudo systemctl stop networking.service
(gemini) $ sudo systemctl is-active networking.service
(gemini) $ sudo systemctl disable networking.service
(gemini) $ sudo systemctl is-enabled networking.service

--2017/04/20追記--
そもそも、 networking.service が failed になる理由だけど…。
今回、 OpenvSwitch で br-external という仮想スイッチ(仮想デバイス)を作成している。物理デバイスは存在しないデバイスだ。
networking.service は、 /etc/network/interfaces と /etc/network/interfaces.d/* で auto に指定されているデバイスは起動時に有効にしようとするが、 br-external は物理デバイスが無いため、 networking.service では有効に出来ない。(openvswitch-nonetwork.service にて有効にされる。)
networking.service が failed になる理由は、起動時に br-external を有効化しようとしてコケるからだ。

というわけで、 br-external は networking.service からは有効化されないように設定しよう。
(gemini) $ sudo cp -pi /etc/default/networking /etc/default/netwoking.orig
(gemini) $ sudo vi /etc/default/networking
--ココから
8行目付近
#EXCLUDE_INTERFACES=
↓(br-externalを指定)
EXCLUDE_INTERFACES=br-external
--ココまで

(gemini) $ sudo systemctl daemon-reload

networking.service は有効化しておこう。
(gemini) $ sudo systemctl enable networking.service
(gemini) $ sudo systemctl is-enabled networking.service

これで、再起動しても networking.service が failed になることは無いはずだ。
--2017/04/20追記ココまで--
--2017/04/20削除ココから--
これで再起動してみると…。再現した!というか、状況はもっと悪くて、vg-kvmがアクティベートされてない!?

なるほど、networking.serviceを無効にしたら停止や再起動で刺さったような状態になるのか…。
実際にaquariusで停止を実行しようとすると、cifsアンマウントやiSCSI領域のアンマウント前にOpenvSwitchが停止しているように見える。
cifsやiSCSIは、OpenvSwitchのネットワークを経由して接続している。これらの停止前にOpenvSwitchが停止してはマズいのだ。

しかし、networking.serviceを有効にすると、systemctlでFaild:1unitsになってしまう。
これはこれで問題だ。
どうすりゃいいんだろうか。

gfs2マウントについて(その1:自動マウント)」辺りと同じように、x-systemd.requiresを設定して対応するのではないだろうか?

ちょっと長いのと、調査に時間がかかるので、ここで一旦記事を切ろう。
--2017/04/20削除ココまで--

2017年3月3日金曜日

iSCSIでmultipath

さて、試してみたいことはたくさんある。
その内の1つが、iSCSIストレージでmultipathは使えるのか?だ。

ストレージ装置(SAN/iSCSI等)とサーバ間の接続を、冗長構成を考慮して複数のパスを用意した場合、ディスクデバイスが複数個に見えてしまう。
同一のディスクデバイスに対して、複数のデバイスファイルが見えてしまうと、管理上めちゃくちゃ面倒くさい。
同一のディスクデバイスに対して、1つの仮想デバイスファイルを用意して、ボリューム管理をそのデバイスファイルに対して行えるようにする、というのがmultipathだ。
下の図だと、パスが2系統有る。この場合、同一の領域(LUN)に対して、OSは2つのデバイスファイル(例えば、/dev/sdgと/dev/sdh)を作成する。
が、この両方を操作するのは面倒くさい。
multipathを使うと、これを1つの仮想デバイス(例えば、/dev/mapper/mpathc等)に紐付けられる。
ディスクに対する操作(parted等)は、その/dev/mapper/mpathcに対して行うことになる。

仕事では、FC接続の場合でこのmultipathを使うことは多かった。(iSCSIでmultipathは実装したことが無い。)

更に、ウチの環境ではiSCSIこそあれど、パスはシングルだ。
シングルパスの場合、multipathを用いるメリットは殆ど無いのだが、iSCSIでmultipathが使えるのかどうか、試してみたいと思っていた。

とりあえず、gemini/cancerというゲストマシンがあるので、この2つとiSCSIストレージを使って、iSCSIディスクが使えるように環境を整える。
手順は、「iSCSIを利用しようその1」等に従えばいい、はずだ。

今回は、iSCSIターゲットは1つで、そのiSCSIターゲットに対して、gemini/cancerともに接続出来るようにしておくよ。

1つだけLUN(100GB)を割り当てたら、/dev/sdaとして見えてきた。

gemini/cancerから、LUNが見える状態になったこと、iSCSIターゲットへの自動ログインが確認できたら、multipathを導入してみる。
(現時点では、LUN(/dev/sda)に対してパーティションの作成等は不要だ)
(gemini) $ sudo apt-get update
(gemini) $ sudo apt-cache search multipath

multipath-toolsっぽいな。
(gemini) $ sudo apt-get --simulate install multipath-tools
(gemini) $ sudo apt-get install multipath-tools

cancerにも。
(cancer) $ sudo apt-get update
(cancer) $ sudo apt-get install multipath-tools

導入できたら、デーモンの確認。
(gemini) $ ps -ef | grep multipath
(cancer) $ ps -ef | grep multipath
/sbin/multipathdというデーモンが動きだしたはず。

syslog見てみよう。
(gemini) $ tail -30 /var/log/syslog
エラーは特に無さそうだ。

が、multipathデバイスが出来ている様子が無い…。
多分、再起動しても無駄だと思うが…。
(gemini) $ sudo shutdown -r now

げ、再起動したら/etc/multipathディレクトリが出来上がったよ…。再起動必要なんかい!?
その中には、wwidsというファイルが出来上がっているが、中身は空(コメントのみ)。

それ以前に、multipath.confが必要なはずなんだが…。Ubuntuでは用意されてないのかな…。
(gemini) $ dpkg -L multipath-tools
サンプルっぽいのが2つある。
/usr/share/doc/multipath-tools/examples/multipath.conf.annotated.gz
/usr/share/doc/multipath-tools/examples/multipath.conf.synthetic

どちらも中身はすべて#で始まる無効行だが、前者の方がコメントがしっかり書かれている。
こちらを/etcの下に展開してしまおう。
(gemini) $ ls /etc/multipath.conf
(gemini) $ cd /usr/share/doc/multipath-tools/examples
(gemini) $ sudo bash -c "zcat multipath.conf.annotated.gz > /etc/multipath.conf"
(gemini) $ ls /etc/multipath.conf
(gemini) $ cd

(gemini) $ sudo systemctl daemon-reload
う~ん。まぁ中身が全部コメントだったから、何も変化は無いよな。

ちょっとmultipathの結果を見てみよう。
(gemini) $ sudo multipath -v 3
以下のような行が出た…。
wwid 23966323038343131 not in wwids file, skipping sda
この、239...という数字は、/dev/disk/by-id/ の中で/dev/sdaにリンクが貼られているファイルの名前と同じだ。
つまり、このディスク(/dev/sda)のuuid/wwidってことだよな…。

そして、not in wwids fileということは、逆に言うとwwidsファイルに記載したら何か起きるのか?

書き込んでみよう。
なんか、wwidsファイルにwwidを書く時は、/で囲わないといけないっぽい。
(gemini) $ sudo bash -c "echo /23966323038343131/ >> /etc/multipath/wwids"
(gemini) $ sudo cat /etc/multipath/wwids

(gemini) $ sudo multipath -v 3
お、変化が出た。
色々メッセージが出たけど、その中に
create: 23966323038343131 undef ASUSTOR,iSCSI Storage
というのが出てきた。

これは…
(gemini) $ sudo multipath -ll
23966323038343131 dm-2 ASUSTOR,iSCSI Storage
size=100G features='0' hwhandler='0' wp=rw
`-+- policy='round-robin 0' prio=1 status=active
`- 8:0:0:0 sda 8:0 active ready running
出来てる!

(gemini) $ ls -l /dev/mapper
数字の羅列のデバイスファイルが出来上がってるぞ。

これ、ディスク操作とかに使えるのかな?
(gemini) $ sudo parted /dev/mapper/23966323038343131 print
出来た。

しかしこれではちょっと見にくい。
なにせ名前が数字の羅列だ。
というわけで、分かりやすい名前に変更する方法を確認。
multipath.confのuser_friendly_nameというのが該当の設定項目だ。
さっそく変更しよう。
(gemini) $ sudo vi /etc/multipath.conf
--ココから
10行目付近
#defaults {
↓先頭の#を削除
defaults {

215行目付近
# user_friendly_names no
↓先頭の#を削除し、no→yesへ書き換え
user_friendly_names yes

341行目付近
#}
↓先頭の#を削除
}
--ココまで

設定の再読込み
(gemini) $ sudo systemctl reload multipathd.service

確認
(gemini) $ sudo multipath -ll
mpatha (23966323038343131) dm-2 ASUSTOR,iSCSI Storage
size=100G features='0' hwhandler='0' wp=rw
`-+- policy='round-robin 0' prio=1 status=active
`- 8:0:0:0 sda 8:0 active ready running
mpathaと表示された!

(gemini) $ ls -l /dev/mapper
数字のデバイスファイルが消えて、mpathaが作成された。

(gemini) $ sudo parted /dev/mapper/mpatha print
ディスク認識OK。

(gemini) $ sudo cat /etc/multipath/bindings
wwidsとmpathaを紐付けるファイルが出来上がっている。

(gemini) $ lsblk /dev/sda
sdaからmpathaが作られている、ということが分かる。

これで最低限の設定は出来た。
パフォーマンスチューニング等、/etc/multipath.confを手直しすることになるんだけど、そこまで実施はしない。
(本当に複数パスで繋いでいる場合、パス分散ルールを変えることでパフォーマンス向上が期待できるけど、自分の構成ではシングルパスでしか繋いでいないので意味が無い…。)

さて、もう1つだけ実験しておこう。
デバイス名が/dev/mapper/mpathaになったけど、この名前を変更できるのだろうか?
なんとなく、/etc/multipath/bindingsファイルを書き換えれば実現できそうだ。
試してみよう。
(gemini) $ sudo vi /etc/multipath/bindings
以下のように修正
--ココから
mpatha 23966323038343131

ocfs2-001 23966323038343131
--ココまで
今回、iSCSIストレージ装置側で作成した100GBのLUNの名前を、ocfs2-001としておいた。
サーバ側でも同じ名前だと管理が楽かもしれない。
ということでこの名前が使えるかを試してみる。

変更したら、一旦マルチパスデバイスを消して…
(gemini) $ sudo multipath -F /dev/sda
(gemini) $ sudo multipath -ll
消えたのを確認したら、デバイス再読込み…
(gemini) $ sudo multipath -r /dev/sda
で、ocfs2-001という名前で作られるようだ。

(gemini) $ sudo multipath -ll
出来上がった。

念のためデバイスファイルの確認
(gemini) $ ls -l /dev/mapper
ocfs2-001に変わっている。

ディスク確認
(gemini) $ sudo parted /dev/mapper/ocfs2-001 print
きちんと読み込める。(パーティション情報が一切ないので、ラベルが認識できない等のエラーになるが、無視してOK。)

さて、途中からgeminiにのみ設定を施していたので、cancer側も同じ設定を施しておく。
geminiとは若干順番が変わっているが気にしないでいい。

まずはmultipath.confファイルの作成。
(cancer) $ ls /etc/multipath.conf
(cancer) $ cd /usr/share/doc/multipath-tools/examples
(cancer) $ sudo bash -c "zcat multipath.conf.annotated.gz > /etc/multipath.conf"
(cancer) $ ls /etc/multipath.conf
(cancer) $ cd

multipath.confのカスタマイズ
(cancer) $ sudo vi /etc/multipath.conf
--ココから
10行目付近
#defaults {
↓先頭の#を削除
defaults {

215行目付近
# user_friendly_names no
↓先頭の#を削除し、no→yesへ書き換え
user_friendly_names yes

341行目付近
#}
↓先頭の#を削除
}
--ココまで
(cancer) $ sudo systemctl reload multipathd.service

まだwwidsファイルは出来上がってないと思うので、一旦OS再起動。
(cancer) $ sudo shutdown -r now

wwidsファイル変更(geminiの時は直接編集したが、今回はmultipathコマンドで編集)
(cancer) $ ls -ld /etc/multipath
(cancer) $ sudo ls -l /etc/multipath
(cancer) $ sudo cat /etc/multipath/wwids
(cancer) $ sudo multipath -a /dev/sda
(cancer) $ sudo cat /etc/multipath/wwids

multipathデバイスの認識。
(cancer) $ sudo multipath -ll /dev/sda
(cancer) $ sudo multipath -r /dev/sda
(cancer) $ sudo multipath -ll /dev/sda

デバイスファイル名の修正
(cancer) $ sudo vi /etc/multipath/bindings
以下のように修正
--ココから
mpatha 23966323038343131

ocfs2-001 23966323038343131
--ココまで

(cancer) $ sudo multipath -ll /dev/sda
(cancer) $ sudo multipath -F /dev/sda
(cancer) $ sudo multipath -ll /dev/sda
(cancer) $ sudo multipath -r /dev/sda
(cancer) $ sudo multipath -ll /dev/sda

とりあえず、これでiSCSIボリュームをmultipathd管理にすることは完了。

2017年3月2日木曜日

VGのSharedフラグ

クラスタマークを付けたVG(vgchange -c y)に対してvgdisplayを実行すると、Clusterdというパラメータの他に、Sharedというパラメータが表示される。

このSharedは、いつ見ても「no」になっていて、一体このフラグが何を意味しているのか?どういう状況で「yes」に変わるのか?が分からないでいた。

というわけで、今回はこれを調べてみたい。

が…Webで調べてもマニュアルを読んでも、このあたり全然情報が無い。調べ方が悪いのか?
こうなってくると、もうソースを読んで見るしか無いわけだが…正直なところ、あまりやりたくない。

ので、軽く調べて「分かりませんでした」という結論にしたいと思う。

まずはソースコードの入手。
Ubuntuのパッケージ検索サイトから、キーワード「clvm」、Distribution「xenial」で検索し、ヒットした結果の「lvm2ソースパッケージのダウンロード」から[lvm2_2.02.133.orig.tar.xz]をダウンロードする。
とは言っても、gemini/cancerにはwebブラウザは導入していないので、ダウンロードurlをwget/curlで取得しよう。
(gemini) $ wget http://archive.ubuntu.com/ubuntu/pool/main/l/lvm2/lvm2_2.02.133.orig.tar.xz
もしくは
(gemini) $ curl http://archive.ubuntu.com/ubuntu/pool/main/l/lvm2/lvm2_2.02.133.orig.tar.xz > lvm2_2.02.133.orig.tar.xz

ダウンロードしたらファイルの展開だ。
.tar.xz形式なので、オプションに注意だ。
(gemini) $ tar tvJf lvm2_2.02.133.orig.tar.xz
(gemini) $ tar xvJf lvm2_2.02.133.orig.tar.xz
lvm2-2.02-133というディレクトリが作成され、その下に展開される。

(gemini) $ cd lvm2-2.02.133
ここからは、ソースファイル(.c)やヘッダファイル(.h)を色々漁って探してみる。

vgdisplayというファイルがあるかも。
(gemini) $ find . -name "*vgdisplay*" -print
./man/vgdisplay.8.in
./tools/vgdisplay.c
あった。
前者はマニュアルなので、後者(./tools/vgdisplay.c)がそれっぽい。

中身を確認してみよう。
(gemini) $ view ./tools/vgdisplay.c
う~ん。何かチガウな…。

「Shared」というキーワードで調べてみよう…。
(gemini) $ find . -type f -print | xargs grep Shared
30行ぐらい出て来るが、その中の1つにそれっぽい行がある。
./lib/display/display.c: log_print("Shared %s",
だ。

どうやら、./lib/display/display.cに、vgdisplayのSharedフラグを表示する行があるっぽい。
見てみよう。
(gemini) $ view ./lib/display/display.c
あったあった。
一部引用する。
--ココから
void vgdisplay_full(const struct volume_group *vg)
{
(略)
log_print("--- Volume group ---");
log_print("VG Name %s", vg->name);
(略)
if (vg_is_clustered(vg)) {
log_print("Clustered yes");
log_print("Shared %s",
vg->status & SHARED ? "yes" : "no");
}
(略)
log_print(" ");
}
--引用ココまで
なるほど、vg構造体ポインタのstatus値でSHAREDフラグが立っていたら「yes」、立っていいなければ「no」か。
(構造体やら論理式やら三項演算子やらが入った行なので、分からなければ「一応、no固定で出しているわけじゃなく、yesかnoかを判定する処理は入ってるんだな」程度の理解でいいだろう。)

vg構造体(volume_group構造体)のstatusフラグか…。一体ドコに更新処理が入ってるんだろう…?この値が更新されないと、Sharedがyesになることは無いんだよな…。

ちょっと検索。
(gemini) $ find . -type f -print | xargs grep status | grep SHARED
う~む。
./lib/format1/import-export.c
./lib/format_pool/import_export.c
の2つのファイルで、SHAREDフラグを立ててるっぽいなぁ。
逆に、フラグを倒す部分が見つからなかった。検索漏れかな?

とりあえず、両ファイルを見てみるか。
(gemini) $ view ./lib/format1/import-export.c
(gemini) $ view ./lib/format_pool/import_export.c
後者はちょっと分からなかった…。
前者は、
  • vgをexportする時、当該vgのSHAREDフラグが立ってたら、export情報にもSHARED情報を載せるよ。
  • vgをimportする時、入力情報にSHARED情報が載っていたら、import時にSHAREDフラグを立てるよ。
というモノだった。
なんじゃそりゃ…。結局、明示的にSHAREDフラグを立てる方法は無いんかい!?

更に色々見ていったら、vgcreateのmanに、--sharedというオプションがある。
これ、vgcreate時に指定できるけど、vgchangeで変更出来るようには見えない。もしかしたら、vgchange --lock-typeで変更出来るのか…?

いずれにしても、lvmlockdというのが関連しているようなんだけど、Ubuntuにはlvmlockdは実装されていないっぽい。
もはや、vgのSharedフラグは無視してもいいんじゃないか…。

Sharedフラグがlvmlockdに関連すると仮定して、更にwebを調べてみたら、lvmlockdを使用する場合は/etc/lvm/lvm.confのlocking_typeを1(LVM uses local file-based locking, the standard mode.)に設定する必要があるようだ。
CLVMを用いる場合は、同フラグを3(LVM uses built-in clustered locking with clvmd.)に設定するため、どうやらCLVMとlvmlockdは排他使用のようだ。

Ubuntu16.04にはlvmlockdは実装されていないっぽい&CLVMとlvmlockdは競合する、ということで、これ以上の調査は止めよう。

ということで、Sharedフラグは無視することに。