🦇

KVM ライブマイグレーションの練習

2023/02/23に公開

マイグレーション元の環境

Debian10 で、マイグレーション元の環境を構築します。

$ uname -a
Linux debian10 4.19.0-23-amd64 #1 SMP Debian 4.19.269-1 (2022-12-20) x86_64 GNU/Linux

$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

マイグレーションの準備として、マイグレーション先ホスト名に対して、IPアドレスをひけるようにしておきます。

# vi /etc/hosts
# grep 10.2.0.242 /etc/hosts
10.2.0.242      web1

仮想ブリッジは Open vSwitch を使用します。

# apt install --no-install-recommends openvswitch-switch

# ovs-vsctl show
bb2b01e3-13a1-424e-a32f-453f7aa743bc
    ovs_version: "2.10.7"

利用する仮想ブリッジ ovsbr0 を作成します。
下記の内容で /etc/network/interfaces を作成します。

/etc/network/interfaces
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
auto ovsbr0
allow-ovs ovsbr0
iface ovsbr0 inet static
        ovs_type OVSBridge
        ovs_ports ens3
        address 10.2.0.241/24
        gateway 10.2.0.1
        dns-nameservers 192.168.11.249
allow-ovsbr0 ens3
iface ens3 inet manual
        ovs_bridge ovsbr0
        ovs_type OVSPort

networking をリスタートし、結果を確認します。

# systemctl restart networking

# ip a show ovsbr0
5: ovsbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 22:c3:30:e6:23:4d brd ff:ff:ff:ff:ff:ff
    inet 10.2.0.241/24 brd 10.2.0.255 scope global ovsbr0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c3:30ff:fee6:234d/64 scope link
       valid_lft forever preferred_lft forever

KVM、Libvirt に関連するパッケージをインストールします。

# apt install --no-install-recommends qemu-kvm qemu-utils libvirt-clients libvirt-daemon-system virtinst dnsmasq

仮想ブリッジ ovsbr0 を使用する仮想ネットワークを作成します。
以下の内容で ovs.xml ファイルを作成します。

ovs.xml
<network>
  <name>ovs</name>
  <forward mode='bridge'/>
  <bridge name='ovsbr0'/>
  <virtualport type='openvswitch'/>
  <portgroup name='untag' default='yes'/>
  <portgroup name='vlan10'>
    <vlan>
      <tag id='10'/>
    </vlan>
  </portgroup>
</network>

仮想ネットワークを作成、起動して、結果を確認します。

# virsh net-define ovs.xml
Network ovs defined from ovs.xml


# virsh net-start ovs
Network ovs started


# virsh net-list --all
 Name      State      Autostart   Persistent
----------------------------------------------
 default   inactive   no          yes
 ovs       active     no          yes

ボリュームを格納するストレージプール nfs を作成、起動して、結果を確認します。

# virsh pool-define-as nfs dir --target /var/lib/libvirt/images/nfs
Pool nfs defined

# mkdir /var/lib/libvirt/images/nfs

# virsh pool-start nfs
Pool nfs started

# virsh pool-list --all
 Name   State    Autostart
----------------------------
 nfs    active   no

仮想マシンを起動します。

# virt-install --virt-type kvm --name rockylinux-old --cdrom /var/lib/libvirt/images/nfs/Rocky-9.1-x86_64-minimal.iso --os-variant rhel8-unknown --disk pool=nfs,size=10 --network network=ovs --memory 1024 --graphics vnc,listen=0.0.0.0,port=5900
WARNING  Unable to connect to graphical console: virt-viewer not installed. Please install the 'virt-viewer' package.
WARNING  No console to launch for the guest, defaulting to --wait -1

Starting install...
Allocating 'rockylinux-old.qcow2'                                                                                                                                                                                     |  10 GB  00:00:01
Domain installation still in progress. Waiting for installation to complete.

仮想マシンを起動した結果を確認します。
tap デバイスが作成されて、所定のブリッジに割り当てられます。

# ovs-vsctl show
bb2b01e3-13a1-424e-a32f-453f7aa743bc
    Bridge "ovsbr0"
        Port "vnet0"
            Interface "vnet0"
        Port "ens3"
            Interface "ens3"
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
    ovs_version: "2.10.7"

# ip link show vnet0
7: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master ovs-system state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether fe:54:00:a2:df:75 brd ff:ff:ff:ff:ff:ff

所定のストレージプールにボリュームが作成されます。

