カテゴリー
未分類

HDDでLVMストライプしたボリュームを作る

HDDでも同様な実験を行なってみました。
こちらは WDC WD15EARS(1.5TB)×2本と同じく WD10EALS(1TB)×4本でVGを構成しています。
PEサイズはデフォルトの4MBではなく16MBになっています。これはLVサイズの上限256MB(4MB×65536個)の壁を超えるためです。

大台の300MB/sを超えている部分を緑で強調表示しています。最大値を太字で示しています。


こちらの環境に限れば、チャンクサイズはデフォルトの64KBで良さそうな感じです。
わざわざ変えるメリットは見当たりません。

カテゴリー
未分類

SSDでLVMストライプしたボリュームを作る(3)

各チャンクサイズで作成したLVに対して異なるブロックサイズで書き込みを行なった実験結果は以下の通りです。
1 GB/sの大台に乗っているものは緑色で強調表示しています。
HDD/SSDのアクセスLEDの点灯状況を眺めていると、結果をまとめる前に予想できました。全ドライブのアクセスLEDが同時に全点灯していれば、並行同時アクセスできる証拠です。そのほうが良い結果を出しています。

各チャンクサイズで作成したLVに対して異なるブロックサイズで書き込みを行なった結果

今回の実験結果から以下のことがわかりました。回転待ちの発生しないSSDの場合には、チャンクサイズをデフォルトの64KBだとOKだと思います。わざわざ変える必要、チューニングする必要はないようです。OSが大きな単位の書き込みを行なったとしても、それが複数ドライブにまたがって並行分散同時アクセスができなくなりますので、平均転送速度は低下します。


今回はddコマンドを使って、ブロックデバイスを直接書き込んでいます。
通常は、ブロックデバイス上にファイルシステムを作成し、さらにアプリケーション、カーネルが適度なバッファリングを行ないながら書き込みを行なっています。よりチャンクサイズの差は、よりわかり難くなっているかもしれません。チャンクサイズに応じて、階層のI/Oサイズが最適化されているならば凄いですね。

カテゴリー
未分類

SSDでLVMストライプしたボリュームを作る(2)

LV名にチャンクサイズを単位KBで埋め込んだのは妙案だと思ったのですが、
テストするときにややこしいです。
以下のようににて時刻順(昇順)にして並べ替えることができました。

# ls -rt /dev/VG1/striped*  | cat
/dev/VG1/striped32K
/dev/VG1/striped64K
/dev/VG1/striped128K
/dev/VG1/striped256K
/dev/VG1/striped512K
/dev/VG1/striped1024K
/dev/VG1/striped2048K
/dev/VG1/striped4096K

ファイルシステムを作る前のこの状態で簡単に性能を測ってみます。
ddコマンドと /usr/bin/time コマンドを使います。
bashの組み込みの time コマンドではありません。
まずは理論上の上限を推察します。そのために10GBくらいのデータを
書き込んでいます。データを生成する速度はそれよりもうんと速いという前提ではありますが。。。

以下のような簡単なスクリプトを作って、ブロックサイズ(bs)を変えながら総バイト数10GB を /dev/null に書き込む(実際には書き込まない、捨てるだけ)ようにしました。

# cat dd-10GB.bash
#!/bin/bash
DEVICE=/dev/null
max=$(( 1024*1024*1024*10 ))

for pow in `seq 9 20`
do
bs=$(( 2**$pow ))
count=$(( $max/$bs ))
echo /usr/bin/time dd if=/dev/zero of=$DEVICE bs=$bs count=$count
/usr/bin/time dd if=/dev/zero of=$DEVICE bs=$bs count=$count
done

実行結果は以下の通りです。
bsが256KBくらいで飽和しています。
壁の時計が1秒進む前に10GBの転送が終わってしまっています。
もう少し時間を稼ぐべきかもしれません。

