Images virtueller Maschinen von Xen nach KVM konvertieren und in libvirt einbinden

Problem: Ein alter Xen-Server unter Ubuntu 7.10 (Gutsy Gibbon) mit diversen Hardy-Gästen, neuerdings zickig und nicht mehr unterstützt. Ein vorsichtiges Update auf Hardy Heron machte Xen erst richtig instabil, mindestens eine VM war immer down.

Ein Wechsel zu KVM lag also nahe, zumal er schon lange auf der Todo-Liste stand und nur aus Zeitgründen noch nicht umgesetzt wurde. Da ich die KVM-Unterstützung in Hardy auch nicht in allzu guter Erinnerung hatte, Lucid Lynx in wenigen Tagen released werden wird und ich mit KVM unter Lucid schon gute Erfahrungen gemacht habe, wurde also erst einmal auf Lucid aktualisiert.

Dann mussten zunächst die Disk-Images der Xen-Maschinen konvertiert werden. Das geht nicht automatisch, aber es gibt im Netz beispielsweise unter [1] und [2] gute Hinweise dazu. Wir haben uns nicht ganz daran gehalten, vor allem, weil wir die VMs unter Xen teilweise gar nicht mehr booten konnten, um sie vorbereitend zu modifizieren.

Zur Konvertierung und Inbetriebnahme eines Images hat sich dieser Ablauf bewährt:

Neues Image erstellen, etwas größer als das Xen-Image zzgl. gewünschter Swap-Partition. Für ein 150GB-Image:

# dd if=/dev/zero of=kvm.img bs=1M count=163840

Image partitionieren:

# parted kvm.img mklabel msdos
# parted kvm.img mkpart primary ext2 0 162000 -a minimal
# parted kvm.img mkpart primary linux-swap 162000 163840
# parted kvm.img set 1 boot on

Block-Devices für das Image erstellen:

# losetup /dev/loop0 kvm.img
# kpartx -a /dev/loop0

Inhalt des Xen-Images kopieren und an Partition ausrichten:

# dd if=/opt/domain/domains/alter-xen-server/disk.img of=/dev/mapper/loop0p1 bs=1M
# fsck.ext3 -f /dev/mapper/loop0p1
# resize2fs /dev/mapper/loop0p1
# fsck.ext3 -f /dev/mapper/loop0p1

Swap anlegen:

# mkswap /dev/mapper/loop0p2

Grub und Kernel in Partition installieren:

# mount /dev/mapper/loop0p1 /mnt
# mkdir -p /mnt/boot/grub
# cp /boot/grub/stage1 /mnt/boot/grub/
# cp /boot/grub/stage2 /mnt/boot/grub/
# cp /boot/grub/e2fs_stage1_5 /mnt/boot/grub/
# chroot /mnt
# apt-get install grub linux-server
# update-grub
# exit
# umount /mnt

Block-Devices entfernen:

# kpartx -d /dev/loop0
# losetup -d /dev/loop0

Boot-Sektor installieren:

# echo "device (hd0) kvm.img
root (hd0,0)
setup (hd0)
quit" > /tmp/grub.input
# grub --device-map=/dev/null < /tmp/grub.input

Eine Instanz in libvirt bekanntmachen:
Vorher wurde "roge-subnet-1" definiert, so wie das Subnetz unter [3].

# virt-install -n mein-toller-server -r 512 --vcpus=1 --os-type=linux --os-variant=ubuntuhardy --virt-type=kvm --import --disk /opt/kvm/mein-toller-server/kvm.img --network network=roge-subnet-1,model=virtio --vnc --noautoconsole

Mit etwas Glück läuft anschließend die virtuelle Maschine und ist erreichbar. Falls eine Firewall auf dem Server läuft, sollte man daran denken, die Interfaces entsprechend der neuen Netzwerk-Konfiguration anzupassen.

Für die dd-Aufrufe muss Zeit eingeplant werden. Der erste dauert für diese Größe etwa 30 Minuten, der zweite einige Stunden.

[1] http://searchnetworking.techtarget.com.au/articles/35011
[2] http://blog.pregos.info/2009/09/06/migration-virtueller-maschinen-von-xen-zu-kvm/
[3] http://wiki.hetzner.de/index.php/Netzkonfiguration_für_Xen_und_KVM_mit_libvirt