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).
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
- kashyapc.com - Creating Rapid Thin Provisioned Guests Using Qemu Backing Files
- Nixcraft - How to: Ubuntu / Debian Linux Regenerate OpenSSH Host Keys
- Linux Man Page - virt-clone
First published: 16th August 2018