# bash dd-10GB.bash
/usr/bin/time dd if=/dev/zero of=/dev/null bs=512 count=20971520
20971520+0 レコード入力
20971520+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 12.3932 s, 866 MB/s
3.54user 8.83system 0:12.39elapsed 99%CPU (0avgtext+0avgdata 2204maxresident)k
0inputs+0outputs (0major+95minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=1024 count=10485760
10485760+0 レコード入力
10485760+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 6.44634 s, 1.7 GB/s
1.54user 4.89system 0:06.44elapsed 99%CPU (0avgtext+0avgdata 2268maxresident)k
0inputs+0outputs (0major+99minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=2048 count=5242880
5242880+0 レコード入力
5242880+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 3.66838 s, 2.9 GB/s
0.86user 2.79system 0:03.66elapsed 99%CPU (0avgtext+0avgdata 2208maxresident)k
0inputs+0outputs (0major+96minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=4096 count=2621440
2621440+0 レコード入力
2621440+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 2.13416 s, 5.0 GB/s
0.44user 1.68system 0:02.13elapsed 99%CPU (0avgtext+0avgdata 2200maxresident)k
0inputs+0outputs (0major+94minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=8192 count=1310720
1310720+0 レコード入力
1310720+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 1.49307 s, 7.2 GB/s
0.21user 1.27system 0:01.49elapsed 99%CPU (0avgtext+0avgdata 2204maxresident)k
0inputs+0outputs (0major+95minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=16384 count=655360
655360+0 レコード入力
655360+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 1.15523 s, 9.3 GB/s
0.11user 1.03system 0:01.15elapsed 99%CPU (0avgtext+0avgdata 2280maxresident)k
0inputs+0outputs (0major+100minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=32768 count=327680
327680+0 レコード入力
327680+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 0.974549 s, 11.0 GB/s
0.06user 0.90system 0:00.97elapsed 99%CPU (0avgtext+0avgdata 2232maxresident)k
0inputs+0outputs (0major+102minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=65536 count=163840
163840+0 レコード入力
163840+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 0.887813 s, 12.1 GB/s
0.02user 0.85system 0:00.88elapsed 99%CPU (0avgtext+0avgdata 2260maxresident)k
0inputs+0outputs (0major+110minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=131072 count=81920
81920+0 レコード入力
81920+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 0.844839 s, 12.7 GB/s
0.02user 0.81system 0:00.84elapsed 99%CPU (0avgtext+0avgdata 2452maxresident)k
0inputs+0outputs (0major+127minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=262144 count=40960
40960+0 レコード入力
40960+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 0.815341 s, 13.2 GB/s
0.00user 0.80system 0:00.81elapsed 99%CPU (0avgtext+0avgdata 2580maxresident)k
0inputs+0outputs (0major+160minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=524288 count=20480
20480+0 レコード入力
20480+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 0.816412 s, 13.2 GB/s
0.00user 0.80system 0:00.81elapsed 99%CPU (0avgtext+0avgdata 2708maxresident)k
0inputs+0outputs (0major+222minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=1048576 count=10240
10240+0 レコード入力
10240+0 レコード出力
10737418240 bytes (11 GB, 10 GiB) copied, 0.809183 s, 13.3 GB/s
0.00user 0.80system 0:00.81elapsed 99%CPU (0avgtext+0avgdata 3224maxresident)k
0inputs+0outputs (0major+351minor)pagefaults 0swaps

もう少し精度を高めるべく、16GB、32GBでも試しています。
以下は16GBにした場合です。最大で13.4GB/s くらいです。

/usr/bin/time dd if=/dev/zero of=/dev/null bs=131072 count=131072
131072+0 レコード入力
131072+0 レコード出力
17179869184 bytes (17 GB, 16 GiB) copied, 1.34912 s, 12.7 GB/s
0.01user 1.32system 0:01.35elapsed 99%CPU (0avgtext+0avgdata 2452maxresident)k
0inputs+0outputs (0major+127minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=262144 count=65536
65536+0 レコード入力
65536+0 レコード出力
17179869184 bytes (17 GB, 16 GiB) copied, 1.32563 s, 13.0 GB/s
0.01user 1.30system 0:01.32elapsed 99%CPU (0avgtext+0avgdata 2584maxresident)k
0inputs+0outputs (0major+160minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=524288 count=32768
32768+0 レコード入力
32768+0 レコード出力
17179869184 bytes (17 GB, 16 GiB) copied, 1.28532 s, 13.4 GB/s
0.00user 1.27system 0:01.28elapsed 99%CPU (0avgtext+0avgdata 2772maxresident)k
0inputs+0outputs (0major+224minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=1048576 count=16384
16384+0 レコード入力
16384+0 レコード出力
17179869184 bytes (17 GB, 16 GiB) copied, 1.3062 s, 13.2 GB/s
0.00user 1.29system 0:01.30elapsed 99%CPU (0avgtext+0avgdata 3284maxresident)k
0inputs+0outputs (0major+353minor)pagefaults 0swaps

以下は32GBにした場合です。最大で13.5GB/s くらいです。

/usr/bin/time dd if=/dev/zero of=/dev/null bs=131072 count=262144
262144+0 レコード入力
262144+0 レコード出力
34359738368 bytes (34 GB, 32 GiB) copied, 2.70391 s, 12.7 GB/s
0.05user 2.63system 0:02.70elapsed 99%CPU (0avgtext+0avgdata 2264maxresident)k
0inputs+0outputs (0major+126minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=262144 count=131072
131072+0 レコード入力
131072+0 レコード出力
34359738368 bytes (34 GB, 32 GiB) copied, 2.59097 s, 13.3 GB/s
0.02user 2.56system 0:02.59elapsed 99%CPU (0avgtext+0avgdata 2580maxresident)k
0inputs+0outputs (0major+159minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=524288 count=65536
65536+0 レコード入力
65536+0 レコード出力
34359738368 bytes (34 GB, 32 GiB) copied, 2.58548 s, 13.3 GB/s
0.00user 2.57system 0:02.58elapsed 99%CPU (0avgtext+0avgdata 2712maxresident)k
0inputs+0outputs (0major+223minor)pagefaults 0swaps
/usr/bin/time dd if=/dev/zero of=/dev/null bs=1048576 count=32768
32768+0 レコード入力
32768+0 レコード出力
34359738368 bytes (34 GB, 32 GiB) copied, 2.53585 s, 13.5 GB/s
0.00user 2.52system 0:02.53elapsed 99%CPU (0avgtext+0avgdata 3284maxresident)k
0inputs+0outputs (0major+352minor)pagefaults 0swaps

上記の通り、どんなに頑張ってもこのマシンでは dd コマンドで 13.5GB/s の壁が越えられないことがわかりました。
今度は、書き込み先を /dev/null から LV にします。まだファイルシステムは使いません。
以下の通り、ブロックデバイスかどうかだけは、test するようにします。
書き込み先を間違えると、簡単にファイルシステムが壊れるので。。。

# ls -l /dev/VG1/striped128K
lrwxrwxrwx 1 root root 7  3月 21 11:00 /dev/VG1/striped128K -> ../dm-5
# ls -lL /dev/VG1/striped128K
brw-rw---- 1 root disk 253, 5  3月 21 11:00 /dev/VG1/striped128K
[root@pc02 keizof]# test -b /dev/VG1/striped128K; echo $?
0
# test -b /dev/dm-5; echo $?
0

ということで以下のスクリプト 16GB版を作ってみました。

# cat dd-16GB.bash
#!/bin/bash
if [ $# -ne 1 ]; then
echo usage: $0 device
exit 1
fi
if [ ! -b "$1" ]; then
echo "$1" is not block device.
exit 1
fi
max=$(( 1024*1024*1024*16 ))
for pow in `seq 9 20`
do
bs=$(( 2**$pow ))
count=$(( $max/$bs ))
echo /usr/bin/time dd if=/dev/zero of="$1" bs=$bs count=$count                            /usr/bin/time dd if=/dev/zero of="$1" bs=$bs count=$count
done
カテゴリー
未分類

SSDでLVMストライプしたボリュームを作る(1)

Linux LVM2にて RAID0 Striped ボリュームを作れるそうです。
約1年かけて買いためた SSD 480GB (CFD販売, SSD-S6O480CG3VP)が沢山あるので、それを束ねて自家最高速のオールフラッシュのストレージを作って iSCSI で利用したいと思います。

lvcreate するときにいくつかのオプションを指定します。
以下 man ページからの抜粋です。

$ man lvcreate
-i|--stripes Number
-I|--stripesize Size[k|UNIT]
-n|--name String
--type striped

以下の5本のSSDによるPV(物理ボリューム)から構成されたVG(ボリュームグループ)に対してLV(論理ボリューム)を切り出します。
VGを作るときに特別ばオプションを指定しなかったのでデフォルトのままです。
PEサイズが4MBなのが後で問題になります。

# vgdisplay VG1
--- Volume group ---
VG Name               VG1
System ID
Format                lvm2
Metadata Areas        5
Metadata Sequence No  33
VG Access             read/write
VG Status             resizable
MAX LV                0
Cur LV                0
Open LV               0
Max PV                0
Cur PV                5
Act PV                5
VG Size               2.18 TiB
PE Size               4.00 MiB ★
Total PE              572325
Alloc PE / Size       0 / 0
Free  PE / Size       572325 / 2.18 TiB
VG UUID               5dMsuo-nRfw-71Ay-B8kP-7Mpc-VYf2-OenbWL

ストライプするときの切り分け単位(チャンクサイズとも言う)を何KBにするのかに悩みました。
一般論、ハードウェアによるRAIDでは、
ランダムアクセスするなら小さいほうが良くて、
シーケンシャルアクセスするならば大きいほうが良いそうです。
HDD(SSDではなく)では、64KB前後(その1/2から数倍くらい)が多いそうです。
HDDではなくSSDの場合には最適値があるのでしょうか?
さらに、LVMでストライプするなら最適値があるのでしょうか?

というわけで、当家の環境における最適値を見付けるめに、チャンクサイズの異なるボリュームを作って実験してみることにしました。
以下のスクリプトで複数のLVを作りました。

#!bin/bash
for i in `seq 15 24`
do
echo $(( 2 ** i ))
echo $(( (2 ** i) / 1024 ))KB
echo lvcreate -L 200G -i 5 -I $(( (2 ** i) / 1024 )) -n striped$(( (2 ** i) / 1024 ))K --type striped VG1
lvcreate -L 200G -i 5 -I $(( (2 ** i) / 1024 )) -n striped$(( (2 ** i) / 1024 ))K --type striped VG1
sleep 5
done

実行結果は、以下の通りです。
PEサイズを超えたチャンクサイズは作れないそうです。
この壁を超えたいとなると、VGの作り直しとなります。

# bash lvm-striped.bash
32768
32KB
lvcreate -L 200G -i 5 -I 32 -n striped32K --type striped VG1
Logical volume "striped32K" created.
65536
64KB
lvcreate -L 200G -i 5 -I 64 -n striped64K --type striped VG1
Logical volume "striped64K" created.
131072
128KB
lvcreate -L 200G -i 5 -I 128 -n striped128K --type striped VG1
Logical volume "striped128K" created.
262144
256KB
lvcreate -L 200G -i 5 -I 256 -n striped256K --type striped VG1
Logical volume "striped256K" created.
524288
512KB
lvcreate -L 200G -i 5 -I 512 -n striped512K --type striped VG1
Logical volume "striped512K" created.
1048576
1024KB
lvcreate -L 200G -i 5 -I 1024 -n striped1024K --type striped VG1
Logical volume "striped1024K" created.
2097152
2048KB
lvcreate -L 200G -i 5 -I 2048 -n striped2048K --type striped VG1
Logical volume "striped2048K" created.
4194304
4096KB
lvcreate -L 200G -i 5 -I 4096 -n striped4096K --type striped VG1
Logical volume "striped4096K" created.
8388608
8192KB
lvcreate -L 200G -i 5 -I 8192 -n striped8192K --type striped VG1
Reducing requested stripe size 8.00 MiB to maximum, physical extent size 4.00 MiB.
Logical volume "striped8192K" created.
16777216
16384KB
lvcreate -L 200G -i 5 -I 16384 -n striped16384K --type striped VG1
Reducing requested stripe size 16.00 MiB to maximum, physical extent size 4.00 MiB.
Logical volume "striped16384K" created.

失敗(意図したチャンクサイズにならなかったLVは消しておきます。

# ls /dev/VG1/striped* | cat
/dev/VG1/striped1024K
/dev/VG1/striped128K
/dev/VG1/striped16384K
/dev/VG1/striped2048K
/dev/VG1/striped256K
/dev/VG1/striped32K
/dev/VG1/striped4096K
/dev/VG1/striped512K
/dev/VG1/striped64K
/dev/VG1/striped8192K
# lvremove /dev/VG1/striped16384K /dev/VG1/striped8192K
Do you really want to remove active logical volume VG1/striped8192K? [y/n]: y
Logical volume "striped8192K" successfully removed
Do you really want to remove active logical volume VG1/striped16384K? [y/n]: y
Logical volume "striped16384K" successfully removed

本当にストライプしているのか不安なので、少しだけ覗いてみました。
以下の通りなので大丈夫なのでしょう。

# lvdisplay -m /dev/VG1/striped1024K
--- Logical volume ---
LV Path                /dev/VG1/striped1024K
LV Name                striped1024K
VG Name                VG1
LV UUID                rx8idB-1FAI-l8ae-cxpJ-Ofwy-23dR-TlS590
LV Write Access        read/write
LV Creation host, time pc02.soar.keizof.com, 2020-03-21 11:00:53 +0900
LV Status              available
# open                 0
LV Size                200.00 GiB
Current LE             51200
Segments               1
Allocation             inherit
Read ahead sectors     auto
- currently set to     20480
Block device           253:8

--- Segments ---
Logical extents 0 to 51199:
Type                striped ★
Stripes             5
Stripe size         1.00 MiB ★
Stripe 0:
Physical volume   /dev/sdb
Physical extents  51200 to 61439 ★
Stripe 1:
Physical volume   /dev/sdc
Physical extents  51200 to 61439 ★
Stripe 2:
Physical volume   /dev/sdd
Physical extents  51200 to 61439 ★
Stripe 3:
Physical volume   /dev/sde
Physical extents  51200 to 61439 ★
Stripe 4:
Physical volume   /dev/sdf
Physical extents  51200 to 61439 ★

ちなみに、チャンクサイズを省略したときのデフォルトは 64KB です。

# lvcreate -i 5 -n default-chunk-size --type striped -L 200GB VG1
Using default stripesize 64.00 KiB.
Logical volume "default-chunk-size" created.
# lvdisplay -m /dev/VG1/default-chunk-size
--- Logical volume ---
LV Path                /dev/VG1/default-chunk-size
LV Name                default-chunk-size
VG Name                VG1
LV UUID                igh4R1-FcV2-8GxE-SBZK-3xKE-RQKD-ECvlFU
LV Write Access        read/write
LV Creation host, time pc02.soar.keizof.com, 2020-03-21 15:30:49 +0900
LV Status              available
# open                 0
LV Size                200.00 GiB
Current LE             51200
Segments               1
Allocation             inherit
Read ahead sectors     auto
- currently set to     8192
Block device           253:11

--- Segments ---
Logical extents 0 to 51199:
Type                striped
Stripes             5
Stripe size         64.00 KiB ★
Stripe 0:
Physical volume   /dev/sdb
Physical extents  81920 to 92159
Stripe 1:
Physical volume   /dev/sdc
Physical extents  81920 to 92159
Stripe 2:
Physical volume   /dev/sdd
Physical extents  81920 to 92159
Stripe 3:
Physical volume   /dev/sde
Physical extents  81920 to 92159
Stripe 4:
Physical volume   /dev/sdf
Physical extents  81920 to 92159
カテゴリー
KVM

KVMでiSCSIストレージを使ってライブなマイグレーションする(5)

今度ははじかれた側のKVMホスト上で初めてゲストOSをインストールします。
インストール先は LUN1 とします。

# virsh list --all
Id   Name   State
--------------------
# virt-install --name guest-iscsi-1 --arch x86_64 --os-type g
eneric --vcpus 4 --memory 4096 --disk vol=iscsipool1/unit:0:0:1 --network bridge=br0 --graphics vnc,keymap=ja --location /home/iso/CentOS-8.1.1911-x86_64-dvd1.iso --initrd-inject /home/iso/CentOS811911-ks.cfg --noautoconsole --extra-args "ks=file:/CentOS811911-ks.cfg text console=tty0 console=ttyS0,115200n8r"
Starting install...
Retrieving file .treeinfo...                          | 1.5 kB  00:00
Retrieving file vmlinuz...                            | 7.7 MB  00:00
Retrieving file initrd.img...                         |  59 MB  00:00
Domain installation still in progress. You can reconnect to
the console to complete the installation process.

# ls -l /var/lib/libvirt/lockd/scsivolumes/
-rw------- 1 root root 0  3月 15 22:26 36001405b56906a6f1b64077ba05c0f4b
-rw------- 1 root root 0  3月 15 22:45 36001405e6ea60493c19463baec9aa7c6

# virsh list --all
Id   Name            State
-------------------------------
3    guest-iscsi-1   running

root@newsol:~# virsh console guest-iscsi-1
Connected to domain guest-iscsi-1
Escape character is ^]
unbound-libs.x86_64 (287/436) のインストール中
python3-unbound.x86_64 (288/436) のインストール中
kernel-modules.x86_64 (289/436) のインストール中

まだインストールが始まった直後ですが、ロックファイルが生成されています。

インストールが終わると shutdown された状態になります。従来通りです。
起動してゲストにログインして ping しながらライブなマイグレーションを試してみます。
“–undefinesource” オプションを指定するので、
こちらからあちらにゲストOSが移動して後には何も残りません。

# virsh shutdown guest-iscsi-1
# virsh console guest-iscsi-1
CentOS Linux 8 (Core)
Kernel 4.18.0-147.el8.x86_64 on an x86_64
pc13 login: root
パスワード:
前回のログイン: Sun Mar 15 23:00:17 端末: ttyS0
[root@pc13 ~]# ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=255 time=0.688 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=255 time=0.356 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=255 time=0.357 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=255 time=0.356 ms
64 bytes from 192.168.1.1: icmp_seq=5 ttl=255 time=0.508 ms
64 bytes from 192.168.1.1: icmp_seq=6 ttl=255 time=0.330 ms
^]           # コンソールから一時的に抜けます。

# ssh root@172.16.1.93 "hostname;whoami;hostname"

# time virsh migrate --undefinesource --persistent \
--live guest-iscsi-1 qemu+ssh://172.16.1.93/system
real    0m7.170s
user    0m0.021s
sys     0m0.008s
# virsh list --all
Id   Name   State
--------------------

移行先のKVMホストで確認します。

# virsh list --all
Id   Name              State
---------------------------------
4    guest-local-hdd   running
6    guest-iscsi-0     running
8    guest-iscsi-1     running
# virsh console guest-iscsi-1
Connected to domain guest-iscsi-1
Escape character is ^]
64 bytes from 192.168.1.1: icmp_seq=186 ttl=255 time=0.357 ms
64 bytes from 192.168.1.1: icmp_seq=187 ttl=255 time=0.253 ms
64 bytes from 192.168.1.1: icmp_seq=188 ttl=255 time=0.272 ms
64 bytes from 192.168.1.1: icmp_seq=189 ttl=255 time=0.223 ms
64 bytes from 192.168.1.1: icmp_seq=190 ttl=255 time=0.247 ms
--- 192.168.1.1 ping statistics ---
190 packets transmitted, 190 received, 0% packet loss, time 628ms
rtt min/avg/max/mdev = 0.200/0.361/1.587/0.167 ms

という感じでたまたまかもしれませんが、1秒周期の ICMP エコー要求、応答を取りこぼさない程度にライブな移行ができています。

“–undefinesource” オプションを指定しない場合にはややこしくなります。
移行元では ”shut off” となり、エントリーはまだ残っています。

# ssh root@172.16.1.100 "hostname;whoami;hostname"
newsol
root
newsol
# time virsh migrate --persistent \
--live guest-iscsi-1 qemu+ssh://172.16.1.100/system
real    0m7.168s
user    0m0.033s
sys     0m0.008s
# virsh list --all
Id   Name              State
----------------------------------
4    guest-local-hdd   running
6    guest-iscsi-0     running
-    guest-iscsi-1     shut off

移行先では以下の通り”runring”です。

# virsh list --all
Id   Name            State
-------------------------------
7    guest-iscsi-1   running

# virsh console guest-iscsi-1
Connected to domain guest-iscsi-1
Escape character is ^]
64 bytes from 192.168.1.1: icmp_seq=157 ttl=255 time=0.356 ms
64 bytes from 192.168.1.1: icmp_seq=158 ttl=255 time=0.317 ms
64 bytes from 192.168.1.1: icmp_seq=159 ttl=255 time=0.286 ms
64 bytes from 192.168.1.1: icmp_seq=160 ttl=255 time=0.264 ms
--- 192.168.1.1 ping statistics ---
160 packets transmitted, 160 received, 0% packet loss, time 218ms
rtt min/avg/max/mdev = 0.197/0.374/1.780/0.238 ms

ここであえて、故意に移行元で “shut off”のゲストOSを起動すると何が起きるでしょうか?どうあるべきでしょうか?試してみます。

# virsh list --all
Id   Name              State
----------------------------------
4    guest-local-hdd   running
6    guest-iscsi-0     running
-    guest-iscsi-1     shut off
# virsh start guest-iscsi-1
error: Failed to start domain guest-iscsi-1
error: resource busy: Lockspace resource '36001405e6ea60493c19463baec9aa7c6' is locked

ちゃんと起動しませんでした。ロックファイルの仕組みがちゃんと動いているようです。これを実現するためにはファイル、ディレクトリの排他制御がちゃんと動いている必要があります。

カテゴリー
KVM

KVMでiSCSIストレージを使ってライブなマイグレーションする(4)

同様に、もう1台のKVMホストを準備します。
「KVMホストを跨いで」排他制御の仕組みを利用するのはiSCSI経由でゲストを格納するときだけです。そうではなく、KVMホストのローカルにゲストのボリュームを格納するときには関係ありません。

本筋からそれますが、まずは関係ない部分から確認します。
ゲストOSをKVMホストのローカルなEXT4ファイルシステム上の /home/kvm ディレクトリ以下に格納します。

# ls -l /home/kvm

# virsh list --all
Id   Name   State
--------------------

# virt-install --name guest-local-hdd --arch x86_64 \
--os-type generic --vcpus 4 --memory 4096 \
--disk path=/home/kvm/guest-local-hdd.img,format=qcow2,size=40 \
--network bridge=br0 --graphics vnc,keymap=ja \
--location /home/iso/CentOS-8.1.1911-x86_64-dvd1.iso \
--initrd-inject /home/iso/CentOS811911-ks.cfg \
--noautoconsole \
--extra-args "ks=file:/CentOS811911-ks.cfg text console=tty0 console=ttyS0,115200n8r"
Starting install...
Retrieving file .treeinfo...                                | 1.5 kB  00:00
Retrieving file vmlinuz...                                  | 7.7 MB  00:00
Retrieving file initrd.img...                               |  59 MB  00:00
Allocating 'guest-local-hdd.img'                            |  40 GB  00:09
Domain installation still in progress. You can reconnect to
the console to complete the installation process.
# virsh list
Id   Name              State
---------------------------------
3    guest-local-hdd   running

# virsh console guest-local-hdd
Connected to domain guest-local-hdd
Escape character is ^]
gettext-libs.x86_64 (220/436) のインストール中
libcroco.x86_64 (221/436) のインストール中
libfdisk.x86_64 (222/436) のインストール中
libmount.x86_64 (223/436) のインストール中
dbus-libs.x86_64 (224/436) のインストール中
dbus-tools.x86_64 (225/436) のインストール中
coreutils.x86_64 (226/436) のインストール中
途中省略
Executing com_redhat_kdump addon
Executing org_fedora_oscap addon
initramfs の生成中
インストール後のスクリプトを実行中
設定ファイルとキックスタートを保存中
インストールは完了しました。 ENTER を押して終了します:
Starting Reboot...
[  OK  ] Stopped Device-Mapper Multipath Device Controller.
[  491.169438] reboot: Restarting system
# virsh list --all
Id   Name              State
----------------------------------
-    guest-local-hdd   shut off

# ls -l /home/kvm/
-rw------- 1 libvirt-qemu libvirt-qemu 42956488704  3月 15 22:27 guest-local-hdd.img

# virsh start guest-local-hdd
Domain guest-local-hdd started

root@zfs93:/home# virsh list --all
Id   Name              State
---------------------------------
4    guest-local-hdd   running
# ls -l /var/lib/libvirt/lockd/files/ # NFS領域外
-rw------- 1 root root 0  3月 15 22:06 7948b1d523f2b3a15a53d01d1cbd283fb5a41ae2e817076cddbbf8db9ccfd03c
# ls -l /var/lib/libvirt/lockd/scsivolumes/ # NFS領域
合計 0

ファイルサイズが0のファイルを作っています。典型的なロックファイル(ファイル名と存在の有無に意味がある)のようです。
今度は iSCSIのプール “iscsipool1” の unit:0:0:0″にインストールします。ここは iSCSI的には LUN0 に対応しています。

# virt-install --name guest-iscsi-0 --arch x86_64 \
--os-type generic --vcpus 4 --memory 4096 \
--disk vol=iscsipool1/unit:0:0:0 \
--network bridge=br0 --graphics vnc,keymap=ja \
--location /home/iso/CentOS-8.1.1911-x86_64-dvd1.iso
--initrd-inject /home/iso/CentOS811911-ks.cfg \
--noautoconsole \
--extra-args "ks=file:/CentOS811911-ks.cfg text console=tty0 console=ttyS0,115200n8r"
Starting install...
Retrieving file .treeinfo...                                | 1.5 kB  00:00
Retrieving file vmlinuz...                                  | 7.7 MB  00:00
Retrieving file initrd.img...                               |  59 MB  00:00
Domain installation still in progress. You can reconnect to
the console to complete the installation process.
# virsh list
Id   Name              State
---------------------------------
4    guest-local-hdd   running
5    guest-iscsi-0     running

# ls -l /var/lib/libvirt/lockd/files/ # NFS領域外
-rw------- 1 root root 0  3月 15 22:06 7948b1d523f2b3a15a53d01d1cbd283fb5a41ae2e817076cddbbf8db9ccfd03c

# ls -l /var/lib/libvirt/lockd/scsivolumes/ # NFS領域
-rw------- 1 root root 0  3月 15 22:15 36001405b56906a6f1b64077ba05c0f4b

インストールの最中ですが、上記の通り、iSCSIの領域にゲストを格納すると、
ロックファイルが作成されています。
インストールが終わって shutdown の状態になるとロックファイルは消失します。
ゲストOSの稼働中に限ってロックが存在するという理由のためです。

[  OK  ] Reached target Final Step.
Starting Reboot...
[  393.009846] reboot: Restarting system

# virsh list --all
Id   Name              State
----------------------------------
4    guest-local-hdd   running
-    guest-iscsi-0     shut off

root@zfs93:/home# ls -l /var/lib/libvirt/lockd/scsivolumes/
ファイルはありません!
# virsh start guest-iscsi-0
Domain guest-iscsi-0 started

# ls -l /var/lib/libvirt/lockd/scsivolumes/
-rw------- 1 root root 0  3月 15 22:26 36001405b56906a6f1b64077ba05c0f4b

# virsh console guest-iscsi-0
Connected to domain guest-iscsi-0
Escape character is ^]

CentOS Linux 8 (Core)
Kernel 4.18.0-147.el8.x86_64 on an x86_64

pc01 login:

ほんのさっきインストールしたばかりの同一KVMホスト上にて、既に動いている LUN0 にゲストのインストールを試みるとどうなるでしょうか?どうあるべきでしょうか?試してみます。

# virsh list --all
Id   Name              State
---------------------------------
4    guest-local-hdd   running
6    guest-iscsi-0     running

# virsh dumpxml guest-iscsi-0 | grep disk | 抜粋
<disk type="block" device="disk"><source dev="/dev/disk/by-path/ip-172.16.1.90:3260-iscsi-iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2-lun-0"></disk>
# virt-install --name hoge --arch x86_64 \
--os-type generic --vcpus 4 --memory 4096 \
--disk vol=iscsipool1/unit:0:0:0 \
--network bridge=br0 --graphics vnc,keymap=ja \
--location /home/iso/CentOS-8.1.1911-x86_64-dvd1.iso \
--initrd-inject /home/iso/CentOS811911-ks.cfg \
--noautoconsole \
--extra-args "ks=file:/CentOS811911-ks.cfg text console=tty0 console=ttyS0,115200n8r"
ERROR    Disk /dev/disk/by-path/ip-172.16.1.90:3260-iscsi-iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2-lun-0 is already in use by other guests ['guest-iscsi-0']. (Use --check path_in_use=off or --check all=off to override)

上記の通り、キチンとはじいてくれました。

それでは”別のKVMホスト”上で、
さっきインストールが成功し既に動いている LUN0 にゲストのインストールを試みるとどうなるでしょうか?どうあるべきでしょうか?試してみます。

# virsh list --all
Id   Name   State
--------------------

# virsh pool-list
Name         State    Autostart
----------------------------------
iscsipool1   active   yes
iso          active   yes
kvm          active   yes
# virt-install --name hoge --arch x86_64 \
--os-type generic --vcpus 4 \
--memory 4096 \
--disk vol=iscsipool1/unit:0:0:0 \ # 故意に同じ場所へ試行します
--network bridge=br0 \
--graphics vnc,keymap=ja \
--location /home/iso/CentOS-8.1.1911-x86_64-dvd1.iso \
--initrd-inject /home/iso/CentOS811911-ks.cfg \
--noautoconsole \
--extra-args "ks=file:/CentOS811911-ks.cfg text console=tty0 console=ttyS0,115200n8r"

Starting install...
Retrieving file .treeinfo...                          | 1.5 kB  00:00
Retrieving file vmlinuz...                            | 7.7 MB  00:00
Retrieving file initrd.img...                         |  59 MB  00:00
ERROR    resource busy: Lockspace resource '36001405b56906a6f1b64077ba05c0f4b' is locked
Domain installation does not appear to have been successful.
If it was, you can restart your domain by running:
virsh --connect qemu:///system start hoge
otherwise, please restart your installation.

上記の通り、少しインストールが進んで”肝心の”ディスク領域の確保の部分できちんとはじいてくれました。

カテゴリー
KVM

KVMでiSCSIストレージを使ってライブなマイグレーションする(3)

iSCSIイニシエータ兼NFSクライアント兼KVMホスト側の構成は以下の通りです。
インストール時にディレクトリが自動的に作成されます。
できるだけそれを流用したいので、
KVMをインストールして、iSCSIイニシエータの構成をして、NFSクライアントの構成をする、という順番で作業しました。
石橋を叩きながら、単純な構成から複雑な(依存関係という意味で)構成へ進めました。

# cat /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.1993-08.org.debian:01:6c1f28cf1fd3

# iscsiadm -m discovery -t sendtargets -p 172.16.1.90
172.16.1.90:3260,1 iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2

# iscsiadm -m node --login
Logging in to [iface: default, target: iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2, portal: 172.16.1.90,3260] (multiple)
Login to [iface: default, target: iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2, portal: 172.16.1.90,3260] successful.

# virsh pool-define-as --name iscsipool1 --type iscsi \
--source-host 172.16.1.90 \
--source-dev iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2 \
--target /dev/disk/by-path

# virsh pool-list --all
Name         State      Autostart
------------------------------------
iscsipool1   inactive   no

# virsh pool-start iscsipool1
Pool iscsipool1 started

root@zfs93:/etc/libvirt# virsh pool-autostart iscsipool1
Pool iscsipool1 marked as autostarted

# virsh pool-list
Name         State    Autostart
----------------------------------
iscsipool1   active   yes

# virsh pool-info iscsipool1
Name:           iscsipool1
UUID:           bddb637a-0a18-46e7-be7a-589b9dca5fd0
State:          running
Persistent:     yes
Autostart:      yes
Capacity:       5.00 TiB
Allocation:     5.00 TiB
Available:      0.00 B

# virsh vol-list iscsipool1
Name         Path
--------------------------------------------------------------------------------------------------------------------------
unit:0:0:0   /dev/disk/by-path/ip-172.16.1.90:3260-iscsi-iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2-lun-0
unit:0:0:1   /dev/disk/by-path/ip-172.16.1.90:3260-iscsi-iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2-lun-1
unit:0:0:2   /dev/disk/by-path/ip-172.16.1.90:3260-iscsi-iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2-lun-2
unit:0:0:3   /dev/disk/by-path/ip-172.16.1.90:3260-iscsi-iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2-lun-3
unit:0:0:4   /dev/disk/by-path/ip-172.16.1.90:3260-iscsi-iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2-lun-4

上記のプールを作った後で、排他制御の仕組みをオンにします。
その後で virtlockd を 止めて、NFSマウントして、start します。
簡単な構成から複雑な構成へとスパイラルに設定しています。

# diff /etc/libvirt/qemu.conf  /etc/libvirt/qemu.conf.org
658c658
< lock_manager = "lockd"
---
> #lock_manager = "lockd"

# diff /etc/libvirt/qemu-lockd.conf /etc/libvirt/qemu-lockd.conf.org
17c17
< require_lease_for_disks = 1
---
> #require_lease_for_disks = 1
39c39
< file_lockspace_dir = "/var/lib/libvirt/lockd/files"
---
> #file_lockspace_dir = "/var/lib/libvirt/lockd/files"
53c53
< lvm_lockspace_dir = "/var/lib/libvirt/lockd/lvmvolumes"
---
> #lvm_lockspace_dir = "/var/lib/libvirt/lockd/lvmvolumes"
67c67
< scsi_lockspace_dir = "/var/lib/libvirt/lockd/scsivolumes"
---
> #scsi_lockspace_dir = "/var/lib/libvirt/lockd/scsivolumes"

# systemctl restart virtlockd

virtlockdを止めて作業します。
単体で手動でマウントできることを確認します。
その後で手動でマウントしています。
元の状態に戻ったことを確認して、
最後に自動マウントを実行しています。
virtlockdを再実行します。

# systemctl stop virtlockd.socket
# mkdir -p /home/libvirt/lockd/scsivolumes
# mount -t nfs \
172.16.1.90:/home/libvirt/lockd/scsivolumes \
/var/lib/libvirt/lockd/scsivolumes
# umount /var/lib/libvirt/lockd/scsivolumes
# cat /etc/fstab | 抜粋
172.16.1.90:/home/libvirt/lockd/scsivolumes /var/lib/libvirt/lockd/scsivolumes nfs defaults,intr,hard 0 0
# mount -a
# mount | grep scsi
172.16.1.90:/home/libvirt/lockd/scsivolumes on /var/lib/libvirt/lockd/scsivolumes type nfs4 (rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=172.16.1.93,local_lock=none,addr=172.16.1.90)
# systemctl restart virtlockd.socket
カテゴリー
KVM

KVMでiSCSIストレージを使ってライブなマイグレーションする(2)

ストレージを提供する iSCSIターゲット兼NFSサーバーの構成は以下の通りです。
このマシンに限って、歴史的事情により CentOS 8.1.1911 で構成しています。
寄せ集めの部品で作ったPCなので古くて、記録密度が低くて申し訳ありません。(笑)
1TBのHDD×6本を寄せて集めてLVMを構成しています。

# pvdisplay
--- Physical volume ---
PV Name               /dev/sda4
VG Name               VG1
PV Size               1.24 TiB / not usable &lt;14.40 MiB
Allocatable           yes
PE Size               128.00 MiB
Total PE              10186
Free PE               2734
Allocated PE          7452
PV UUID               I4Grfv-0O2p-bhxA-gFQG-Lnk3-ugIS-4ogXlk

--- Physical volume ---
PV Name               /dev/sdb4
VG Name               VG1
PV Size               1.24 TiB / not usable &lt;14.40 MiB
Allocatable           yes
PE Size               128.00 MiB
Total PE              10186
Free PE               2734
Allocated PE          7452
PV UUID               dTWmNU-q2mL-yafI-ioGC-7h0g-NcDl-I8DOK6

--- Physical volume ---
PV Name               /dev/sdc1
VG Name               VG1
PV Size               931.51 GiB / not usable 12.71 MiB
Allocatable           yes (but full)
PE Size               128.00 MiB
Total PE              7452
Free PE               0
Allocated PE          7452
PV UUID               h2ze7K-Oz5u-zLTC-ZDw4-vXIa-uR11-zPeHgl

--- Physical volume ---
PV Name               /dev/sdd1
VG Name               VG1
PV Size               931.51 GiB / not usable 12.71 MiB
Allocatable           yes (but full)
PE Size               128.00 MiB
Total PE              7452
Free PE               0
Allocated PE          7452
PV UUID               hkKel9-BRYr-IPrZ-bDJS-Jd1t-xylV-MNlSHP

--- Physical volume ---
PV Name               /dev/sde1
VG Name               VG1
PV Size               931.51 GiB / not usable 12.71 MiB
Allocatable           yes (but full)
PE Size               128.00 MiB
Total PE              7452
Free PE               0
Allocated PE          7452
PV UUID               h8AGD3-MEnB-19CJ-Nfbp-0leD-nxFJ-S7jgGQ

--- Physical volume ---
PV Name               /dev/sdf1
VG Name               VG1
PV Size               931.51 GiB / not usable 12.71 MiB
Allocatable           yes (but full)
PE Size               128.00 MiB
Total PE              7452
Free PE               0
Allocated PE          7452
PV UUID               h24afJ-eN39-5Edk-HiiH-6ih5-FELi-FcIOM4
# vgs
VG  #PV #LV #SN Attr   VSize  VFree
VG1   6   6   0 wz--n- &lt;6.13t 683.50g
[root@zfs-4c keizof]# lvscan
ACTIVE            '/dev/VG1/disk1' [1.00 TiB] inherit
ACTIVE            '/dev/VG1/disk2' [1.00 TiB] inherit
ACTIVE            '/dev/VG1/disk3' [1.00 TiB] inherit
ACTIVE            '/dev/VG1/disk4' [1.00 TiB] inherit
ACTIVE            '/dev/VG1/disk5' [1.00 TiB] inherit
ACTIVE            '/dev/VG1/disk6' [466.50 GiB] inherit

動いているVMがどの領域を使っているのかを管理するためのロックファイルの格納場所は以下の通りです。
ディレクトリを掘って準備して、エクスポートしています。エクスポート先はKVMホストのストレージ専用ネットワーク(172.16.1.0/24)に限定しています。

# ls -ld /home/libvirt/lockd/scsivolumes
drwxr-xr-x 2 root root 88  3月 15 20:21 /home/libvirt/lockd/scsivolumes

# cat /etc/exports
/home/libvirt/lockd 172.16.1.0/24(rw,no_root_squash,no_subtree_check)

iSCSIの構成は以下の通りです。LV単位でLUN番号が割り当てています。
LUNの上限は512くらいらしいです。
/dev/sda,/dev/sdb, /dev/sdc,,,/dev/sdz とアルファベットの最後に達したら
何が起こるのかはわかりませんが。。。
家庭内、かつストレージ専用の独立したネットワークなので、認証無しにしています。

# targetcli
>ls
o- / .............................................................................. [...]
o- backstores ................................................................... [...]
| o- block ....................................................... [Storage Objects: 5]
| | o- disk1 ........................... [/dev/VG1/disk1 (1.0TiB) write-thru activated]
| | | o- alua ........................................................ [ALUA Groups: 1]
| | |   o- default_tg_pt_gp ............................ [ALUA state: Active/optimized]
| | o- disk2 ........................... [/dev/VG1/disk2 (1.0TiB) write-thru activated]
| | | o- alua ........................................................ [ALUA Groups: 1]
| | |   o- default_tg_pt_gp ............................ [ALUA state: Active/optimized]
| | o- disk3 ........................... [/dev/VG1/disk3 (1.0TiB) write-thru activated]
| | | o- alua ........................................................ [ALUA Groups: 1]
| | |   o- default_tg_pt_gp ............................ [ALUA state: Active/optimized]
| | o- disk4 ........................... [/dev/VG1/disk4 (1.0TiB) write-thru activated]
| | | o- alua ........................................................ [ALUA Groups: 1]
| | |   o- default_tg_pt_gp ............................ [ALUA state: Active/optimized]
| | o- disk5 ........................... [/dev/VG1/disk5 (1.0TiB) write-thru activated]
| |   o- alua ........................................................ [ALUA Groups: 1]
| |     o- default_tg_pt_gp ............................ [ALUA state: Active/optimized]
| o- fileio ...................................................... [Storage Objects: 0]
| o- pscsi ....................................................... [Storage Objects: 0]
| o- ramdisk ..................................................... [Storage Objects: 0]
o- iscsi ................................................................. [Targets: 1]
| o- iqn.2003-01.org.linux-iscsi.zfs-4c.x8664:sn.5d395c3181b2 ............... [TPGs: 1]
|   o- tpg1 .................................................... [no-gen-acls, no-auth]
|     o- acls ............................................................... [ACLs: 2]
|     | o- iqn.1993-08.org.debian:01:6c1f28cf1fd3 .................... [Mapped LUNs: 5]
|     | | o- mapped_lun0 ...................................... [lun0 block/disk1 (rw)]
|     | | o- mapped_lun1 ...................................... [lun1 block/disk2 (rw)]
|     | | o- mapped_lun2 ...................................... [lun2 block/disk3 (rw)]
|     | | o- mapped_lun3 ...................................... [lun3 block/disk4 (rw)]
|     | | o- mapped_lun4 ...................................... [lun4 block/disk5 (rw)]
|     | o- iqn.1993-08.org.debian:01:7e1c78ef6a2d .................... [Mapped LUNs: 5]
|     |   o- mapped_lun0 ...................................... [lun0 block/disk1 (rw)]
|     |   o- mapped_lun1 ...................................... [lun1 block/disk2 (rw)]
|     |   o- mapped_lun2 ...................................... [lun2 block/disk3 (rw)]
|     |   o- mapped_lun3 ...................................... [lun3 block/disk4 (rw)]
|     |   o- mapped_lun4 ...................................... [lun4 block/disk5 (rw)]
|     o- luns ............................................................... [LUNs: 5]
|     | o- lun0 ..................... [block/disk1 (/dev/VG1/disk1) (default_tg_pt_gp)]
|     | o- lun1 ..................... [block/disk2 (/dev/VG1/disk2) (default_tg_pt_gp)]
|     | o- lun2 ..................... [block/disk3 (/dev/VG1/disk3) (default_tg_pt_gp)]
|     | o- lun3 ..................... [block/disk4 (/dev/VG1/disk4) (default_tg_pt_gp)]
|     | o- lun4 ..................... [block/disk5 (/dev/VG1/disk5) (default_tg_pt_gp)]
|     o- portals ......................................................... [Portals: 1]
|       o- 172.16.1.90:3260 ...................................................... [OK]
o- loopback .............................................................. [Targets: 0]

カテゴリー
KVM

KVMでiSCSIストレージを使ってライブなマイグレーションする(1)

KVMでライブな(ゲストOSを稼働させたまま)マイグレーションする、という記事はネット上に沢山溢れていました。同じく、KVMでiSCSIストレージを使うという記事も沢山ありました。しかし、ゲストOSの多重起動防止策について具体的に記載してある記事はほとんどありませんでした。
さらっと、「説明を簡単にするためにNFSを使います」とか「NFSでは大規模なシステムには向きません」と書いてあったりします。というわけで試してみることにしました。
iSCSIの部分については後で詳しく書き出すことにして、肝心なあの部分に限って記録に残しておきます。

iSCSIを使って、ストレージをIPネットワークを経由して、複数のKVMホストから共有することができます。その結果、ライブなマイグレーション(動かすのはRAM領域だけ)を実現できます。
がしかし、、、担当領域が違う、レイヤーが違う、歴史的な理由などにより、iSCSIでは「ファイルの排他制御」の仕組みがありません。LUN(Logical Unit Number)単位で占有(他を締め出す)が出来る程度です。結果的に、iSCSIストレージ上のゲストOSを別々のKVMホストから「誤って多重起動」することができます。ファイルシステムがぐちゃぐちゃになって壊れます。あるいは他のKVMホスト上で動いているゲストOSの領域に「誤って上書きインストール」できます。これは自己責任かもしれませんが、簡単に壊れてしまうのです。

NFSを使って共有ストレージを使えばそのようなことは起きません。それは「ファイルの排他制御」の仕組みがNFSでもそれなりに動くからです。でも肝心の性能がいまいちらしいのです。
なお、UNIX系OSでは「アドバイザリーロック」方式です。排他制御の仕組みを利用するかどうかは、プログラマの責任です。ロックを使用するかしないかは、プログラマの自由です。一方で Windows系OSでは「強制ロック」方式です。プログラマに選択の自由はありません。

KVMホスト側×2台は、以下の環境で試しています。

# uname -a
Linux newsol 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64 GNU/Linux

# cat /etc/issue
Debian GNU/Linux 10 \n \l

# dpkg -l | 抜粋
ii  qemu-kvm                             1:3.1+dfsg-8+deb10u4            amd64        QEMU Full virtualization on x86 hardware
ii  libvirt-clients                      5.0.0-4+deb10u1                 amd64        Programs for the libvirt library
ii  libvirt-daemon                       5.0.0-4+deb10u1                 amd64        Virtualization daemon
ii  libvirt-daemon-system                5.0.0-4+deb10u1                 amd64        Libvirt daemon configuration files
ii  libvirt-glib-1.0-0:amd64             1.0.0-1                         amd64        libvirt GLib and GObject mapping library
ii  libvirt0:amd64                       5.0.0-4+deb10u1                 amd64        library for interfacing with different virtualization systems
ii  python3-libvirt                      5.0.0-1                         amd64        libvirt Python 3 bindings

ヒントはここにあります。

# cat /etc/libvirt/qemu.conf | 抜粋

# In order to prevent accidentally starting two domains that
# share one writable disk, libvirt offers two approaches for
# locking files. The first one is sanlock, the other one,
# virtlockd, is then our own implementation. Accepted values
# are "sanlock" and "lockd".
#
# lock_manager = "lockd" # デフォルトではlockdがコメント化してある

排他制御を実現する方法(実装)として”sanlock”と”virtlockd”の二つが用意されているようです。ここでどちらかを使用する、という設定をしなければ安全装置はオンになりません。さらに、各方法の構成ファイルが独立して用意されています。

virtlockd用の構成ファイルの抜粋は以下の通りです。

# cat /etc/libvirt/qemu-lockd.conf | 抜粋

# Flag to determine whether we allow starting of guests
# which do not have any <lease> elements defined in their
# configuration.
#
# If 'auto_disk_leases' is disabled, this setting defaults
# to enabled, otherwise it defaults to disabled.
#
# require_lease_for_disks = 1</lease>

# When using SCSI volumes that can be visible across
# multiple, it is desirable to do locking based on
# the unique UUID associated with each volume, instead
# of their paths. Setting this path causes libvirt to
# do UUID based locking for SCSI.
#
# Typically this directory would be located on a shared
# filesystem visible to all hosts accessing the same
# storage.
#
#scsi_lockspace_dir = "/var/lib/libvirt/lockd/scsivolumes"

sanlock用の構成ファイルの抜粋は以下の通りです。

# cat qemu-sanlock.conf | 抜粋

# Recommendation is to just mount this default location as
# an NFS volume. Uncomment this, if you would prefer the mount
# point to be somewhere else. Moreover, please make sure
# sanlock daemon can access the specified path.
#
#disk_lease_dir = "/var/lib/libvirt/sanlock"
# The unique ID for this host.
#
# IMPORTANT: *EVERY* host which can access the filesystem mounted
# at 'disk_lease_dir' *MUST* be given a different host ID.
#
# This parameter has no default and must be manually set if
# 'auto_disk_leases' is enabled
#host_id = 1

というわけで、用意されています。後はそれらを動かしてあげればいいんです。
もっとも「使用中」を意味する「ロックファイル」をなんらかの方法でKVMホスト間で共有しなければならない、という問題が残ったままです。
それは主としてiSCSIを使ったとしても、副として「アドバイザリーロックが使えるNFS」と併用するのが推奨のようです。この部分が SFOP(単一故障点:single point of failure)になるのはいかがものか、ということについては別途検討するとします。

カテゴリー
KVM

KVM始めました(3)

シリアルコンソールだけを使う CentOS編

CentOSにおいても同様でした。

# virt-install --name centcd --arch x86_64 --os-type generic \
--vcpus 4 --memory 4096 \
--disk /dev/guest_images_lvm-1/lv20 \
--network type=direct,source=enp10s0 \
--graphics vnc,keymap=ja \
--location /iso/CentOS-8.1.1911-x86_64-dvd1.iso \
--noautoconsole --extra-args "text console=ttyS0,115200n"

上記のオプションでインストールを開始すると、想像を絶する質問責めに合いますがなんとか最後まで進むことができました。
インストール中もインストール後、再起動後もコンソールに接続できます。
インストール時のオプションも下記のようにしかるべきファイルに記載されていました。

# cat /etc/default/grub | 抜粋
GRUB_TERMINAL="serial console"
GRUB_SERIAL_COMMAND="serial --speed=115200"
GRUB_CMDLINE_LINUX="crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap console=ttyS0,115200n"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true