# virsh vol-list nfs
 Name                           Path
------------------------------------------------------------------------------------------
 Rocky-9.1-x86_64-minimal.iso   /var/lib/libvirt/images/nfs/Rocky-9.1-x86_64-minimal.iso
 rockylinux-old.qcow2           /var/lib/libvirt/images/nfs/rockylinux-old.qcow2

マイグレーション先の環境

マイグレーション先となる環境は https://zenn.dev/mnod/articles/cade2dfb9dbd4d で作成した環境を元とします。
マイグレーション先で、ユーザを libvirt グループに追加します。

# adduser user libvirt
Adding user `user' to group `libvirt' ...
Adding user user to group libvirt
Done.

# id user
uid=1000(user) gid=1000(user) groups=1000(user),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),116(libvirt)

また、必要となる ncat パッケージをインストールします。

# apt install --no-install-recommends ncat

上記設定したら、マイグレーション元から下記のように、virsh コマンドで接続できることを確認します。

# virsh --connect qemu+ssh://user@10.2.0.242/system
user@10.2.0.242's password:
Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit


virsh # uri
qemu+ssh://user@10.2.0.242/system


virsh # list
 Id   Name         State
----------------------------
 2    rockylinux   running

共有ディスクを利用するマイグレーション

https://www.belbel.or.jp/opensuse-manuals_ja/cha-libvirt-managing.html

ここでは、簡単にマイグレーションのテストを実施することを目指し、本当の意味で共有ディスクを利用するのではなく、
マイグレーション元のディレクトリを nfs エクスポートして、マイグレーション先サーバで nfs マウントすることにします。

マイグレーション元の設定

マイグレーション元サーバで nfs サーバの設定をします。
ストレージプール nfs のディレクトリをエクスポートします。

# apt install --no-install-recommends nfs-kernel-server
# grep -v ^# /etc/exports
/var/lib/libvirt/images/nfs 10.2.0.0/24(rw,sync,no_root_squash)

# systemctl restart nfs-server

マイグレーション先の設定

マイグレーション先サーバで nfs クライアントの設定をします。
nfs エクスポートされたディレクトリをマウントします。

# apt install --no-install-recommends nfs-common
# mkdir /var/lib/libvirt/images/nfs
# mount 10.2.0.241:/var/lib/libvirt/images/nfs /var/lib/libvirt/images/nfs

マウントしたら、書き込みできることを確認します。

# touch /var/lib/libvirt/images/nfs/test

# ls -l /var/lib/libvirt/images/nfs/test
-rw-r--r-- 1 root root 0 Feb 14 17:48 /var/lib/libvirt/images/nfs/test

# rm /var/lib/libvirt/images/nfs/test

# ls -l /var/lib/libvirt/images/nfs
total 2967028
-rw-rw-r-- 1 root         root          1592590336 Feb  8 18:04 Rocky-9.1-x86_64-minimal.iso
-rw------- 1 libvirt-qemu libvirt-qemu 10739318784 Feb 14 16:48 rockylinux-old.qcow2

マイグレーション元と同じように、nfs マウントしたディレクトリを利用する nfs ストレージプールを作成します。

# virsh pool-list --all
 Name      State    Autostart
-------------------------------
 default   active   yes
 user      active   yes


# virsh pool-define-as nfs dir --target /var/lib/libvirt/images/nfs
Pool nfs defined


# virsh pool-list --all
 Name      State      Autostart
---------------------------------
 default   active     yes
 nfs       inactive   no
 user      active     yes


# virsh pool-start nfs
Pool nfs started


# virsh pool-list --all
 Name      State    Autostart
-------------------------------
 default   active   yes
 nfs       active   no
 user      active   yes


# virsh vol-list nfs
 Name                           Path
------------------------------------------------------------------------------------------
 Rocky-9.1-x86_64-minimal.iso   /var/lib/libvirt/images/nfs/Rocky-9.1-x86_64-minimal.iso
 rockylinux-old.qcow2           /var/lib/libvirt/images/nfs/rockylinux-old.qcow2

ライブマイグレーションを開始

マイグレーション元で、ライブマイグレーションを開始します。

# virsh list
 Id   Name             State
--------------------------------
 3    rockylinux-old   running

# virsh -c qemu+ssh://user@10.2.0.242/system list
user@10.2.0.242's password:
 Id   Name         State
----------------------------
 2    rockylinux   running

