How to Deploy Linux KVM Virtual Machine Live Migration using libvirt and QEMU

In enterprise virtualization, downtime is unacceptable. If a physical hypervisor (host node) requires a reboot for a kernel patch or hardware maintenance, the virtual machines (VMs) running on it cannot simply be shut down. Live Migration solves this. It allows a running VM to be transferred from one physical Linux host to another across a network, with absolutely zero perceived downtime or dropped TCP connections.

Under the hood of the Linux Kernel-based Virtual Machine (KVM), this miraculous feat is orchestrated by QEMU (which handles the memory transfer) and libvirt (which manages the state and configuration). During live migration, the source host copies the VM’s active RAM to the destination host iteratively. In the final fraction of a second, the source VM pauses, transfers the final few dirtied memory pages and CPU registers, and the destination VM instantly resumes execution.

This guide explains how to configure a highly available KVM environment and execute secure, peer-to-peer live migrations via libvirt.

Prerequisites for Live Migration

Live migration is a delicate orchestration of shared state. Your infrastructure must meet strict requirements:

  1. Shared Storage: The virtual disk (e.g., the .qcow2 file or LVM volume) MUST be accessible by both the source and destination hosts at exactly the same mount point. This typically requires NFS, iSCSI, or a clustered filesystem like Ceph or GlusterFS. (Block-level storage migration exists, but is significantly slower and less reliable).
  2. Layer 2 Network Parity: The destination host must have a virtual bridge (e.g., br0) with the exact same name as the source host, and both bridges must connect to the same physical VLAN. When the VM wakes up on the new host, it will broadcast a Gratuitous ARP to update switch mac-address tables.
  3. CPU Architecture Match: The source and destination CPUs should ideally be identical. If they differ, the VM must be configured to use a generic, compatible CPU model (e.g., qemu64 or Broadwell-noTSX) rather than host-passthrough.

Step 1: Configuring libvirt for Remote Access

By default, the libvirtd daemon only listens on local Unix sockets. For Host A to instruct Host B to accept a live migration, they must communicate securely over the network.

While SSH is the easiest transport, setting up native TLS for libvirt is the enterprise standard for high-throughput migration.

Edit the libvirt daemon configuration on both hosts:

sudo nano /etc/libvirt/libvirtd.conf

Enable TCP/TLS listening and specify the authorization mechanisms:

listen_tls = 1
listen_tcp = 0
auth_tls = "none" # In production, configure x509 cert validation

Next, edit the libvirt default systemd configuration to force the daemon to listen on network interfaces.

sudo nano /etc/default/libvirtd

Add the following flag:

libvirtd_opts="-l"

Restart the daemon on both hosts:

sudo systemctl restart libvirtd

Step 2: Securing the QEMU Migration Stream

The libvirt TLS connection only encrypts the management commands. The actual transfer of the VM’s RAM is handled by QEMU. If a VM has 32GB of RAM, transferring that unencrypted across a network is a massive security risk (memory scraping).

Edit the QEMU configuration on both hosts:

sudo nano /etc/libvirt/qemu.conf

Force QEMU to encrypt the migration stream and ensure the hypervisor runs under the correct unprivileged user:

user = "libvirt-qemu"
group = "libvirt-qemu"
# If using TLS for QEMU data streams (requires x509 cert setup):
# migrate_tls_x509_cert_dir = "/etc/pki/libvirt-migration"

Step 3: Preparing the Shared Storage

For this example, assume we have an NFS share mounted on both hosts at /var/lib/libvirt/images/shared.

Verify the VM disk is located on the shared mount:

virsh domblklist my-database-vm

Ensure the target reads: /var/lib/libvirt/images/shared/db-disk.qcow2.

Step 4: Executing the Live Migration via Virsh

With shared storage mounted and libvirtd listening, you can execute the migration from the source host.

The virsh migrate command takes several critical flags:

  • --live: Do not suspend the VM; perform an iterative memory transfer.
  • --p2p: Instruct the source libvirtd to manage the transfer directly to the destination libvirtd.
  • --auto-converge: If the VM is writing to RAM faster than the network can transfer it (dirty page rate > network bandwidth), artificially throttle the VM’s CPU to force the migration to converge.
  • --persistent: Ensure the VM’s XML configuration is permanently saved on the destination host after migration.

Execute the migration from Host A (source) to Host B (destination):

virsh migrate --live --p2p --auto-converge --persistent my-database-vm qemu+tls://host-b.internalcorp.com/system

This command will block until the migration is complete.

Step 5: Monitoring the Migration

In a separate terminal on the source host, you can monitor the progress of the memory transfer and the dirty page rate:

virsh domjobinfo my-database-vm

You will see output detailing Data processed, Data remaining, and Memory dirty rate. If the remaining data is not decreasing, the --auto-converge flag will kick in, slowly throttling the guest CPU until the final memory copy can complete within a sub-second window.

Conclusion

KVM Live migration is the cornerstone of non-disruptive infrastructure operations. By carefully aligning shared storage, Layer 2 networking, and libvirt TLS configurations, systems administrators can seamlessly teleport running workloads between physical hardware, ensuring 100% application uptime during critical data center maintenance.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.