Skip to content
Menu

Virtualization9 min read

Storage & High Availability

Storage backends, ZFS, Ceph, clustering, and automatic failover

Storage Types

Proxmox supports many storage backends. The choice determines whether you get snapshots, thin provisioning, and whether the storage can be shared across cluster nodes.

Type Content Types Shared Snapshots Thin Provision Notes
Directory All (images, ISOs, backups, templates) No (unless NFS-backed) qcow2 only qcow2 only Simplest — just a path on the filesystem
LVM Disk images, CT rootfs No No No Raw block devices, good performance
LVM-thin Disk images, CT rootfs No Yes Yes Thin provisioning via dm-thin — Proxmox default
ZFS (local) All No Yes Yes Feature-rich, RAM-hungry (1 GB per TB rule)
Ceph RBD Disk images Yes Yes Yes Distributed block storage, no SPOF
CephFS All Yes Yes Yes Distributed filesystem, needs MDS
NFS All Yes qcow2 only qcow2 only Simple shared storage over network
iSCSI Disk images Yes No Depends on target Block over TCP/IP — SAN access
GlusterFS All Yes qcow2 only qcow2 only Distributed filesystem (less common now)

Tip

For a single-node setup, LVM-thin or ZFS are the best choices. For clusters needing shared storage, Ceph (built-in to Proxmox) or NFS (external server) are most common.

Disk Formats

raw
  • Simple block image — byte-for-byte disk representation
  • Best performance — no translation overhead
  • No snapshots, no compression, no encryption
  • File size = allocated disk size (no thin provisioning)
  • Used natively by LVM, LVM-thin, Ceph RBD, ZFS zvols
qcow2
  • QEMU Copy-On-Write format v2
  • Backing files — snapshot chains, linked clones
  • Snapshots — internal snapshot support
  • Compression — zlib/zstd per-cluster
  • LUKS encryption — built-in at-rest encryption
  • ~5-10% performance overhead vs raw
  • Used on directory/NFS/GlusterFS storage

Note

On LVM-thin, ZFS, and Ceph, snapshots are handled by the storage layer (not qcow2). These backends use raw format and still get snapshots natively. qcow2 snapshots are only needed on directory-based or NFS storage.

ZFS Basics

What is ZFS?

A combined filesystem + volume manager. Manages disks, RAID, filesystems, snapshots, compression, checksums, and caching in a single integrated stack. Originally from Sun/Solaris, now available on Linux via OpenZFS.

ZFS Architecture

ZFS Pool (zpool)
vdev: mirror
sda
sdb
vdev: mirror
sdc
sdd
SLOG (ZIL)
nvme0n1p1
L2ARC (cache)
nvme0n1p2

RAID Levels (vdev types)

vdev Type Parity Disks Min Disks Tolerated Failures Usable Capacity
mirror N/A (mirroring) 2 N-1 (in the mirror) 50% (2-way mirror)
raidz1 1 3 1 (N-1)/N
raidz2 2 4 2 (N-2)/N
raidz3 3 5 3 (N-3)/N

Key Features

Copy-on-Write (CoW)

Data is never overwritten in place. New blocks are written to free space, then metadata pointers are updated atomically. This makes snapshots instant and free — they just preserve old block pointers.

Checksums

Every block has a checksum stored in its parent block (Merkle tree). Detects silent data corruption (bit rot). With mirrors/raidz, ZFS auto-repairs corrupted blocks.

ARC Cache

Adaptive Replacement Cache — uses available RAM for read caching. Rule of thumb: 1 GB RAM per 1 TB of storage. Can add an L2ARC (SSD) for overflow.

Send/Recv Replication

zfs send streams a snapshot (or incremental delta) to another pool — local or remote. Basis for backup strategies and disaster recovery.

Common ZFS Commands

console
console

    # Create a mirrored pool
    zpool create tank mirror /dev/sda /dev/sdb
    # Create a dataset with compression
    zfs create -o compression=lz4 tank/data
    # Take a snapshot
    zfs snapshot tank/data@2024-01-15
    # List snapshots
    zfs list -t snapshot
NAME                       USED  AVAIL  REFER  MOUNTPOINT
tank/data@2024-01-15       128K      -  1.23G  -
    # Incremental replication to remote host
    zfs send -i tank/data@snap1 tank/data@snap2 | ssh backup zfs recv backup/data
    # Pool status (health, errors, scrub progress)
    zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 01:23:45 with 0 errors
