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.