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]
updates
updates
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.

#!/bin/bash

# Specify settings here.
NEW_GUEST_DOMAIN="new-guest"
BASE_GUEST_DOMAIN="template-ubuntu-16.04-docker"
BASE_GUEST_DISK="/vms/base-images/ubuntu-16.04.qcow2"
NEW_GUEST_FOLDER="/vms/$NEW_GUEST_DOMAIN"
NEW_GUEST_DISK="`echo $NEW_GUEST_FOLDER`/`echo $NEW_GUEST_DOMAIN`.qcow2"
NEW_GUEST_XML_PATH="`echo $NEW_GUEST_FOLDER`/`echo $NEW_GUEST_DOMAIN`.xml"

# Create a directory for anything related 
# to our guest such as snapshots
mkdir -p $NEW_GUEST_FOLDER

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

# 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 \
--name $NEW_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
sudo rm $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.

References

Author

Programster

Stuart is a software developer with a passion for Linux and open source projects.

comments powered by Disqus