config:
        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0
  

Warning

ZFS is RAM-hungry. The ARC will consume most available RAM by default. For Proxmox, set zfs_arc_max to limit it: echo "options zfs zfs_arc_max=4294967296" > /etc/modprobe.d/zfs.conf (4 GB limit).

Ceph Integration

What is Ceph?

Distributed storage system with no single point of failure. Data is replicated across multiple nodes and disks. Proxmox has first-class Ceph integration — you can deploy and manage Ceph directly from the Proxmox web UI.

Ceph Components

📡
MON (Monitor)
Cluster state, consensus (Paxos). Need 3+ for quorum.
💿
OSD (Object Storage Daemon)
One per disk. Stores data, handles replication, recovery.
📂
MDS (Metadata Server)
Required for CephFS only. Handles POSIX filesystem metadata.
MGR (Manager)
Dashboard, monitoring, module host. Active/standby pair.

Ceph Storage in Proxmox

RBD (RADOS Block Device)

  • Block storage for VM disks and CT rootfs
  • Thin provisioned, snapshots, clones
  • Shared across all cluster nodes — enables live migration
  • Data striped across OSDs, replicated (default 3x)
  • Proxmox creates a pool (e.g., rbd-pool) and adds it as storage

CephFS (Ceph Filesystem)

  • POSIX filesystem for ISOs, backups, templates, snippets
  • Requires at least one MDS daemon
  • Shared across all nodes — all nodes see the same files
  • Good for backup storage (vzdump), ISO library
  • Not recommended for VM disks (use RBD instead)

Self-Healing on OSD Failure

  1. OSD Dies

    Disk failure or node crash

  2. MON Detects

    Heartbeat timeout, OSD marked "down"

  3. Wait Period

    10 min default — allows transient recovery

  4. OSD Marked Out

    CRUSH map updated, data re-replicated to surviving OSDs

  5. Recovery Complete

    All data back to target replication count (3x)

console
console

    # Create Ceph OSDs from Proxmox CLI
    pveceph osd create /dev/sdc
pveceph osd create /dev/sdd
    # Create a Ceph pool
    pveceph pool create vm-pool --pg_autoscale_mode on --size 3 --min_size 2
    # Check Ceph cluster health
    ceph status
  cluster:
    id:     a1b2c3d4-...
    health: HEALTH_OK
  services:
    mon: 3 daemons, quorum pve1,pve2,pve3
    mgr: pve1(active), standbys: pve2
    osd: 12 osds: 12 up, 12 in
  data:
    pools:   2 pools, 128 pgs
    objects: 4.2k objects, 16 GiB
    usage:   52 GiB used, 3.5 TiB / 3.6 TiB avail
  

Clustering

Corosync

Cluster Communication Layer

  • Membership — tracks which nodes are alive (heartbeats)
  • Messaging — reliable multicast/unicast between nodes
  • Quorum — calculates whether the cluster has majority
  • Uses UDP (default port 5405) on a dedicated cluster network
  • Config: /etc/corosync/corosync.conf (auto-managed by Proxmox)

pmxcfs — Proxmox Cluster Filesystem

How /etc/pve/ Works

  • /etc/pve/ is a FUSE mount backed by a local SQLite database
  • The database is replicated in real time via Corosync
  • All nodes see the same configs — VM configs, firewall rules, HA state, user permissions
  • Max file size: 128 KB (it is a config store, not a general filesystem)
  • If a node loses quorum, /etc/pve/ becomes read-only
text
bash

    /etc/pve/
      corosync.conf
      storage.cfg
      user.cfg
      datacenter.cfg
      firewall/
        cluster.fw
      
      nodes/
        pve1/
          qemu-server/100.conf
          lxc/200.conf
        
        pve2/
          qemu-server/101.conf
        
      
      qemu-server/
        100.conf
        101.conf
      
      lxc/
        200.conf
      
    
  

Quorum

Why Quorum Matters

A cluster requires a majority of nodes to agree before making changes. This prevents split-brain — two halves of a partitioned cluster both thinking they are in charge.

Cluster Size Quorum (majority) Max Failures
2 nodes 2 0 (need QDevice for 1-node tolerance)
3 nodes 2 1
4 nodes 3 1
5 nodes 3 2
7 nodes 4 3

