KVM: Implementing linked clones with a backing file

If you need KVM to bring up a full guest OS as quickly as possible, consider preparing a base disk image that can be used as the basis for any number of linked clones by using a backing file.

This article is related to a previous article, “Cloning and fixing an Ubuntu host using KVM“.  But instead of copying the entire disk file, it will instead use the concept of a backing file to create a very small new disk that references the larger backing disk of the parent host and only records the differences written.

Using a backing disk avoids the overhead of copying what might be Gigabytes of base OS and application settings.

Preparation

First, have a KVM guest OS prepared that can serve as the “parent” disk.  This machine should be powered down, and prepared at the OS level to come back up as clone.  For example, on Windows it would have been freshly sysprep’d, and on Linux it might be ready to run network configuration scripts on the next startup.

From a KVM standpoint the parent host needs to be in a format that can serve as a source backing file, only qcow2 and qed are supported.

As an example for this article, I’m going to create an Ubuntu 18.04 host with the following command.

virt-install --virt-type=kvm --name=ukvm1804 --ram 2048 --vcpus=2 --virt-type=kvm --hvm --cdrom ~/Downloads/ubuntu-18.04-live-server-amd64.iso --network network=default --graphics vnc --disk pool=kvmpool,size=20,bus=virtio,format=qcow2 --noautoconsole

I guide it through the manual Ubuntu installation process.  Then disconnect the CDROM.

cdrom=`virsh domblklist ukvm1804 --details | grep cdrom | awk {'print $3'}`

virsh change-media ukvm1804 $cdrom --eject

Finally, shutdown the host.  This is mandatory, you do not want the parent disk image modified after this point (destroy means stop, it does not mean delete the virtual host).

virsh destroy ukvm1804

Create new disk with backing file

Then create a new disk image using the parent image as the backing disk.  If you need to know where the parent disk is located, you can look at the xml.

virsh dumpxml ukvm1804 | grep "<source file"

Once you change into that directory, you can then create the new disk with parent backing file.

qemu-img create -f qcow2 -F qcow2 -b ukvm1804.qcow2 myclone1.qcow2

If you get a permissions error while reading ukvm1804.qcow2, use chown/chmod to make it owned by the ‘kvm’ group and read permission for the group (Your user should be a member of kvm and libvirt-qemu).  Also make sure you have permission to write in the directory.

Now you can can get information on the actual and virtual sizes of this new disk, along with its source backing files with the command:

qemu-img info myclone1.qcow2
qemu-img info myclone1.qcow2 --backing-chain

Create new linked clone

Deploying a new guest OS as a linked clone is now just a matter of specifying the new file as the primary disk.

virt-install --virt-type=kvm --name=myclone1 --ram 2048 --vcpus=2 --virt-type=kvm --hvm --network network=default --graphics vnc --disk /data/kvm/pool/myclone1.qcow2 --boot=hd --noautoconsole

You still need to fix up this host at the OS level, changing its hostname, network, openssl certs, etc..but that is the same as explained in my earlier article on cloning and fixing.

 

REFERENCES

https://infologs.wordpress.com/2012/08/10/kvm-qemu-snapshots-and-linked-clones/ (backing disk for linked clones)

https://kashyapc.fedorapeople.org/virt/lc-2012/snapshots-handout.html (backing file explanation)

https://dustymabe.com/2015/01/11/qemu-img-backing-files-a-poor-mans-snapshotrollback/ (developer workflow for snapshots, retries)

https://forums.unraid.net/topic/48837-creating-linked-clones/

https://blog.programster.org/qemu-img-cheatsheet (show full chain, convert formats, merge back down with commit, change backing, collapse to one)

https://serverfault.com/questions/324281/how-do-you-increase-a-kvm-guests-disk-space (resize KVM disks, LVM extension)

https://www.ndchost.com/wiki/libvirt/change-media (eject CDROM)

https://blog.programster.org/kvm-external-snapshots (external snapshots)

 

NOTES

Pull device label on CDROM using xpath (use “virsh domblklist” instead)

$ sudo apt install libxml-xpath-perl
$ cdrom=`virsh dumpxml ukvm1804 | xpath -q -e "/domain/devices/disk[@device='cdrom']/target/@dev" | cut -d= -f 2 | tr -d '"'`
$ echo disconnecting CDROM device $cdrom

disconnect CDROM (use change-media –eject instead)

virsh attach-disk ukvm1804 "" $cdrom --type cdrom --mode readonly

insert CDROM

change-media vm1 hdc /var/lib/libvirt/images/cd2.iso --insert

Create snapshot

$ virsh snapshot-create-as --domain <name> --name <snapshotName> 
$ virsh snapshot-dumpxml --domain <name> --snapshotname <snapshotName>
$ virsh snapshot-list --domain <name>
$ virsh snapshot-info --domain <name> --snapshotname <snapshotName>
$ virsh shutdown --domain <name>
$ virsh snapshot-revert --domain <name> --snapshotname <snapshotName>
$ virsh snapshot-delete --domain <name> -snapshotname <snapshotName>

resize disk img

qemu-img resize mydisk.img +20G