Pither.com / Simon
Development, systems administration, parenting and business

Convert an OpenVZ VM to KVM

I administer (mostly through SEOSS) quite a few OpenVZ virtual machines and I recently wanted to create a clone of one onto a local system for some testing. Unfortunately I didn't have an OpenVZ machine locally, so decided I'd have a go at migrating the OpenVZ virtual to a local KVM instance. The process I went through is below.

Create a local disk image for the clone.

qemu-img create -f raw clone.raw 10G

Setup a loop back device so the image can have a partition table created.

sudo losetup /dev/loop0 clone.raw
sudo fdisk /dev/loop0

Create swap (1st primary partition, 2G in size and set type to Linux swap - just the fdisk key presses are listed).

n
p
1
<enter>
+2G
t
82

Create root (2nd primary partition, rest of disk - just the fdisk key presses are listed).

n
p
2
<enter>
<enter>

Finally save and quit fdisk.

w

Remove the simple loopback device.

sudo losetup -d /dev/loop0

Create loopback devices for each of the new partitions.

sudo kpartx -av clone.raw

Initialise the swap partition and create a suitable file system on the root.

sudo mkswap /dev/mapper/loop0p1
sudo mke2fs -j /dev/mapper/loop0p2

Mount the clone's root file system locally and rsync the remote source machine into it. In my case I connect to the actual, running VM as there is nothing running that will break my copy. In other cases it may be necessary to shutdown the source VM and rsync the underlying directory from the host machine.

mkdir mnt
sudo mount /dev/mapper/loop0p2 mnt
sudo rsync -avzx --numeric-ids root@your.source.machine:/ ./mnt/

An OpenVZ VM doesn't have terminals but some will be needed for KVM.

sudo vi mnt/etc/inittab
# Re-enable the tty terminals

Having a DHCP client will also make life easier with KVM, so I install a common one.

sudo chroot mnt
apt-get install isc-dhcp-client
exit

Finished with the root file system and the cloned image loopbacks.

sudo umount mnt
sudo kpartx -d clone.raw

For the next bit, you'll need to have a suitable kernel (to run the VM) installed locally (outside the VM).

sudo kvm -m 512 -kernel /boot/vmlinuz-2.6.38-11-generic -initrd /boot/initrd.img-2.6.38-11-generic -append "root=/dev/vda2" -drive file=clone.raw,if=virtio -net nic,model=virtio -net user

For some reason I had to change VT (ie Alt+F2) within the KVM console in order to get a login prompt. Make sure you login as (or become) root for the next bit.

For me the KVM networking interface appeared as eth3 (you can check with "ip a"), which needs to be used in the next commands.

echo "auto eth3" >> /etc/network/interfaces
echo "iface eth3 inet dhcp" >> /etc/network/interfaces

ifup eth3

Install a kernel (choose one suitable for your VM) and a boot loader (probably grub).

apt-get install linux-image-amd64 grub

The normal grub configuration questions will need answering during this. To tidy up you probably want to enable the swap space and create a simple fstab as well.

vi /etc/fstab

cat /etc/fstab 
/dev/vda2 / ext3 rw,relatime 0 0
/dev/vda1 none swap defaults 0 0

swapon -a

shutdown -h now

The machine can now be run without sudo and with a simpler command line

kvm -m 512 -drive file=clone.raw,if=virtio,boot -net nic,model=virtio -net user

That's it! You may want to reconfigure the networking, perhaps import the VM into libvirt/virt-manager or perform other configuration specific to your setup. For me, I just needed a local clone of the machine for testing so I stuck with the existing config and just ran it from the command line when needed.

Add a comment