KVM Live or Near-Live Migration from LVM to filesystem backend

My guest machine has 2 partitions (80GB + 1TB). Both of them is on LVM. I want to transfer all disks to another machine with minimum downtime. I transferred another machine with nc. It takes 4 days and during transfer my VM was off.

I tried to make snapshot after then transfer dirty pages. But AFAIK with LVM its'not possible. My target machine has no LVM setup and free unpartitioned space. So on target machine disks must be raw file images.

<disk type='block' device='disk'>
  <driver name='qemu' type='raw' cache='none'/>
  <source dev='/dev/vg-datastore/lv-vm-1138'/>
  <target dev='vda' bus='virtio'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</disk>
<disk type='block' device='disk'>
  <driver name='qemu' type='raw' cache='none'/>
  <source dev='/dev/vg-datastore-sata/lv-vm-1138-2'/>
  <target dev='vdb' bus='virtio'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</disk>

Source Host:

  • CPU: Intel(R) Xeon(R) CPU D-1520 @ 2.20GHz
  • OS: 16.04.1 LTS
  • Kernel: 4.2.0-34-generic
  • qemu-kvm: 1:2.3+dfsg-5ubuntu9.2
  • QEMU: 2.3.0
  • libvirt: 1.2.16

Target Host:

  • CPU: Intel(R) Xeon(R) CPU D-1520 @ 2.20GHz
  • OS: 16.04 LTS
  • Kernel: 4.4.0-28-generic
  • qemu-kvm: 1:2.5+dfsg-5ubuntu10.2
  • QEMU: 2.5.0
  • libvirt: 1.3.1

Solution 1:

KVM/libvirt supports VM live migration with storage migration (a shared-nothing setup), albeit with some limitation. Your main problem is that storage pools have different configuration, so I am not sure libvirt will migrate the VM image without problem.

The command to do a live migration + storage copy is:

virsh migrate  --live --copy-storage-all --persistent qemu+ssh://root@/system

This command presumes you have a valid libvirt-based connection to the remote host.

If you have problems migrating your virtual disks, you can try to create stub destination virtual disk files with executing (on the destination host) something similar to fallocate /dev/vg-datastore/lv-vm-1138 -l 80G and /dev/vg-datastore-sata/lv-vm-1138-2 -l 1T.

Anyway, due to differences between hosts, this can be a bumpy road.

A simpler way to migrate your VM images is to use an incremental disk copy approach, using blocksync. In short:

  • when the VM is running, do a first copy of the virtual disks to the destination host. This first copy will be incoherent and unreliable, but will work as a "seed" for the next copy;
  • at appropriate time, shutdown the VM and execute a second copy of the virtual disks. This second copy will transfer the changed blocks only and it will be much faster than the first one;
  • when finished, define the virtual domain and start the VM on the destination host.

Please note that the linked blocksync program is a personal forked version based on this original script (which, by the way, is a improved version of this script). I obviously assume NO RESPONSIBILITY for the code and I strongly suggest you to thoroughly test it before using it on production virtual machines/disk files. As always, you MUST have a confirmed-good backup before doing anything.

EDIT: as suggested in the comment below, another great software to synchronize a block device/virtual image file is bdsync. The approach is basically the same: take a first "seed" copy of the disk file while the VM is running, then stop the VM and do another final copy. In the past I even asked bdsync developer about a similar question; see here for more information.