Transferring a KVM virtual machine installed on an LVM partition to another server using lvmsync

Greetings Habr!

In this short how-to I would like to share with you my experience in using the lvmsync utility.

This utility allows you to solve the problem of transferring a virtual machine from one KVM server to another, with minimal downtime of the virtual machine, without using shared storage (non-shared storadge).
We will transfer the entire LVM partition on which the virtual machine is installed. Well, the magic of LVM snapshot will help us to reduce downtime. You can easily find information about it on the Internet.

Here is a summary of the virtual machine transfer:

  1. Take a picture of the LVM section.
  2. We transfer the main LVM partition over the network without stopping our VM.
  3. When the transfer of the primary partition ends, stop the VM.
  4. Run lvmsync to transfer the snapshot over the network. Not the whole picture is transferred, but only the changed blocks.
  5. We prepare and run the VM on the new server.

As a result, when using lvmsync, the virtual machine downtime will be equal to the transfer time of the modified blocks in the snapshot of the main partition.

You can read more about the work of lvmsync, and additional goodies on the project page .

It is further assumed that we have sudo rights in the system, ssh access is configured by keys, and root access is denied.

Let's start the VM transfer:


For lvmsync to work, we need Ruby 1.8 (or later), ssh, and dmsetup.
Download lvmsync to the local computer:


Copy lvmsync to root PATH, for example, to / usr / bin /

Preparing the remote server (server2):

1) Download and install lvmsync.
2) Create an LVM partition for the replicated VM.

server2# lvcreate vg -n new-virtual  -L 16G

The size of the partition should be equal to the original partition (in principle, it may be larger than the original, but I have not tested this option).

Preparing the local server and moving the VM.

Further, all the commands must be executed on the server from which we want to move the virtual machine (server1).

1) Create a definition xml:

server1# virsh dumpxml virtual > virtual.xml

2) Take a picture of the section:

server1# lvcreate --snapshot -L10G -n virtual-snap /dev/vg/virtual

Please note that the image size should be selected depending on the intensity of use of the VM. Because all data, while we transfer the main section, will be “saved” to the snapshot.
And when the picture is completely filled, it is automatically deactivated .

3) Without stopping the VM, we transfer the main partition using dd:

server1# dd if=/dev/vg/virtual bs=1M | gzip -c | pv -ptrb | ssh me@server2 "gunzip -c | sudo dd of=/dev/vg/new-virtual"

Here the compression of the transmitted data with a gzip is added, and the display of the data transfer progress using pv.

4) When the transfer is complete, stop the virtual machine:

server1# virsh shutdown virtual

5) And after the machine stops completely, start lvmsync to transfer the image:

server1# lvmsync --stdout /dev/vg/virtual-snap | ssh me@server2 sudo lvmsync --apply - /dev/vg/new-virtual

This operation will not only transfer the snapshot to the new server, but also hold it immediately with the main LVM partition.

6) Copy definition xml to the remote server:

server1# scp virtual.xml me@server2:/home/me/new-virtual.xml

Preparing and starting a virtual machine on a new server:

1) Change the definition xml, if necessary.

2) Create a virtual machine based on xml:

server2# virsh define new-virtual.xml

3) We start our virtual machine, and register it in the auto start:

server2# virsh start new-virtual
server2# virsh autostart new-virtual

That's it, virtual machine migration is finished!


The utility was tested on Centos 6.4. I find it difficult to say anything about the transfer time, because it all depends on the intensity of working with the virtual machine during its transfer, and, accordingly, the size of the snapshot.

Also popular now: