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.