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
- Proxmox cluster documentation: https://pve.proxmox.com/wiki/Cluster_Manager
- ZFS replication: https://pve.proxmox.com/wiki/Storage_Replication
- High availability: https://pve.proxmox.com/wiki/High_Availability
- QDevice: https://pve.proxmox.com/wiki/Cluster_Manager#_corosync_external_vote_support


















