Migrating OpenVZ virtual machines to OpenStack

A OpenVZ cluster hosts GNU/Linux based virtual machines. The disk is extracted with rsync and uploaded to the glance OpenStack image service with glance add … disk_format=ami…. It is associated with a kernel image compatible with both OpenStack and the existing file system with glance update … kernel_id=0dfff976-1f55-4184-954c-a111f4a28eef ramdisk_id=aa87c84c-d3be-41d0-a272-0b4a85801a34 ….

copying the file system to a disk image

A virgin disk image is created with:

qemu-img create temporary.img 5G

The 5G size is chosen to be large enough to contain the file system of the OpenVZ container to be migrated. The image is initialized with a ext4 file system:

# mkfs.ext4  temporary.img
mke2fs 1.42.5 (29-Jul-2012)
temporary.img is not a block special device.
Proceed anyway? (y,n) y
Discarding device blocks: done
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
327680 inodes, 1310720 blocks
65536 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=1342177280
40 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

The image is mounted with

# mount -o loop  temporary.img /mnt
# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop1      5.0G  203M  4.6G   5% /mnt

After login into the OpenVZ container, the entire file system is transfered to the disk with

openvz# rsync -avHSz --numeric-ids --exclude=/proc --exclude=/sys \
                      / bm0001.the.re:/mnt/

When it completes, the /proc and /sys directories must to be created:

mkdir /mnt/proc /mnt/sys

And the eth0 interface must be added to /mnt/etc/network/interfaces as follows:

auto eth0
iface eth0 inet dhcp

The file system can then be umounted and reduced to its minimal size with:

# umount /mnt
# fsck -f $(pwd)/temporary.img
# resize2fs -M temporary.img

uploading to glance

Assuming the OpenVZ container was running on a 2.6.32 linux kernel, a compatible kernel and the corresponding initrd are uploaded to glance with:

glance add is_public=true name='initrd-2.6.32-5-amd64' disk_format=ari \
  container_format=ari < initrd.img-2.6.32-5-amd64
glance add is_public=true name='linux-2.6.32-5-amd64' disk_format=aki \
  container_format=aki < vmlinuz-2.6.32-5-amd64

The uuid of the kernel and initrd are listed with:

# glance --limit=400 index | grep 2.6.32
6bd78e8c-7ada-4e6f-bf5c-158de71c7664 initrd-2.6.32-5-amd64 ari ari 9309460
42d6e697-28b2-40b7-adcb-7c77b209bf97 linux-2.6.32-5-amd64 aki aki 2424448

The temporary.img file system can then be uploaded with:

glance add disk_format=ami container_format=ami name="exemple" \
  is_public=false \
  kernel_id="42d6e697-28b2-40b7-adcb-7c77b209bf97" \
  ramdisk_id="6bd78e8c-7ada-4e6f-bf5c-158de71c7664" < temporary.img

booting

The instance can then boot with

nova boot --image 'exemple' --flavor e.1-cpu.10GB-disk.1GB-ram --key_name loic --availability_zone=bm0001 --poll exemple

and the boot log should look like:

# nova console-log exemple
...
INIT: version 2.88 booting
Using makefile-style concurrent boot in runlevel S.
Activating swap...done.
Cleaning up ifupdown....
Activating lvm and md swap...done.
Checking file systems...fsck from util-linux-ng 2.17.2
done.
Setting up networking....
Mounting local filesystems...done.
Activating swapfile swap...done.
Cleaning up temporary files....
Configuring network interfaces...Internet Systems Consortium DHCP Client 4.1.1-P1
Copyright 2004-2010 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/eth0/fa:16:3e:33:0a:bf
Sending on   LPF/eth0/fa:16:3e:33:0a:bf
Sending on   Socket/fallback
[    3.280425] eth0: IPv6 duplicate address fe80::f816:3eff:fe33:abf detected!
Setting kernel variables ...done.
DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 4
DHCPOFFER from 10.145.2.11
DHCPREQUEST on eth0 to 255.255.255.255 port 67
DHCPACK from 10.145.2.11
bound to 10.145.2.9 -- renewal in 50 seconds.
venet0: ERROR while getting interface flags: No such device
Failed to bring up venet0.
SIOCSIFADDR: No such device
venet0:0: ERROR while getting interface flags: No such device
SIOCSIFNETMASK: No such device
venet0:0: ERROR while getting interface flags: No such device
Failed to bring up venet0:0.
done.
Cleaning up temporary files....