Logo

Build a 2-node Proxmox cluster with ZFS replication

Build a 2-node Proxmox cluster with ZFS replication

Configure a high-availability Proxmox VE cluster on two VeryCloud dedicated servers with near-real-time ZFS replication. Live migration, automatic failover and service continuity included.

Introduction

A Proxmox cluster enables:

  • Live migration: move a VM from one node to another without downtime
  • ZFS replication: sync disks between nodes every minute
  • High Availability (HA): automatically restart VMs on the other node in case of failure

This guide covers a 2-node + QDevice architecture (which acts as an arbiter to avoid split-brain).

Prerequisites

  • 2 VeryCloud dedicated servers with identical Proxmox VE 8.x installed
  • ZFS disks on each node (RAIDZ or mirror recommended)
  • Private network between the two nodes (vRack or VLAN)
  • A third Debian/Ubuntu VPS as QDevice (can be very small, 1 vCPU / 1 GB RAM)
  • Active NTP sync on all nodes

Step 1: Node preparation

On each Proxmox node, configure hostnames and /etc/hosts:

Node 1 (pve01):

hostnamectl set-hostname pve01

Node 2 (pve02):

hostnamectl set-hostname pve02

On both nodes, edit /etc/hosts:

nano /etc/hosts

Add:

10.10.10.1   pve01.local pve01
10.10.10.2   pve02.local pve02

Use the private network IPs (vRack) for internal cluster communication.

Step 2: NTP sync

apt install -y chrony
systemctl enable --now chrony
timedatectl set-timezone Europe/Paris

Check drift:

chronyc tracking

Drift between nodes must be under 1 second.

Step 3: Create the cluster on node 1

On pve01 only:

pvecm create production-cluster --link0 10.10.10.1

--link0 specifies the IP used by Corosync (cluster communication layer).

Check:

pvecm status

You see a cluster with 1 node (pve01).

Step 4: Join node 2 to the cluster

On pve02:

pvecm add pve01 --link0 10.10.10.2

Enter pve01's root password. Sync takes ~30 seconds.

Check on either node:

pvecm status

Must show 2 nodes, status Quorate.

Step 5: Configure a QDevice (arbiter)

With only 2 nodes, in case of a network outage, each node thinks it's alone and risks starting the same VMs simultaneously (split-brain). The QDevice solves this problem.

On your third VPS (Debian/Ubuntu):

apt update
apt install -y corosync-qnetd

On both Proxmox nodes:

apt install -y corosync-qdevice

On pve01:

pvecm qdevice setup QDEVICE_VPS_IP

Enter the QDevice VPS root password. The script configures everything automatically.

Check:

pvecm status

Must show 3 votes total: 2 nodes + 1 QDevice.

Step 6: Create ZFS pools for replication

On each node, create an identical ZFS pool. Example with a 2-disk mirror:

zpool create -f data mirror /dev/sda /dev/sdb
zfs set compression=lz4 data
zfs set atime=off data

Add the pool in Proxmox:

Datacenter → Storage → Add → ZFS

  • ID: data
  • ZFS Pool: data
  • Content: Disk image, Container
  • Nodes: all

Do the same on the other node, with the same ID data.

Step 7: Create a VM and replicate it

Create a VM on pve01 using the data pool for disk (see previous guide for Windows).

Once the VM is created:

VM → Replication → Add:

  • Target: pve02
  • Schedule: */15 (every 15 minutes — adjustable)
  • Comment: Replication to pve02

Click Create. Proxmox takes a ZFS snapshot and transmits it to the other node.

Check:

zfs list -t snapshot data

You see __replicate_* snapshots on both nodes.

Step 8: Live migration

Migrate a VM from one node to another without interruption:

VM → Migrate

  • Target node: pve02
  • Online: checked (live migration)

Migration takes a few seconds to minutes depending on VM RAM. The VM doesn't stop.

Step 9: Configure High Availability (HA)

Datacenter → HA → Resources → Add:

  • VM: select the ID (e.g. 100)
  • Max. restart: 1
  • Max. relocate: 1
  • Group: leave empty or create a group
  • State: started

If pve01 goes down, VM 100 will be automatically started on pve02 (using the last ZFS replication, so with a potential data loss of a few minutes).

Step 10: Failover test

Simulate a pve01 failure:

# On pve01
shutdown -h now

On pve02, monitor:

ha-manager status

After 1-2 minutes, you should see VM 100 automatically restart on pve02.

Once pve01 is rebooted, the VM can be brought back via live migration.

Troubleshooting

"no quorum" after losing a node

The QDevice is not configured or not responding. Check on the QDevice:

systemctl status corosync-qnetd

And on Proxmox nodes:

systemctl status corosync-qdevice

ZFS replication failure

Most common error: ZFS pool with different names between nodes. All names must be identical (e.g. data everywhere).

Inspect logs:

cat /var/log/replicate/100-0.log

Live migration fails

Check that Proxmox VE version and kernel are identical on both nodes:

pveversion
uname -r

Update if needed:

apt update && apt full-upgrade -y

Cluster "two nodes, no quorum" despite QDevice

Restart services:

systemctl restart corosync corosync-qdevice

Useful commands

# Cluster status
pvecm status

# List nodes
pvecm nodes

# HA status
ha-manager status

# Force immediate replication
pvesr run --id 100-0

# List ZFS replication snapshots
zfs list -t snapshot | grep __replicate

# Leave cluster (on the node to remove)
pvecm delnode pve02

# Check Corosync consumption
journalctl -u corosync -n 50

Conclusion

You now have a robust Proxmox cluster, able to withstand a full node failure without significant service loss. This is professional production infrastructure.

Going further:

  • Combine with Proxmox Backup Server for deduplicated incremental backups (see next guide)
  • Add a 3rd node to reach true HA (without QDevice)
  • Use Ceph instead of ZFS for synchronous distributed storage

Resources

Join our Discord community server

For any questions, suggestions, or just to chat with the community, join us on Discord!

900+Members