Skip to content

QEMU backing files: An introduction

This tutorial provides a brief introduction to QEMU backing files. We assume that you're already familiar with the basics of QEMU, KVM, and virsh.

A backing file is a read-only base image that a QEMU virtual machine's disk image is linked to. The VM's actual disk (the overlay or delta disk) only stores the differences or changes made relative to the backing file. This creates a parent-child relationship between the images.

Advantages of using backing files

Using a backing file, typically in the qcow2 format, offers significant advantages for managing VMs:

  • Rapid Deployment: Creating a new VM is nearly instantaneous. You only need to create a tiny overlay file that points to the large base image, rather than copying the entire 20-30 GB disk image each time.
  • Storage Efficiency: You can run dozens of VMs from a single "golden image" (the backing file). Only the unique changes for each VM consume additional disk space. This dramatically reduces storage requirements.
  • Template Integrity: The base image remains untouched and pristine. You can easily destroy a test VM and spin up a new, clean one from the same base in seconds, knowing it's in a perfect state.

Example with Debian, KVM, and virsh

Here's a practical workflow for creating a Debian base image and launching a new VM from it.

1. Install the required tools

For this tutorial we will be using tools like virt-sysprep and virt-customize which are provided by the libguestfs-tools package. Install the package if you don't have it.

sudo apt update
sudo apt install libguestfs-tools

2. Create and prepare the backing file ("Golden Image")

First, install a base Debian system as you normally would. Let's say this results in a disk image named debian12-base.qcow2.

After installation, it's critical to generalize this image using virt-sysprep. virt-sysprep can reset or unconfigure a virtual machine so that clones can be made from it. Steps in this process include removing SSH host keys, removing persistent network MAC configuration, and removing user accounts.

Warning

virt-sysprep modifies the guest or disk image in place. The guest must be shut down. If you want to preserve the existing contents of the guest, you must snapshot, copy or clone the disk first.

cd /var/lib/libvirt/images
virt-sysprep -a debian12-base.qcow2

This debian12-base.qcow2 is now your clean backing file.

Warning

A backing file must be treated as read-only and immutable once an overlay image is linked to it. If you need to update a base image, the correct procedure is to create a new, updated base image and then "rebase" the existing overlay images onto the new backing file.

Modifying or deleting a backing image that is in use will result in data corruption or render the virtual machine unusable. Both actions break the dependency chain that the overlay images rely on to function.

Tip

The SSH service will fail to start because the base image does not have any SSH host keys (virt-sysprep removed them). We can configure the base image to generate SSH host keys on the first boot. The perfect tool for this job is virt-customize, which allows you to modify a virtual machine's disk image from the host by running commands inside it while it's offline.

virt-customize -a debian12-base.qcow2 --firstboot-command "dpkg-reconfigure openssh-server"

This ensures that every VM created from this base image has a unique set of SSH host keys.

3. Create a new VM from the backing file

Now, create a new, small overlay image for your new VM, which we'll call web-server-01. For this we can use qemu-img create:

qemu-img create -b debian12-base.qcow2 -F qcow2 -f qcow2 web-server-01.qcow2

This command creates web-server-01.qcow2, which might only be a few kilobytes initially.

4. Launch the new VM

You can now use virt-install to create and launch a new VM using this overlay disk.

virt-install \
--connect qemu:///system \
--import \
--virt-type kvm \
--name "web-server-01" \
--memory "1024" \
--autostart \
--vcpus=1 \
--os-variant=debian12 \
--disk "/var/lib/libvirt/images/web-server-01.qcow2,format=qcow2" \
--network "bridge=br0" \
--noautoconsole \
--hvm

The --import flag tells virt-install that you are providing an existing disk image rather than performing a new OS installation.