Warning

Without quorum: the partition goes read-only. VMs keep running but you cannot start, stop, or migrate them. This is by design — it prevents both halves from modifying the same VM.

Tip

A 2-node cluster has no fault tolerance by default (quorum = 2). Add a QDevice (lightweight third-party voter, e.g., a Raspberry Pi) to achieve 1-node tolerance.

Fencing (STONITH)

Shoot The Other Node In The Head

Before migrating a failed node's VMs, the cluster must guarantee the failed node is truly off. Otherwise, two copies of the same VM could run simultaneously — causing data corruption.

Hardware Fencing

  • IPMI/BMC — remotely power off via out-of-band management
  • HP iLO — Integrated Lights-Out
  • Dell iDRAC — Integrated Dell Remote Access Controller
  • PDU — Smart power distribution unit (cut power to port)
  • Most reliable — works even if OS is hung

Software Fencing (Watchdog)

  • Proxmox default: software watchdog
  • HA manager resets the watchdog timer periodically
  • If the node becomes unresponsive, watchdog fires and reboots the node
  • Hardware watchdog (/dev/watchdog) is more reliable than software
  • Sufficient for many deployments

High Availability

HA Manager

The HA manager continuously monitors HA-managed resources (VMs and CTs). When a node fails, it coordinates fencing and automatic failover.

Failover Sequence

  1. Node Failure Detected

    Corosync stops receiving heartbeats from the failed node. After timeout (typically a few seconds), the node is declared dead.

  2. Remaining Nodes Achieve Quorum

    The surviving nodes verify they still have majority. If quorum is lost (e.g., 1 of 2 nodes), failover does not proceed — safety first.

  3. Failed Node Fenced (STONITH)

    The cluster ensures the failed node is truly powered off. Via IPMI, iLO, iDRAC, or watchdog reboot. This prevents two instances of the same VM from running simultaneously.

  4. HA Manager Identifies Affected Resources

    All VMs and CTs that were running on the failed node and are marked as HA-managed are queued for restart on surviving nodes.

  5. Resources Started on Other Nodes

    VMs/CTs are started on surviving nodes based on HA group preferences and node priority. Requires shared storage (Ceph, NFS, iSCSI) — the disk must be accessible from the new node.

  6. Recovery Complete

    Total failover time: ~2-5 minutes (fence timeout + VM boot time). This is not live migration — VMs are cold-started, so there is downtime.

Note

HA failover is not live migration. The VMs on the failed node crash — they are then cold-booted on a surviving node. Applications inside the VM experience a hard restart. For zero-downtime, you need application-level HA (e.g., database replication, load-balanced web servers).

HA Groups

Controlling Placement

HA groups define which nodes a resource can run on and with what priority.

console
console

    # Create an HA group
    ha-manager groupadd prod-group --nodes pve1:2,pve2:1,pve3:1 --restricted --nofailback
    # pve1 has priority 2 (preferred), pve2 and pve3 have priority 1
    # --restricted: resource can ONLY run on nodes in this group
    # --nofailback: don't auto-migrate back when preferred node recovers
    # Add a VM to HA management
    ha-manager add vm:100 --group prod-group --state started --max_restart 3 --max_relocate 2
  

Recovery Policies

Policy Behavior Use Case
migrate Live migrate to another node (graceful, minimal downtime) Planned maintenance — drain a node before rebooting
relocate Shut down on current node, start on another node (cold move) When live migration is not possible (local storage, incompatible CPUs)
freeze Do not attempt to recover — leave the resource in failed state Resources that should not auto-restart (manual intervention required)

HA State Diagram

disabled
started
stopped
migrate
relocate
freeze
error
console
console

    # Check HA status for all resources
    ha-manager status
quorum OK, master pve1
vm:100  pve1  started
vm:101  pve2  started
ct:200  pve1  started
    # Manually migrate an HA resource
    ha-manager migrate vm:100 pve3
    # Set a resource to freeze (prevent auto-recovery)
    ha-manager set vm:100 --state freeze
  

Tip

For production HA, use at least 3 nodes (for quorum), shared storage (Ceph recommended), and configure hardware fencing (IPMI/iLO/iDRAC) for reliable STONITH.

Solidnines — solidnines.com