Home » Random Goodies » Migrating from Proxmox/OpenVZ to ESX/ESXi/VMWare Server Part 1

Migrating from Proxmox/OpenVZ to ESX/ESXi/VMWare Server Part 1

It seems there is little to no documentation on migrating over from Proxmox/OpenVZ to VMWare server/ESX/ESXi. With that being said, a tutorial (which includes break time) is needed 🙂
The following will cover all the basics needed to successfully transfer over your OS from OpenVZ, to vmdk format.

Let’s begin:

1. Create an image file big enough to fit your OS. In my case, the VM was taking up 12GB so I’m going around 13GB for the image file size to be on the safe side.

You can determine the size of your VM/CT like so:

root@ks28473:~# vzlist -a|grep hostname
107 449 running xxx.xxx.xxx.xxx your.hostname.com
root@ks28473:~# du -sh /var/lib/vz/root/107
12G /var/lib/vz/root/107

Then on to the image creation:

root@ks28473:~# dd if=/dev/zero of=/var/lib/vz/transfer.img bs=516096c count=26000
26000+0 records in
26000+0 records out
13418496000 bytes (13 GB) copied, 149.642 s, 89.7 MB/s
root@ks28473:~# fdisk -u -C26000 -S63 -H16 /var/lib/vz/transfer.img

If you get any issues with fdisk, such as:

root@ks28473:~# fdisk -u -C26000 -S63 -H16 /var/lib/vz/transfer.img
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x29f27a31.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
switch off the mode (command 'c').
Command (m for help):

First print to make sure you’re on the right partition by typing ‘p’:

Command (m for help): p
Disk /var/lib/vz/transfer.img: 0 MB, 0 bytes
16 heads, 63 sectors/track, 26000 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x29f27a31
Device Boot Start End Blocks Id System
Command (m for help):

Then type:

Command (m for help): w
The partition table has been altered!
Syncing disks.

2. Mount image and create your filesystem:

root@ks28473:~# losetup -o32256 /dev/loop0 /var/lib/vz/transfer.img

Note creating the filesystem correlates directly with the amount of bytes which the first dd image creation showed, which in our case was 13104000 (13418496000 / 1024). Due to overhead, to avoid going out of bounds with the filesystem, we will use 13103000(KB) instead:

root@ks28473:~# mke2fs -b1024 /dev/loop0 13103000
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
819200 inodes, 13103000 blocks
655150 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=80216064
1600 block groups
8192 blocks per group, 8192 fragments per group
512 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409, 663553,
1024001, 1990657, 2809857, 5120001, 5971969
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 28 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

If you receive a warning similar to this, then you would have to reduce the size a bit more:

root@ks28473:~# mke2fs -b1024 /dev/loop0 13104000
mke2fs 1.41.12 (17-May-2010)
mke2fs: Filesystem larger than apparent device size.
Proceed anyway? (y,n) n

Now to add an ext3 journal to the filesystem, mount and check status:

root@ks28473:~# tune2fs -j /dev/loop0
tune2fs 1.41.12 (17-May-2010)
Creating journal inode: done
This filesystem will be automatically checked every 28 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
root@ks28473:~# mkdir /mnt/transfer && mount -text3 /dev/loop0 /mnt/transfer
root@ks28473:~# df -ah /mnt/transfer
Filesystem Size Used Avail Use% Mounted on
/dev/loop0 13G 36M 12G 1% /mnt/transfer

So far so good 😀

4. Now comes the fun part – coping over the container contents. We previously determined that the container ID was 107. At this point, there are two methods of going about this: best practice, zero-downtime. They are as follows:

– For “Best practice”, we’re going to do a first pass copy, then remove the IP addresses, shutdown the container, do the second rsync pass (which will omit previously copied files unless modified since), readd the IP addresses and restart the container. It goes something like this:

root@ks28473:/# rsync -a /vz/private/107/ /mnt/transfer/
root@ks28473:/# grep ^IP_ADDRESS /etc/vz/conf/107.conf
root@ks28473:/# vzctl stop 107
Stopping container ...
Container was stopped
Container is unmounted
root@ks28473:/# vzctl set 107 --ipdel --ipdel --save
CT configuration saved to /etc/pve/openvz/107.conf
root@ks28473:/# rsync -a /vz/private/107/ /mnt/transfer/
root@ks28473:/# vzctl set 107 --ipadd --ipadd --save
root@ks28473:/# vzctl start 107

The reason this is considered best practice is to avoid further network configurations which vary by OS, inconsistent data migration, possible database corruptions if using InnoDB and the list goes on. When we restore the vmdk on VMWare server/ESX/ESXi, adding the IP addresses in vSphere would not have any conflicts.

– For “Zero-downtime”, we’re going to do everything live, so removing the IP addresses is no longer required as we will simply be copying over the data. Please note, using this method may result in the VM not booting as well:

root@ks28473:/# rsync -a /vz/private/107/ /mnt/transfer/

5. Now that we have our data on the image mount, let’s move on to converting it in a format that VMWare would accept it. This requires unmounting the image, and proceeding as follows:

root@ks28473:/# umount /mnt/transfer && mkdir ~/dev && cd ~/dev
root@ks28473:~/dev# wget http://iweb.dl.sourceforge.net/project/kvm/qemu-kvm/1.2.0/qemu-kvm-1.2.0.tar.gz
root@ks28473:~/dev# tar zxf qemu-kvm-1.2.0.tar.gz
root@ks28473:~/dev# cd qemu-kvm-1.2.0
root@ks28473:~/dev/qemu-kvm-1.2.0# apt-get install zlib1g-dev pkg-config libglib2.0-dev
root@ks28473:~/dev/qemu-kvm-1.2.0# ./configure && make
root@ks28473:~/dev/qemu-kvm-1.2.0# ./qemu-img convert -f raw /var/lib/vz/transfer.img -O vmdk /var/lib/vz/transfer.vmdk

The conversion process will be a lot faster than the time it took to copy the filesystem. This is mainly due to only having to deal with one file vs thousands if not millions.

*** NOTE ***
While you can ‘apt-get install qemu-kvm’ this is not suggested. It can break Proxmox as it replaces/uninstalls key PVE components.
*** NOTE ***

6. Time to transfer some data. Now we will be transferring the newly created disk image to ESXi and then create a custom guest OS using Virtual Machine Version 7 and selecting “Use an existing virtual disk”.

Initiate the file transfer in your Proxmox server:

root@ks28473:~/dev/qemu-kvm-1.2.0# scp /var/lib/vz/transfer.vmdk root@esxi.your.host.com:/vmfs/volumes/datastore/
transfer.vmdk 5% 701MB 10.0MB/s 19:17 ETA

Once the transfer is complete, we need to convert it to thin format on ESXi. This will be covered in part 2 – stay tuned.

  • aurelien

    Thanks a lot for this tutorial, there is so little documentation on this!
    Before starting with my VM migration I would like to know if this applies to proxmox 3.0 and how different this procedure is from the export of the vm to the vmdk format using the “clone” function.
    I hope you soon get some time to publish “part 2”!

  • admin


    Sorry for the long delay, been really busy with work. This is basicaly the same process, but a bit more in depth as to the manual aspect if ever needed. I was bored one day what can I say 🙂 It works for Proxmox 3.0 as well. I’ll get around to part 2 either in the next few days or next week.

  • mouste

    Hi admin,

    This is a great tutorial and very useful. Many thanks for this! When do you plan to show part 2, I would to get going with importing into ESXi.

    Thanks again!