How to Migrate a KVM Guest Between Hosts Using LVM Storage and Bridged Networking


4 views

Before proceeding with the migration, ensure both source and destination hosts meet these requirements:

  • Identical or compatible kernel versions
  • Same versions of libvirt and QEMU
  • Identical network bridge configuration
  • Available LVM volume groups with sufficient space

On the source host, gather critical information about your VM:

# List all VMs
virsh list --all

# Dump VM configuration to XML
virsh dumpxml vm_name > vm_name.xml

# Check block device paths
virsh domblklist vm_name

For each LVM volume used by the VM, create snapshots and transfer them:

# Create LVM snapshot on source host
lvcreate -s -n vm_disk_snapshot -L 10G /dev/vg_name/vm_disk

# Transfer snapshot to destination host
dd if=/dev/vg_name/vm_disk_snapshot | ssh root@destination_host "dd of=/dev/vg_name/vm_disk"

Update the XML file to reflect new paths on destination host:

<disk type='block' device='disk'>
  <driver name='qemu' type='raw'/>
  <source dev='/dev/destination_vg/vm_disk'/>
  <target dev='vda' bus='virtio'/>
</disk>
# Copy XML file to destination host
scp vm_name.xml root@destination_host:/etc/libvirt/qemu/

# Define the VM
virsh define /etc/libvirt/qemu/vm_name.xml

# Verify configuration
virsh edit vm_name

For more complex scenarios, consider these options:

  • Virsh migrate: virsh migrate --live vm_name qemu+ssh://destination_host/system
  • Storage migration: virsh migrate --copy-storage-all vm_name qemu+ssh://destination_host/system
  • Offline backup/restore: Use virt-manager's export/import feature

Common pitfalls and their solutions:

# Error: "Unable to resolve address"
# Solution: Ensure /etc/hosts contains correct entries

# Error: "Permission denied"
# Solution: Verify SELinux contexts on LVM volumes:
restorecon -R /dev/vg_name/

When migrating KVM guests between hosts with LVM-backed storage, we need to handle three core components:

  1. The virtual disk data (LVM logical volumes)
  2. The VM configuration (libvirt XML)
  3. Network bridge configuration

1. Transferring LVM Volumes

First, identify the LVM volumes on the source host:

# On source host
lvdisplay | grep "LV Path"
sudo lvs -o lv_name,vg_name,size

Then transfer them to the destination host. For offline migration, you can use either dd or lvconvert:

# Using dd (simple but slower)
sudo dd if=/dev/vg_name/lv_name | ssh user@destination_host "dd of=/dev/vg_name/lv_name"

# Using LVM's native tools (faster)
sudo lvconvert --merge vg_name/lv_snapshot

2. Handling the VM Configuration

Export the XML configuration from the source host:

virsh dumpxml vm_name > vm_name.xml

Key elements to modify in the XML before importing:

<disk type='block' device='disk'>
  <source dev='/dev/vg_name/lv_name'/>
</disk>

3. Finalizing the Migration

On the destination host, define and start the VM:

virsh define vm_name.xml
virsh start vm_name

For larger environments, consider these more scalable methods:

# Using virt-v2v for conversion between hosts
virt-v2v -i libvirt -ic qemu:///system vm_name -o local -os /var/lib/libvirt/images

# Using shared storage (NFS/iSCSI)
<disk type='network' device='disk'>
  <source protocol='nbd' name='vm_image'>
    <host name='storage_host' port='10809'/>
  </source>
</disk>

  • Permission errors: Ensure consistent UID/GID for qemu processes
  • Network connectivity: Verify bridge names match between hosts
  • Storage paths: Double-check LVM volume names in the XML

For automated migrations in production environments, consider using tools like virt-manager or writing a custom script using libvirt's Python bindings.