Programster's Blog

Tutorials focusing on Linux, programming, and open source

KVM - Creating Thinly Provisioned Guests


When you create external snapshots, you create a read-only file that represents your virtual machine at a certain point in time. Since the data is read-only, we can use this file as a base for other guests we create in future. In order to operate, the guests will have all their changes go to a new empty file that we allocate them. Since we only need to create an empty qcow2 file for each guest, rather than copy the guest we are cloning, creating a guest takes seconds to perform (it was instant for me). Also, because the guests are all sharing the same base image, this saves a lot of storage and is called thin-provisioning.

An example diagram is shown below in which 3 guests are cloned from a base image, which is then updated, and a 4th guest is then cloned off the updated base image. With all 5 virtual machines, the storage needs is only about 4.4 GB (the size of the base image).

Ubuntu 16.04 Guest 1 
8.2 MB
[Not supported by viewer]
Ubuntu 16.04 Guest 2
8.2 MB
[Not supported by viewer]
Ubuntu 16.04 Guest 3
8.2 MB
[Not supported by viewer]
Base Ubuntu 16.04 Template Image 
(4.4 GB)
[Not supported by viewer]
Ubuntu 16.04 Guest 4
8.2 MB
[Not supported by viewer]
read-only snapshot 1
read-only snapshot 1
read-only snapshot 2
read-only snapshot 2
current disk image writes go to.
current disk image writes go to.

Below is a script I created for creating thinly provisioned guest called "new-guest" from a base image called "template-ubuntu-16.04-docker". Just tweak the variables at the top to change it to your needs.


# Specify settings here.

# Create a directory for anything related 
# to our guest such as snapshots

# Create a qcow2 disk file for our new guest.
sudo qemu-img create -f qcow2 \

# Generate a new xml file for the guest.
# This takes care of changing the MAC address for us.
sudo virt-clone \
--original $BASE_GUEST_DOMAIN \
--file=$NEW_GUEST_DISK \
--preserve-data \
--print-xml > $NEW_GUEST_XML_PATH

# Use the xml file to define the new guest
sudo virsh define $NEW_GUEST_XML_PATH

After creating a guest, it's a good idea to start it up and run the following commands from inside the guest to give it a new unique identity that is different from the machine it was cloned from.

sudo /bin/rm -v /etc/ssh/ssh_host_*
sudo dpkg-reconfigure openssh-server

Taking It Further

In a future post, I plan to see if I can live migrate guests without shared storage, and see if using external snapshots can be useful in the process.