VMware vApp (from vSphere) to KVM

So we have a simple migration at hand looking at the current virtualization landscape, right ?

  1. Use virt-convert from python-virtinst. In other words: OVF to libvirt’s XML
  2. Launch KVM with the resulting migrated files (both images and metadata)
  3. Do trivial configurations inside the guest machine to match host environment

That was my idealized view. It turns to be this way:

  1. Try virt-convert to discover that it fails when converting from OVF.
  2. Try to fix libvirt python code libraries (OVF XML parser).
  3. When the code is fixed, the resulting metadata files are malformed.
  4. Try with the commercial “vCenter Converter Standalone”: ERROR: “OVF contains multiple virtual machines”.
  5. Download ~500MB of “VMWare Server” to just use the “vmware-vdiskmanager” binary (1.4MB).
  6. Construct libvirt’s xml, with some hand-edited sections.
  7. virt-manager fails when connecting via VNC to your remote VM due to a Ubuntu-CentOS cross-distro issue involving NetCat parameters. Place a workaround and report the bug.
  8. Optimize both virtual network and disk performance switching to VirtIO.
  9. Rebuild guest ramdisk image in order to load VirtIO drivers in the boot process.


Dilbert.com

Want more details ? Keep reading…

Conversion

At the time of writing these lines, converting a file to OVF is barely supported by the virt-convert migration tool:

$ virt-convert -v -i ovf -D qcow2 vApp.ovf
Generating output in 'virt-image' format to vm/
ERROR Couldn't export to file "vm/vm.virt-image.xml":
VM must have a memory setting

After fixing some xpath code I manage to create an XML file lacking several sections. Since it seems that we reached a dead end here, it is time to convert the vmdk images and define the libvirt xml schema later on:

$ qemu-img convert -f vmdk -O qcow2 vApp-disk1.vmdk pfam.qcow2
qemu-img: error while reading

Ok, the vmdk files are not in a format that qemu-img can understand, let’s convert it with the proprietary tool:

$ ./vmware-vdiskmanager -r disk1.vmdk -t 0 final.vmdk
SSLLoadSharedLibrary: Failed to load library
libcrypto.so.0.9.8: libdir/lib/libcrypto.so.0.9.8/libcrypto.so.0.9.8:
cannot open shared object file: No such file or directory

Allright, it seems that needs a specific openssl library that does not match the symbols of the currently installed one on my system. Retrieving that library file from VMWare server tarball solves it:

LD_LIBRARY_PATH="$CWD" ./vmware-vdiskmanager -r disk1.vmdk -t 0 final.vmdk
Converting 1%...

It takes a little while, but succeds. I still want qcow2 files to do proper snapshots:

$ qemu-img convert final.vmdk -O qcow2 final.qcow2

If you are running SELinux, don’t forget to restore the context for your newly created files with “restorecon”, otherwise the VM will not launch:

# restorecon final.qcow2
-rw-r--r-- root root system_u:object_r:virt_image_t final.qcow2

Image migration complete !

Working on the metadata

Now we have to describe basic properties about the virtual machine. Please note that this is a highly “YMMV” section, you should customize it to fit your needs ! But for the impatient:

<domain type='kvm'>
  <name>vm</name>
  <memory>2097152</memory>
  <currentmemory>2097152</currentmemory>
  <vcpu>1</vcpu>
  <os>
    <type arch='x86_64' machine='pc'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi />
    <apic />
    <pae />
  </features>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/local/bin/kvm</emulator>
    <disk type='file' device='disk'>
      <source file='/var/lib/libvirt/images/vm.qcow2'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <interface type='bridge'>
      <mac address='54:52:00:24:34:16'/>
      <source bridge='br0'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
    </interface>
    <serial type='pty'>
      <source path='/dev/pts/4'/>
      <target port='0'/>
    </serial>
    <console type='pty' tty='/dev/pts/4'>
      <source path='/dev/pts/4'/>
      <target port='0'/>
    </console>
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='5900' autoport='yes' keymap='en-us'/>
  </devices>
</domain>

I use to place this file under: /etc/libvirt/qemu/vm.xml.tmpl. In that way I can edit the template and reload it back to libvirtd.

# virsh undefine vm
(edit)
# virsh define vm.xml

You can also use the handy command “virsh edit vm”.

Keep in mind “virtio, acpi, apic” tags/attributes, they are not set by default, and can lead to several booting problems.

Optimize and tweak VM

The default fully virtualized devices are generally slow for production, switching to paravirtualized drivers is advised to gain good speedups both in HDD and networking.

But this speedups need some tweaks in the guest machine, basically changing “sda” or “hda” to “vda” and loading the appropiate modules during ramdisk init:

(in /boot/grub/menu.lst):

title Debian GNU/Linux, kernel 2.6.26-2-amd64
root (hd0,0)
kernel /boot/vmlinuz-2.6.26-2-amd64 root=/dev/vda1 ro clocksource=acpi_pm quiet
initrd /boot/initrd.img-2.6.26-2-amd64


(in /etc/initramfs-tools/modules) add:

virtio_pci
virtio_blk

Then, update the ramdisk image by running:

# update-initramfs -u

Bringing it up

Now, using virt-manager, you expect to see your virtual machine booting… but it complains about not being able to connect via VNC. Looking around launchpad bug I get some pointers and manage to fix the issue and report my case.

As usual I only wish others to avoid wasting their time on those bugs, good luck ;)

4 thoughts on “VMware vApp (from vSphere) to KVM

  1. Ohhh you know a lot! My computer is broken, can you fix it? XDDD

    Cheers and congrats for such a thorough article :)

  2. great reading from you again :)

    just a small typo: “Keep in mind “virtio, acpi, acpi” tags/attributes,” should read ‘virtio, acpi, apic’.

    Salut!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>