# virsh migrate --live rockylinux-old --verbose qemu+ssh://user@10.2.0.242/system --persistent --undefinesource
user@10.2.0.242's password:
error: Unsafe migration: Migration without shared storage is unsafe

# virsh migrate --live rockylinux-old --verbose qemu+ssh://user@10.2.0.242/system --persistent --undefinesource --unsafe
user@10.2.0.242's password:
Migration: [100 %]

マイグレーション完了後、状態を確認します。

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


# virsh -c qemu+ssh://user@10.2.0.242/system list --all
user@10.2.0.242's password:
 Id   Name             State
--------------------------------
 2    rockylinux       running
 7    rockylinux-old   running


# virsh -c qemu+ssh://user@10.2.0.242/system dominfo rockylinux-old
user@10.2.0.242's password:
Id:             7
Name:           rockylinux-old
UUID:           20255981-157b-4408-a60c-5bfb206e1b43
OS Type:        hvm
State:          running
CPU(s):         1
CPU time:       3.0s
Max memory:     1048576 KiB
Used memory:    1048576 KiB
Persistent:     yes
Autostart:      disable
Managed save:   no
Security model: apparmor
Security DOI:   0
Security label: libvirt-20255981-157b-4408-a60c-5bfb206e1b43 (enforcing)

ディスクコピーによるマイグレーション

ディスクコピー方式では、ストレージプールの共有は不要ですが、マイグレーション先であらかじめ空のボリュームを作成しておく必要があります。

# virsh vol-create-as nfs rockylinux-old.qcow2 10GB --format qcow2 --allocation 0
Vol rockylinux-old.qcow2 created

# ls -l /var/lib/libvirt/images/nfs
total 196
-rw------- 1 root root 196760 Feb 15 14:57 rockylinux-old.qcow2

# virsh vol-list nfs
 Name                           Path
------------------------------------------------------------------------------------------
 Rocky-9.1-x86_64-minimal.iso   /var/lib/libvirt/images/nfs/Rocky-9.1-x86_64-minimal.iso
 rockylinux-old.qcow2           /var/lib/libvirt/images/nfs/rockylinux-old.qcow2

下記でマイグレーションを開始します。ディスク容量に応じて、それなりの時間がかかります。

# virsh migrate --live --copy-storage-all --persistent --verbose rockylinux-old qemu+ssh://user@10.2.0.242/system

異なるストレージプールへのディスクコピー

マイグレーション元と先とで異なるストレージプールを利用する場合、
マイグレーション元で、利用するストレージプールを指定した xml ファイル作成します。

# virsh dumpxml rockylinux-old > rockylinux-old.xml
# vi rockylinux-old.xml
# virsh dumpxml rockylinux-old | diff -u - rockylinux-old.xml
--- -   2023-02-15 15:46:27.282975938 -0500
+++ rockylinux-old.xml  2023-02-15 15:46:13.380385048 -0500
@@ -50,7 +50,7 @@
     <emulator>/usr/bin/qemu-system-x86_64</emulator>
     <disk type='file' device='disk'>
       <driver name='qemu' type='qcow2'/>
-      <source file='/var/lib/libvirt/images/nfs/rockylinux-old.qcow2'/>
+      <source file='/var/lib/libvirt/images/rockylinux-old.qcow2'/>
       <backingStore/>
       <target dev='hda' bus='ide'/>
       <alias name='ide0-0-0'/>

マイグレーション先であらかじめボリュームの作成します。

# virsh vol-create-as default rockylinux-old.qcow2 10GB --format qcow2 --allocation 0
Vol rockylinux-old.qcow2 created

# ls -l /var/lib/libvirt/images/rockylinux-old.qcow2
-rw------- 1 root root 196760 Feb 15 15:49 /var/lib/libvirt/images/rockylinux-old.qcow2

# virsh vol-list default
 Name                   Path
----------------------------------------------------------------------
 isos                   /var/lib/libvirt/images/isos
 rockylinux-old.qcow2   /var/lib/libvirt/images/rockylinux-old.qcow2
 rockylinux.qcow2       /var/lib/libvirt/images/rockylinux.qcow2

下記のように、作成したxmlファイルを指定して、マイグレーションを開始します。

# virsh migrate --live --copy-storage-all --persistent --verbose --xml rockylinux-old.xml rockylinux-old qemu+ssh://user@10.2.0.242/system
GitHubで編集を提案

Discussion