Migrating ganeti virtual machines to OpenStack (part 2 / 2)

A ganeti cluster hosts GNU/Linux based fully virtualized virtual machines, booting from a disk image with a boot loader and a partition table. The case of para-virtualized virtual machines has been covered in a previous post. An OpenStack LVM volume is created on a designated bare metal machine with euca-create-volume –zone ZONE –size INGB. The disk image is copied verbatim into the volume with a command such as dd if=/dev/drbd9 | ssh dd of=/dev/nova-volumes/vol-0001. The virtual machine is then defined on the same host to save bandwidth with nova boot … –block_device_mapping vda=39::0:0 … –availability_zone=ZONE … .

exposing the disk

The ganeti cluster contains kvm virtual machines, each with a single bootable disk containing a boot sector, a partition table and a kernel. The virtual machine is shutdown with:

# gnt-instance shutdown packaging-farm.dachary.vm.gnt

The DRBD disk is activated with

# gnt-instance activate-disks packaging-farm.dachary.vm.gnt

creating the volume

Check the size of the disk to create with:

# gnt-instance info packaging-farm.dachary.vm.gnt
    - disk/0: drbd8, size 20.0G

Assuming the bare metal machine on which the virtual is to be run is bm0007.the.re, create the volume that is to receive the disk with:

# euca-create-volume –zone bm0007 –size 20
VOLUME  vol-00000027    20       bm0007  creating (58a46c3994b54a3baa84a7fd5832372b, None, None, None)   2012-09-20T09:10:26.856Z

And wait until it is available:

# nova volume-list
| 39 | available | None         | 20    | None        |                                      |

upload the disk to the volume

To be able to resume the upload in case of a network failure, it is done by first compressing the disk and then uploading it, as follows, on the z2-6 ganeti node which was reported to host the primary DRBD device as shown when activating the disk.

# ssh z2-6
#  pv /dev/drbd9 | gzip > packaging-farm.img.gz

The file can then be transfered to the OpenStack machine ( and will resume if interrupted ) with :

# rsync -v --progress --inplace packaging-farm.img.gz bm0007.the.re:

In nova volume-list the id of the volume ( 39 ) will match the volume name on the machine, translated on base 16 ( 27 ). Alternatively the euca-describe-volumes command will display the volume name that exactly maps the LVM volume name:

 # euca-describe-volumes
VOLUME  vol-00000027     20    bm0007  available (58a46c3994b54a3baa84a7fd5832372b, bm0007.the.re, None, None)

When the transfert is complete, the file can be uncompressed and copied to the volume.

# ssh bm0007.the.re
# gzip -d < packaging-farm.img.gz | pv > /dev/nova-volumes/volume-00000027

creating the virtual machine

Before creating the virtual machine to boot from the volume, an image must be chosen. It should not be necessary and the image chosen will not actually be used. It is a minor bug in OpenStack Essex. The image chosen as an argument to the –image option can be any valid image available in glance.
However, it must not be an AMI associated with an AKI or ARI. It must be an image with no external kernel or initrd files. If an AMI is chosen, OpenStack will assume the volume just created contains a single file system instead of a bootable disk with a partition table and fail to boot.

# nova image-list | grep CirrOS
| fe44546e-66db-4983-8a49-6bed4afc1301 | CirrOS 0.3                    | ACTIVE |        |
# nova boot --image fe44546e-66db-4983-8a49-6bed4afc1301 \
                  --block_device_mapping vda=39::0:0  \
                  --flavor 7 --key_name loic  \
                  --availability_zone=bm0007 packaging-farm --poll

The only value that really matters in the –block_device_mapping vda=39::0:0 option is the 39 which is the number of the volume to boot from. There should be no need to adapt the other values in most cases. And after a few seconds check that it works with:

# nova console-log packaging-farm

Debian GNU/Linux wheezy/sid packaging-farm.dachary.org ttyS0

packaging-farm.dachary.org login:

And the volume is attached to the instance:

# nova volume-list
| 39 | in-use | None         | 20   | None        | 159c8c2c-5c76-4792-aacc-fbdced88eeac |