How To

Configure an NFS Storage Pool in KVM

NFS (Network Filesystem) is the go-to shared storage option for KVM environments where you need multiple hypervisors accessing the same VM images. It is the simplest way to enable live migration between KVM hosts, share ISO libraries, and centralize VM storage without investing in SAN infrastructure. This guide covers setting up an NFS server, exporting a directory, configuring the NFS pool in libvirt, creating volumes, and using NFS as shared storage for live migration.

Original content from computingforgeeks.com - post 89996

Why NFS for KVM Storage

NFS has been a reliable choice for shared storage in virtualization for decades. For KVM specifically, it offers several advantages:

  • Simple to deploy – no special hardware or complex protocols required
  • Enables live migration of VMs between KVM hosts without downtime
  • Centralizes VM disk images for easier backup and management
  • Works over standard Ethernet networking
  • Supported natively by libvirt as a storage pool type

Prerequisites

  • An NFS server (can be a dedicated storage server or another Linux machine)
  • One or more KVM hosts running RHEL 10 or Ubuntu 24.04
  • All servers on the same network with reliable connectivity
  • Root or sudo access on all machines
  • Firewall configured to allow NFS traffic (ports 2049, 111)

Step 1 – Set Up the NFS Server

Install the NFS server packages on the machine that will host the shared storage.

Ubuntu 24.04

sudo apt update
sudo apt install -y nfs-kernel-server

RHEL 10

sudo dnf install -y nfs-utils
sudo systemctl enable --now nfs-server

Verify the NFS server is running.

systemctl status nfs-server

Step 2 – Create and Export the Shared Directory

Create a directory that will hold VM disk images and ISO files.

sudo mkdir -p /srv/nfs/kvm
sudo chown nobody:nogroup /srv/nfs/kvm
sudo chmod 755 /srv/nfs/kvm

On RHEL-based systems, use nobody:nobody instead of nobody:nogroup.

sudo chown nobody:nobody /srv/nfs/kvm

Add the export to /etc/exports. This example exports the directory to an entire subnet with read-write access. Adjust the network range to match your environment.

echo "/srv/nfs/kvm 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports

Key export options explained:

  • rw – Read and write access
  • sync – Write data to disk before acknowledging – safer against corruption
  • no_subtree_check – Disables subtree checking for better performance
  • no_root_squash – Allows root on the client to act as root on the NFS share, which libvirt needs to manage VM files

Apply the export configuration.

sudo exportfs -rav

Verify the exports.

sudo exportfs -v

Step 3 – Configure the Firewall on the NFS Server

Open the necessary ports for NFS.

RHEL 10 with firewalld

sudo firewall-cmd --permanent --add-service=nfs
sudo firewall-cmd --permanent --add-service=rpc-bind
sudo firewall-cmd --permanent --add-service=mountd
sudo firewall-cmd --reload

Ubuntu 24.04 with ufw

sudo ufw allow from 192.168.1.0/24 to any port nfs
sudo ufw allow from 192.168.1.0/24 to any port 111

Step 4 – Mount the NFS Share on the KVM Host

On each KVM host, install the NFS client utilities.

# Ubuntu
sudo apt install -y nfs-common

# RHEL
sudo dnf install -y nfs-utils

Test the mount manually first. Replace 192.168.1.50 with your NFS server IP.

sudo mkdir -p /mnt/nfs-kvm
sudo mount -t nfs 192.168.1.50:/srv/nfs/kvm /mnt/nfs-kvm

Verify the mount.

df -hT /mnt/nfs-kvm
mount | grep nfs

Unmount it after testing – libvirt will handle the mounting when you define the pool.

sudo umount /mnt/nfs-kvm

Step 5 – Define the NFS Storage Pool in libvirt

Define an NFS-type storage pool in libvirt. This tells libvirt to mount the NFS share automatically.

virsh pool-define-as nfs-pool netfs \
  --source-host 192.168.1.50 \
  --source-path /srv/nfs/kvm \
  --target /var/lib/libvirt/images/nfs-pool

Start the pool and set it to auto-start.

virsh pool-start nfs-pool
virsh pool-autostart nfs-pool

Verify the pool.

virsh pool-list --all
virsh pool-info nfs-pool

Confirm the mount is active.

df -hT /var/lib/libvirt/images/nfs-pool

Step 6 – Create Volumes on the NFS Pool

Create VM disk images in the NFS-backed pool.

virsh vol-create-as nfs-pool webserver.qcow2 20G --format qcow2
virsh vol-create-as nfs-pool dbserver.qcow2 50G --format qcow2

List volumes in the pool.

virsh vol-list nfs-pool

Check a specific volume.

virsh vol-info webserver.qcow2 --pool nfs-pool

Step 7 – Create a VM Using NFS Storage

virt-install \
  --name webserver \
  --ram 4096 \
  --vcpus 2 \
  --disk vol=nfs-pool/webserver.qcow2,bus=virtio \
  --os-variant ubuntu24.04 \
  --network bridge=br0 \
  --cdrom /var/lib/libvirt/images/nfs-pool/ubuntu-24.04.iso

Step 8 – Live Migration with Shared NFS Storage

The primary reason to use NFS for KVM storage is enabling live migration. When both KVM hosts mount the same NFS share, VMs can move between hosts without any disk copying because both hosts access the same files.

Set up the same NFS pool on the second KVM host by repeating Steps 4 and 5 on that host. Both hosts must have the pool defined with the same source path.

Make sure both hosts can SSH to each other without a password (or configure libvirt to use TLS).

ssh-copy-id root@kvm-host2

Perform the live migration from the source host.

virsh migrate --live --persistent --undefinesource \
  webserver qemu+ssh://kvm-host2/system

Verify the VM is running on the destination host.

ssh kvm-host2 "virsh list --all"

The migration happens in-memory since the disk files do not need to be transferred – both hosts already see them on the NFS share. This makes migration fast, typically completing in seconds for VMs with moderate memory usage.

NFS Performance Tuning for KVM

For production KVM environments using NFS, consider these optimizations.

Use NFSv4.2 for better performance and features.

# On the client, specify the NFS version in mount options
# Edit /etc/fstab if mounting manually:
192.168.1.50:/srv/nfs/kvm /var/lib/libvirt/images/nfs-pool nfs4 rw,hard,intr,rsize=1048576,wsize=1048576 0 0

Increase the NFS read and write buffer sizes to 1MB for better throughput with large sequential I/O.

Use a dedicated network interface or VLAN for NFS traffic to avoid competition with VM traffic and management traffic.

Use the hard mount option so NFS operations are retried indefinitely on network issues, rather than returning errors to the VM.

Summary

NFS provides a straightforward path to shared storage for KVM environments. The setup is simple – export a directory from the NFS server, define an NFS pool on each KVM host, and create VM volumes in that pool. The real payoff comes with live migration, where VMs move between hosts seamlessly because both access the same disk images over NFS. For small to mid-size deployments where a full SAN is overkill, NFS delivers the shared storage capabilities you need with minimal complexity. Pair it with a dedicated storage network and proper NFS tuning, and it performs well enough for most production KVM workloads.

Related Articles

KVM Installing VMs on KVM using Virt-builder KVM How to Install Virt-Manager on Linux Systems KVM How To Install KVM Hypervisor on Debian 12/11/10 Virtualization Customize Linux Qcow2 or Raw image with virt-customize

Leave a Comment

Press ESC to close