目次
- 目次
- 概要
- 経緯
- 環境
- 手順
- おまけ
- 参考サイト
概要
QEMU+KVM環境のゲストマシンのストレージを、イメージファイル(.img)からiSCSIディスクに移行する。移行といってもddで複製するだけだが、その前後の作業が煩雑だったため記録した。
移行なので既存のゲストマシンが作業対象となる。新規ゲストマシンをiSCSIディスクにインストールする方法は前回記事を参照。
none06.hatenadiary.org
経緯
- KVMホストのローカルディスクの容量が逼迫してきた。恒久対処としてゲストマシンのイメージファイルをKVMホストの外で管理することにした。
- データの管理場所はNASとした。
- 接続インターフェース(プロトコル)はiSCSIとした。
環境
概念図
構成
ホスト名 | 管理NWのIP | ストレージNWのIP | OS | H/W | 備考 |
---|---|---|---|---|---|
file01 | 172.16.0.5 | 172.16.1.5 | RAIDiator 4.2.31 | NETGEAR ReadyNAS Pro 2 | iSCSIターゲット |
kvm01 | 172.16.0.205 | 172.16.1.205 | CentOS 8.4.2105 | HP DL360 G7 | KVMホスト |
guest01 | 172.16.0.253 | - | CentOS 8.4.2105 | - | KVMゲスト |
前提
- iSCSIターゲットの作成手順は各自確認のこと。
- ゲストマシンを作成済みとする。ディスクイメージはファイル(.img)とする。
手順
1.iSCSIターゲット/LUNの作成
1-1.移行元ディスク容量の確認
手順の汎用化のため、ゲストマシンのホスト名を変数_NODE
に格納しておく。
[root@kvm01 ~]# _NODE=guest01 [root@kvm01 ~]# echo $_NODE guest01
移行元ディスクの容量を確認する。
[root@kvm01 ~]# qemu-img info /var/lib/libvirt/images/${_NODE}.img image: /var/tmp/images/guest01.img file format: qcow2 virtual size: 20 GiB (21474836480 bytes) disk size: 2.15 GiB cluster_size: 65536 Format specific information: compat: 1.1 lazy refcounts: false refcount bits: 16 corrupt: false
1-2.iSCSIターゲット/LUNの作成
iSCSIターゲット/LUNを作成する。手順は各自の環境に依存。 |ターゲット名|LUN番号|ディスク容量| |:--|:--|:--| |iqn.2020-09.file01:guest01|0|20GB|
ディスク容量について。移行元ディスクと比較して
- 同一:無駄もなく作業もわかりやすい
- 大きい:ディスク複製は可能だが作業後に必要に応じて拡張が必要(当記事のスコープ外)
- 小さい:当記事の手順では移行不可(※)
※パーティション作成、バックアップ(xfsdump)、リストア(xfsrestore)、grub更新、fstab更新、などを行なえば可能。
2.事前作業
2-1.ゲストマシンの定義ファイルのバックアップ
ゲストマシンの定義ファイルをバックアップする。
[root@kvm01 ~]# ls -l /etc/libvirt/qemu/${_NODE}.xml* -rw------- 1 root root 4316 10月 8 20:25 /etc/libvirt/qemu/guest01.xml
[root@kvm01 ~]# cp -p /etc/libvirt/qemu/${_NODE}.xml{,_$(date +%Y%m%d)}
[root@kvm01 ~]# ls -l /etc/libvirt/qemu/${_NODE}.xml* -rw------- 1 root root 4316 10月 8 20:25 /etc/libvirt/qemu/guest01.xml -rw------- 1 root root 4316 10月 8 20:25 /etc/libvirt/qemu/guest01.xml_20211009
3.移行元ディスクの接続
3-1.nbdモジュールの読み込み
nbdモジュールを読み込む。
[root@kvm01 ~]# modprobe nbd
[root@kvm01 ~]# lsmod | grep nbd nbd 49152 0
nbdデバイスが作成されていることを確認する。
[root@kvm01 ~]# ls -l /dev/nbd* brw-rw---- 1 root disk 43, 0 10月 9 13:26 /dev/nbd0 brw-rw---- 1 root disk 43, 32 10月 9 13:18 /dev/nbd1 brw-rw---- 1 root disk 43, 320 10月 9 13:18 /dev/nbd10 brw-rw---- 1 root disk 43, 352 10月 9 13:18 /dev/nbd11 brw-rw---- 1 root disk 43, 384 10月 9 13:18 /dev/nbd12 brw-rw---- 1 root disk 43, 416 10月 9 13:18 /dev/nbd13 brw-rw---- 1 root disk 43, 448 10月 9 13:18 /dev/nbd14 brw-rw---- 1 root disk 43, 480 10月 9 13:18 /dev/nbd15 brw-rw---- 1 root disk 43, 64 10月 9 13:18 /dev/nbd2 brw-rw---- 1 root disk 43, 96 10月 9 13:18 /dev/nbd3 brw-rw---- 1 root disk 43, 128 10月 9 13:18 /dev/nbd4 brw-rw---- 1 root disk 43, 160 10月 9 13:18 /dev/nbd5 brw-rw---- 1 root disk 43, 192 10月 9 13:18 /dev/nbd6 brw-rw---- 1 root disk 43, 224 10月 9 13:18 /dev/nbd7 brw-rw---- 1 root disk 43, 256 10月 9 13:18 /dev/nbd8 brw-rw---- 1 root disk 43, 288 10月 9 13:18 /dev/nbd9
3-2.nbdデバイスへの接続
ディスクイメージをnbdデバイスに接続する。
[root@kvm01 ~]# blkid | grep nbd0
[root@kvm01 ~]# qemu-nbd --connect=/dev/nbd0 /var/lib/libvirt/images/${_NODE}.img
[root@kvm01 ~]# blkid | grep nbd0 /dev/nbd0: PTUUID="417f0ae5" PTTYPE="dos" /dev/nbd0p1: UUID="41619de3-6f19-40cf-b088-27e34d842a53" BLOCK_SIZE="1024" TYPE="ext4" PARTUUID="417f0ae5-01" /dev/nbd0p2: UUID="64849620-bd0d-48ad-93e3-a2861530fc2e" TYPE="swap" PARTUUID="417f0ae5-02" /dev/nbd0p3: UUID="2a90a8c7-1221-435d-8a8b-b9e660a70c67" BLOCK_SIZE="512" TYPE="xfs" PARTUUID="417f0ae5-03"
パーティションが見えた。すごい。
4.移行先ディスクの接続
4-1.iSCSIプールの定義
iSCSIプールを定義する。
[root@kvm01 ~]# virsh pool-list --all 名前 状態 自動起動 -----------------------------------
[root@kvm01 ~]# virsh pool-define-as --name ${_NODE} --type iscsi --source-host 172.16.1.5 --source-dev iqn.2020-09.file01:${_NODE} --target /dev/disk/by-path/ プール guest01 が定義されました
[root@kvm01 ~]# virsh pool-list --all 名前 状態 自動起動 ------------------------------------ guest01 停止状態 いいえ (no)
4-2.iSCSIプールの起動
iSCSIプールを起動する。裏でiSCSIターゲットへのログインが行われるので前後で状態を確認しておく。
[root@kvm01 ~]# iscsiadm --mode node iscsiadm: No records found
[root@kvm01 ~]# iscsiadm --mode session iscsiadm: No active sessions.
[root@kvm01 ~]# virsh pool-start ${_NODE} プール guest01 が起動されました
[root@kvm01 ~]# virsh pool-autostart ${_NODE} プール guest01 が自動起動としてマークされました
[root@kvm01 ~]# virsh pool-list --all 名前 状態 自動起動 ----------------------------------- guest01 動作中 はい (yes)
[root@kvm01 ~]# iscsiadm --mode node 172.16.1.5:3260,1 iqn.2020-09.file01:guest01
[root@kvm01 ~]# iscsiadm --mode session tcp: [78] 172.16.1.5:3260,1 iqn.2020-09.file01:guest01 (non-flash)
4-3.ディスクの認識確認
ディスクを認識できていることを確認する。
[root@kvm01 ~]# ls -l /dev/disk/by-path | grep ${_NODE} lrwxrwxrwx 1 root root 9 10月 9 17:22 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0 -> ../../sdb lrwxrwxrwx 1 root root 10 10月 9 17:22 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0-part1 -> ../../sdb1 lrwxrwxrwx 1 root root 10 10月 9 17:22 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0-part2 -> ../../sdb2 lrwxrwxrwx 1 root root 10 10月 9 17:22 ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0-part3 -> ../../sdb3
上記よりデバイス名は/dev/sdb
だと特定できる。手順の汎用化のため変数_TARGET_DEV
に格納しておく。
[root@kvm01 ~]# _TARGET_DEV=$(ls -l /dev/disk/by-path/ip-172.16.1.5\:3260-iscsi-iqn.2020-09.file01\:${_NODE}-lun-0 | sed 's#.*../../#/dev/#')
[root@kvm01 ~]# echo $_TARGET_DEV /dev/sdb
[root@kvm01 ~]# fdisk -l ${_TARGET_DEV} ディスク /dev/sdb: 20 GiB, 21474837504 バイト, 41943042 セクタ 単位: セクタ (1 * 512 = 512 バイト) セクタサイズ (論理 / 物理): 512 バイト / 512 バイト I/O サイズ (最小 / 推奨): 512 バイト / 524288 バイト
[root@kvm01 ~]# blkid | grep ${_TARGET_DEV}
※blkidではまだ見えない。
5.ディスクの移行
5-1.ディスクの複製
ディスクを複製する。原始的なddを使う。
[root@kvm01 ~]# dd if=/dev/nbd0 of=${_TARGET_DEV} bs=1024 status=progress 2429779968 bytes (2.4 GB, 2.3 GiB) copied, 6 s, 405 MB/s --- snip --- 21439167488 bytes (21 GB, 20 GiB) copied, 242 s, 88.6 MB/s 20971520+0 レコード入力 20971520+0 レコード出力 21474836480 bytes (21 GB, 20 GiB) copied, 297.242 s, 72.2 MB/s
[root@kvm01 ~]# blkid | grep ${_TARGET_DEV} /dev/sdb1: UUID="81e8e85e-f169-443b-a525-2294f0c3e1ed" BLOCK_SIZE="512" TYPE="xfs" PARTUUID="000a8874-01" /dev/sdb2: UUID="ee5a595f-3bf7-48bd-9ba4-b02468b60eab" TYPE="swap" PARTUUID="000a8874-02" /dev/sdb3: UUID="828fc91e-fa92-4dfc-944c-c4c70ec43cb7" BLOCK_SIZE="512" TYPE="xfs" PARTUUID="000a8874-03"
5-2.nbdデバイスからの切断
移行元ディスクをnbdデバイスから切断する。
[root@kvm01 ~]# qemu-nbd --disconnect /dev/nbd0 /dev/nbd0 disconnected
[root@kvm01 ~]# blkid | grep nbd0
6.ゲストマシンの定義変更
6-1.ゲストマシンからの移行元ディスクの切断
ゲストマシンから移行元ディスクを切断する。
[root@kvm01 ~]# virsh dumpxml guest01 --- snip --- <devices> <emulator>/usr/libexec/qemu-kvm</emulator> <disk type='file' device='disk'> <driver name='qemu' type='raw'/> <source file='/var/tmp/images/guest01.img'/> <target dev='vda' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> </disk> --- snip ---
デバイス名は上記よりvda
だと特定できる。手順の汎用化のために変数_GUEST_DEV
に格納する。
[root@kvm01 ~]# _GUEST_DEV=$(virsh dumpxml ${_NODE} | grep .img -2 | grep "target dev" | sed "s/.*dev='\(.*\)' bus.*/\1/g")
[root@kvm01 ~]# echo $_GUEST_DEV vda
[root@kvm01 ~]# virsh detach-disk ${_NODE} --target ${_GUEST_DEV} --config ディスクが正常に切断されました
6-2.ゲストマシンへの移行先ディスクの接続
ゲストマシンへ移行先ディスクを接続する。
[root@kvm01 ~]# virsh attach-disk --domain ${_NODE} --source /dev/disk/by-path/ip-172.16.1.5\:3260-iscsi-iqn.2020-09.file01\:${_NODE}-lun-0 --target vda --io native --cache none --config ディスクが正常に接続されました
6-3.定義ファイルの差分確認
定義ファイルの差分箇所がディスク関連のみであることを確認する。
[root@kvm01 ~]# diff /etc/libvirt/qemu/${_NODE}.xml{,_$(date +%Y%m%d)} 27c27,29 < <cpu mode='host-model' check='partial'/> --- > <cpu mode='host-model' check='partial'> > <model fallback='allow'/> > </cpu> 42,44c44,46 < <disk type='block' device='disk'> < <driver name='qemu' type='raw' cache='none' io='native'/> < <source dev='/dev/disk/by-path/ip-172.16.1.5:3260-iscsi-iqn.2020-09.file01:guest01-lun-0'/> --- > <disk type='file' device='disk'> > <driver name='qemu' type='qcow2'/> > <source file='/var/lib/libvirt/images/guest01.img'/>
※cpuのmodelの差分は不明だが無影響。
6-4.ゲストマシンの起動
ゲストマシンを起動する。
[root@kvm01 ~]# virsh list Id 名前 状態 -------------------
[root@kvm01 ~]# virsh start ${_NODE} ドメイン guest01 が起動されました
[root@kvm01 ~]# virsh list Id 名前 状態 ------------------------ 1 guest01 実行中
6-5.ゲストマシンの正常性確認
ログインするなどしてOSが正常に起動していることを確認する。
おまけ
当記事の手順をスクリプト化したものを貼っておく。
#!/bin/sh # # img2iscsi.sh # # Usage: img2iscsi.sh <_NODE> # # 引数チェック if [ "$1" = "" ]; then echo "Usage: $0 <_NODE>" exit 1 fi _NODE=$1 # 1.iSCSIターゲット/LUNの作成 # 完了している前提とする # 2.事前作業 ls -l /etc/libvirt/qemu/${_NODE}.xml* if [ ! -f /etc/libvirt/qemu/${_NODE}.xml_$(date +%Y%m%d) ]; then cp -p /etc/libvirt/qemu/${_NODE}.xml{,_$(date +%Y%m%d)} ls -l /etc/libvirt/qemu/${_NODE}.xml* fi # 3.移行元ディスクの接続 lsmod | grep nbd; if [ $? -ne 0 ]; then modprobe nbd; lsmod | grep nbd; fi ls -l /dev/nbd0 blkid qemu-nbd --connect=/dev/nbd0 /var/tmp/images/${_NODE}.img blkid # 4.移行先ディスクの接続 virsh pool-list --all virsh pool-define-as --name ${_NODE} --type iscsi --source-host 172.16.1.5 --source-dev iqn.2020-09.file01:${_NODE} --target /dev/disk/by-path/ virsh pool-start ${_NODE} virsh pool-autostart ${_NODE} virsh pool-list --all _TARGET_DEV=$(ls -l /dev/disk/by-path/ip-172.16.1.5\:3260-iscsi-iqn.2020-09.file01\:${_NODE}-lun-0 | sed 's#.*../../#/dev/#') echo "_TARGET_DEV: $_TARGET_DEV" # 5.ディスクの移行 tune2fs -l /dev/nbd0p1 | grep "Block size" xfs_info /dev/nbd0p3 dd if=/dev/nbd0 of=${_TARGET_DEV} bs=1024 status=progress blkid tune2fs -l ${_TARGET_DEV}1 | grep "Block size" xfs_info ${_TARGET_DEV}3 qemu-nbd --disconnect /dev/nbd0 blkid # 6.ゲストマシンの定義変更 _GUEST_DEV=$(virsh dumpxml ${_NODE} | grep .img -2 | grep "target dev" | sed "s/.*dev='\(.*\)' bus.*/\1/g") virsh detach-disk ${_NODE} --target ${_GUEST_DEV} --config virsh attach-disk --domain ${_NODE} --source /dev/disk/by-path/ip-172.16.1.5\:3260-iscsi-iqn.2020-09.file01\:${_NODE}-lun-0 --target vda --io native --cache none --config diff /etc/libvirt/qemu/${_NODE}.xml{,_$(date +%Y%m%d)} virsh list virsh start ${_NODE} virsh list #EOF