How To

Configure a ZFS Storage Pool in KVM

ZFS brings enterprise-grade storage features to KVM that traditional filesystems cannot match – built-in checksumming, snapshots, compression, and self-healing data are just the starting points. When combined with KVM, ZFS provides a storage backend that handles VM disk images with integrity guarantees that ext4 or XFS simply do not offer. This guide covers installing ZFS on Linux, creating a storage pool and dataset for libvirt, defining the pool in virsh, and attaching ZFS-backed volumes to virtual machines.

Original content from computingforgeeks.com - post 90031

Why Use ZFS for KVM Storage

KVM’s default storage approach uses qcow2 files on a local filesystem. That works, but ZFS adds several capabilities that matter for virtualization:

  • Copy-on-write snapshots are instant and space-efficient – ideal for VM snapshots
  • Data checksumming detects and corrects silent corruption (bit rot)
  • Transparent compression (LZ4 or ZSTD) saves disk space without performance penalties
  • Clones let you create new VMs from snapshots without copying data
  • Send/receive enables replication to remote hosts for disaster recovery

Prerequisites

  • A KVM host running Ubuntu 24.04 or RHEL 10
  • At least one dedicated disk or partition for ZFS (e.g., /dev/sdb)
  • Root or sudo access
  • libvirt and QEMU/KVM already installed

Step 1 – Install ZFS on Linux

Ubuntu 24.04

ZFS is available in the Ubuntu repositories. Install the kernel module and userspace tools.

sudo apt update
sudo apt install -y zfsutils-linux

Verify the ZFS module is loaded.

lsmod | grep zfs
zfs --version

RHEL 10 / AlmaLinux 10 / Rocky Linux 10

On RHEL-based distributions, install ZFS from the official ZFS on Linux repository.

sudo dnf install -y https://zfsonlinux.org/epel/zfs-release-2-4.el10.noarch.rpm
sudo dnf install -y kernel-devel
sudo dnf install -y zfs

Load the ZFS kernel module and enable auto-loading at boot.

sudo modprobe zfs
echo "zfs" | sudo tee /etc/modules-load.d/zfs.conf

Verify the installation.

zfs --version
zpool version

Step 2 – Create a ZFS Pool

Create a ZFS pool using one or more disks. For a single-disk setup (lab or non-critical workloads).

sudo zpool create kvmpool /dev/sdb

For a mirrored setup (recommended for production – survives a single disk failure).

sudo zpool create kvmpool mirror /dev/sdb /dev/sdc

Verify the pool was created.

zpool status kvmpool
zpool list

Expected output shows the pool online with all devices healthy.

Step 3 – Create a ZFS Dataset for libvirt

Create a dedicated dataset within the pool for KVM virtual machine storage. Enable compression and set a reasonable record size for VM workloads.

sudo zfs create kvmpool/libvirt
sudo zfs set compression=lz4 kvmpool/libvirt
sudo zfs set recordsize=64K kvmpool/libvirt

The 64K record size is a good balance for VM disk I/O patterns. LZ4 compression is fast enough that it rarely causes a performance hit and often improves throughput by reducing the amount of data written to disk.

Verify the dataset.

zfs list
zfs get compression,recordsize kvmpool/libvirt

The dataset is automatically mounted at /kvmpool/libvirt. Set the correct ownership for libvirt.

sudo chown libvirt-qemu:kvm /kvmpool/libvirt

Step 4 – Define a libvirt Storage Pool

Define a directory-based storage pool in libvirt that points to the ZFS dataset mount point. While libvirt has a native ZFS pool type, using a directory pool on a ZFS mount is simpler and gives you the same benefits.

virsh pool-define-as zfs-pool dir --target /kvmpool/libvirt

Start the pool and set it to auto-start on boot.

virsh pool-start zfs-pool
virsh pool-autostart zfs-pool

Verify the pool is active.

virsh pool-list --all
virsh pool-info zfs-pool

Step 5 – Create a Volume in the Pool

Create a disk image for a virtual machine within the ZFS-backed pool.

virsh vol-create-as zfs-pool myvm-disk.qcow2 20G --format qcow2

Verify the volume was created.

virsh vol-list zfs-pool
virsh vol-info myvm-disk.qcow2 --pool zfs-pool

You can also verify the file on disk.

ls -lh /kvmpool/libvirt/
qemu-img info /kvmpool/libvirt/myvm-disk.qcow2

Step 6 – Attach the Volume to a VM

When creating a new VM, reference the pool and volume.

virt-install \
  --name myvm \
  --ram 2048 \
  --vcpus 2 \
  --disk vol=zfs-pool/myvm-disk.qcow2,bus=virtio \
  --os-variant ubuntu24.04 \
  --network bridge=br0 \
  --cdrom /kvmpool/libvirt/ubuntu-24.04.iso

For an existing VM, attach the disk with virsh attach-disk.

virsh attach-disk myvm /kvmpool/libvirt/myvm-disk.qcow2 vdb --driver qemu --subdriver qcow2 --persistent

Verify the disk is attached.

virsh domblklist myvm

Taking ZFS Snapshots of VM Disks

One of the biggest advantages of ZFS is instant snapshots. Create a snapshot of the entire libvirt dataset before making changes.

sudo zfs snapshot kvmpool/libvirt@before-upgrade

List snapshots.

zfs list -t snapshot

Roll back to a snapshot if something goes wrong (VM must be shut down first).

virsh shutdown myvm
sudo zfs rollback kvmpool/libvirt@before-upgrade
virsh start myvm

Create a clone from a snapshot to spin up a new VM quickly.

sudo zfs clone kvmpool/libvirt@before-upgrade kvmpool/libvirt-clone

Monitoring ZFS Pool Health

Regularly check pool status for disk errors or degraded states.

zpool status kvmpool
zpool iostat kvmpool 5

Run a scrub periodically to verify data integrity.

sudo zpool scrub kvmpool
zpool status kvmpool

Summary

ZFS provides a storage backend for KVM that goes well beyond what traditional filesystems offer. The combination of checksumming, compression, instant snapshots, and clones makes it a strong choice for both lab environments and production hypervisors. Setting it up is straightforward – install ZFS, create a pool and dataset, define a libvirt storage pool pointing to the ZFS mount, and start creating VM volumes. The snapshot and clone capabilities alone make the setup worthwhile, giving you fast backup and restore options that work at the filesystem level without needing external tools.

Related Articles

KVM Configure KVM Host Networking with systemd-networkd KVM Configure an iSCSI Storage Pool in KVM KVM How To Install KVM Hypervisor on Debian 12/11/10 KVM How To Deploy VM on KVM with Virt-Lightning

Leave a Comment

Press ESC to close