Cloning a live, running Linux sytem into a KVM image for near-zero downtime.

Synopsis

We had this older i686 Linux server running in a facility, hadn't had upgrades in a while and the machine was very stable. Software upgrade was not cricitcal but the hardware was dying and we recently deployed a newer amd64 system. We cloned that dying i686 box, into KVM on the amd64, powered off the physical system and powered up the KVM one. Users on the network only saw this a reboot of the server, flawless victory!

Preparing a Linux Bootable

This command set creates a new disk image, edit partitions, makes it bootable, creates a file-systems and then copies a running system. This is not for the faint of heart, but it should be directly bootable!

~ # modprobe nbd max_part=4
~ # qemu-img create -f qcow2 clone.qcow 64G
~ # qemu-nbd --port 6500 --connect /dev/nbd0 --verbose clone.qcow
~ # cfdisk /dev/nbd0
~ # mkfs.ext3 -L Clone -v /dev/nbd0p1
~ # mount /dev/nbd0p1 /mnt/clone
~ # mkdir -p /mnt/clone/boot
~ # syslinux --install /mnt/clone/boot
~ # rsync -av --one-file-system root@source:/ /mnt/clone/

You must load NBD with max_part parameters! The cfdisk command is used to create a single partition and mark it bootable. We use syslinux as the bootloader and rsync clones the running system.

You will need to repeat the rsync command for all file systems necessary to clone, like perhaps /boot, /home, /opt. The rsync for us took 181 minutes.

Updating the Image

Since the underlying hardware is changing a bit (consolidate partitions maybe?) we need to update configs on the clone.

~ # nano /mnt/clone/boot/syslinux.cfg
~ # nano /mnt/clone/etc/fstab
~ # nano /mnt/clone/etc/conf.d/net

Tear Down

~ # umount /mnt/clone
~ # qemu-nbd --disconnect /dev/nbd0
~ # rmmod nbd
~ # qmeu-kvm clone.qcow

Start the Image

~ # tunctl -t tap03
~ # brctl addif br0 tap03
~ # ifconfig tap03 up 0.0.0.0 promisc
~ # qemu-kvm \
  -m 1024 \
  -cpu qemu32 \
  -name "Clone" \
  -drive file=/opt/kvm/clone.qcow,if=ide,index=0 \
  -net nic,vlan=0,macaddr=00:00:00:00:00:00,model=e1000 \
  -net tap,vlan=0,ifname=tap03,script=no,downscript=no \
  -vga std \
  -vnc 0.0.0.0:5903 \
  -monitor telnet:localhost:2303 \
  -usb \
  -usbdevice tablet \
  -daemonize

Now, VNC in and see if it boots OK, does the rest of it work too?

See Also