LVM (Logical Volume Manager) is a natural fit for KVM storage because it provides block-level volumes with thin provisioning, snapshots, and easy resizing – all built into the Linux kernel with zero extra software required. Unlike file-based storage where VM disks sit as qcow2 files on a filesystem, LVM gives each VM a dedicated logical volume that maps directly to a block device. This reduces I/O overhead and gives better performance for write-heavy workloads. This guide covers creating an LVM storage pool for KVM, managing volumes with virsh, thin provisioning, and taking snapshots.
Prerequisites
- A KVM host running RHEL 10, AlmaLinux 10, Rocky Linux 10, or Ubuntu 24.04
- LVM2 utilities installed (
lvm2package – installed by default on most distributions) - At least one dedicated disk or partition for the LVM volume group (e.g.,
/dev/sdb) - Root or sudo access
- libvirt and QEMU/KVM already installed
Step 1 – Create LVM Physical Volume and Volume Group
Start by preparing the disk as an LVM physical volume and creating a volume group dedicated to KVM storage.
Initialize the disk as a physical volume.
sudo pvcreate /dev/sdb
Verify the physical volume was created.
sudo pvs
sudo pvdisplay /dev/sdb
Create a volume group named kvm-vg on this physical volume.
sudo vgcreate kvm-vg /dev/sdb
Verify the volume group.
sudo vgs
sudo vgdisplay kvm-vg
The output should show the total size of the volume group and the free space available for allocating logical volumes.
Step 2 – Define the LVM Storage Pool in libvirt
Define a libvirt storage pool of type logical that maps to your LVM volume group.
virsh pool-define-as kvm-lvm logical \
--source-name kvm-vg \
--target /dev/kvm-vg
Start the pool and set it to auto-start at boot.
virsh pool-start kvm-lvm
virsh pool-autostart kvm-lvm
Verify the pool is active.
virsh pool-list --all
Expected output:
Name State Autostart
-------------------------------
kvm-lvm active yes
Get detailed information about the pool.
virsh pool-info kvm-lvm
Step 3 – Create Logical Volumes for VMs
Create a logical volume for a VM using virsh vol-create-as. This allocates a block device from the volume group.
virsh vol-create-as kvm-lvm webserver-disk 20G
Verify the volume.
virsh vol-list kvm-lvm
virsh vol-info webserver-disk --pool kvm-lvm
You can also confirm with standard LVM tools.
sudo lvs kvm-vg
sudo lvdisplay /dev/kvm-vg/webserver-disk
Create additional volumes for more VMs as needed.
virsh vol-create-as kvm-lvm dbserver-disk 50G
virsh vol-create-as kvm-lvm appserver-disk 30G
Step 4 – Attach LVM Volumes to Virtual Machines
When creating a new VM, point virt-install to the logical volume.
virt-install \
--name webserver \
--ram 4096 \
--vcpus 2 \
--disk path=/dev/kvm-vg/webserver-disk,bus=virtio \
--os-variant rhel10 \
--network bridge=br0 \
--cdrom /var/lib/libvirt/images/rhel-10.iso
For an existing VM, attach the volume as an additional disk.
virsh attach-disk webserver /dev/kvm-vg/dbserver-disk vdb \
--driver qemu --subdriver raw --persistent
Verify the disk attachment.
virsh domblklist webserver
Step 5 – Set Up Thin Provisioning with LVM
Thin provisioning allows you to over-commit storage – you can allocate more space to VMs than physically exists, and the actual disk space is consumed only as data is written. This is extremely useful when most VMs do not use their full allocated space.
First, install the thin provisioning tools if not already present.
# Ubuntu
sudo apt install -y thin-provisioning-tools
# RHEL
sudo dnf install -y device-mapper-persistent-data
Create a thin pool within the volume group. Allocate most of the VG space to the thin pool.
sudo lvcreate -L 400G --thinpool kvm-thinpool kvm-vg
Verify the thin pool.
sudo lvs kvm-vg
sudo lvdisplay /dev/kvm-vg/kvm-thinpool
Create thin volumes from the pool. Notice these can collectively exceed the thin pool size.
sudo lvcreate -V 100G --thin -n vm1-disk kvm-vg/kvm-thinpool
sudo lvcreate -V 100G --thin -n vm2-disk kvm-vg/kvm-thinpool
sudo lvcreate -V 100G --thin -n vm3-disk kvm-vg/kvm-thinpool
sudo lvcreate -V 100G --thin -n vm4-disk kvm-vg/kvm-thinpool
sudo lvcreate -V 100G --thin -n vm5-disk kvm-vg/kvm-thinpool
That is 500G of virtual capacity from a 400G thin pool. As long as actual usage stays under 400G, everything works. Monitor thin pool usage regularly.
sudo lvs -o+lv_size,data_percent,pool_lv kvm-vg
Set up monitoring to alert when the thin pool reaches 80% capacity.
sudo lvchange --monitor y kvm-vg/kvm-thinpool
Step 6 – LVM Snapshots for VM Backups
LVM snapshots create a point-in-time copy of a logical volume. They are useful for backups and for testing changes that you might want to roll back.
For standard (thick) logical volumes, create a snapshot with a specified size for storing changes.
sudo lvcreate -s -n webserver-snap -L 5G /dev/kvm-vg/webserver-disk
The -L 5G allocates 5GB for storing the differences between the original and the snapshot. If the snapshot fills up, it becomes invalid, so size it according to expected change volume.
For thin volumes, snapshots are more efficient because they share the thin pool and do not need pre-allocated space.
sudo lvcreate -s -n vm1-snap kvm-vg/vm1-disk
List all snapshots.
sudo lvs -o lv_name,origin,snap_percent kvm-vg
To revert a VM to a snapshot, shut down the VM first, then merge the snapshot back.
virsh shutdown webserver
sudo lvconvert --merge /dev/kvm-vg/webserver-snap
After merging, the snapshot is consumed and the logical volume returns to its snapshot state. Start the VM again.
virsh start webserver
Resizing LVM Volumes
Extending an LVM volume for a VM that needs more space is simple. Shut down the VM, extend the volume, then start the VM back up.
virsh shutdown webserver
sudo lvextend -L +10G /dev/kvm-vg/webserver-disk
virsh start webserver
Inside the VM, extend the filesystem to use the new space. For ext4:
sudo resize2fs /dev/vda1
For XFS:
sudo xfs_growfs /
Deleting Volumes
Remove a volume when a VM is decommissioned.
virsh vol-delete webserver-disk --pool kvm-lvm
Or use LVM directly.
sudo lvremove /dev/kvm-vg/webserver-disk
Summary
LVM storage pools give KVM direct block-device access for VM disks, which translates to better I/O performance compared to file-based storage. The workflow is standard LVM administration – create a volume group, define it as a libvirt pool, and allocate logical volumes for each VM. Thin provisioning lets you over-commit storage efficiently, and LVM snapshots provide a straightforward backup and rollback mechanism. Combined with the ability to resize volumes on-the-fly, LVM remains one of the most practical storage backends for KVM in production environments.