Pacemaker is a high-availability cluster resource manager that, combined with the Corosync messaging layer, enables automatic failover of services between cluster nodes. When a node or service fails, Pacemaker detects the failure and restarts the affected resources on a surviving node, minimising downtime. This tutorial builds a two-node active/passive HA cluster on RHEL 9, configuring a floating IP and an Apache web server as clustered resources that automatically migrate on failure.
Prerequisites
- Two RHEL 9 servers (
node1at 192.168.1.101 andnode2at 192.168.1.102) with matching hostnames set in/etc/hostson both nodes - Root or sudo access on both nodes
- Passwordless SSH between nodes (for
pcshost authentication via password, SSH is not strictly required) - A spare IP address for the floating VIP (e.g., 192.168.1.200) not assigned to any interface
- Both nodes registered with RHEL subscription or configured with the HA add-on repository
Step 1 — Install Pacemaker, Corosync, and pcs
Run the following commands on both nodes. The pcs package provides a unified command-line interface for managing both Pacemaker and Corosync. The hacluster system user created during installation is used for cluster node authentication.
# Run on BOTH node1 and node2
sudo dnf install -y pacemaker pcs fence-agents-all
# Enable and start the pcsd daemon on both nodes
sudo systemctl enable --now pcsd.service
# Set a password for the hacluster user (use the same password on both nodes)
sudo passwd hacluster
# If firewalld is running, allow the high-availability service
sudo firewall-cmd --permanent --add-service=high-availability
sudo firewall-cmd --reload
Step 2 — Authenticate Cluster Nodes
Run the following from node1 only. The pcs host auth command authenticates node1’s pcs client against the pcsd daemon on each node using the hacluster credentials. After this step, pcs can manage both nodes remotely.
# Run only on node1
sudo pcs host auth node1 node2 -u hacluster
You will be prompted for the hacluster password. A success message of node1: Authorized and node2: Authorized confirms the handshake completed.
Step 3 — Create and Start the Cluster
Still on node1, create the Corosync ring configuration and initialise the cluster. The --start flag starts the cluster services immediately after setup.
# Create the cluster named "mycluster" using both nodes
sudo pcs cluster setup mycluster node1 node2 --start
# Enable the cluster so it starts automatically after reboot
sudo pcs cluster enable --all
# Verify that corosync and pacemaker are running on both nodes
sudo pcs status
The pcs status output initially shows two nodes in the Online state with no resources configured yet. If a node shows OFFLINE, verify that pcsd is running on that node and that port 2224 (pcsd) and 5405 (Corosync UDP) are not blocked by the firewall.
Step 4 — Disable STONITH for a Test Environment
STONITH (Shoot The Other Node In The Head) fencing prevents split-brain scenarios by forcibly powering off a node that the cluster believes has failed. For production this is mandatory; for a two-node lab without dedicated fencing hardware, disable it temporarily so the cluster becomes operational.
# Disable STONITH (for lab/testing only — do NOT do this in production)
sudo pcs property set stonith-enabled=false
# Also disable the quorum policy for a 2-node cluster
sudo pcs property set no-quorum-policy=ignore
# Verify the property was set
sudo pcs property list
Step 5 — Create a Floating IP Resource
A floating (virtual) IP address migrates with the active node. Clients always connect to this VIP regardless of which physical node is currently serving it. The IPaddr2 resource agent manages the IP using standard Linux ip commands.
# Create the floating IP resource
sudo pcs resource create vip
IPaddr2
ip=192.168.1.200
cidr_netmask=24
op monitor interval=30s
# Check that the VIP resource started and is running on one node
sudo pcs status
# Confirm the VIP is visible on the active node's interface
ip addr show
Pacemaker assigns the VIP to one of the cluster nodes. The pcs status output shows which node is currently hosting vip.
Step 6 — Add Apache and Group Resources, Then Test Failover
Group resources ensure that the VIP and Apache are always co-located and start/stop in the correct order. Install Apache on both nodes first, then create the group.
# Install Apache on both nodes
sudo dnf install -y httpd
# Remove the standalone vip resource so we can add it to a group
sudo pcs resource delete vip
# Create the VIP and Apache resources in a single group
sudo pcs resource create vip
IPaddr2 ip=192.168.1.200 cidr_netmask=24
op monitor interval=30s
sudo pcs resource create webserver
apache
configfile=/etc/httpd/conf/httpd.conf
op monitor interval=30s
# Create a resource group: VIP always starts before Apache
sudo pcs resource group add webgroup vip webserver
# View final resource status
sudo pcs status
# Test failover: put the active node in standby
sudo pcs node standby node1
# The VIP and Apache should move to node2 within a few seconds
sudo pcs status
# Bring node1 back online
sudo pcs node unstandby node1
During the failover test, pcs status shows the resources migrating from node1 to node2. Clients connecting to 192.168.1.200 experience only a brief interruption (typically a few seconds) while Pacemaker stops the resources on the standby node and starts them on the surviving node.
Conclusion
You have built a two-node Pacemaker/Corosync HA cluster on RHEL 9, created a floating VIP and Apache resource group, and verified automatic failover by placing a node in standby. For production deployments, re-enable STONITH with an appropriate fencing agent (IPMI, iLO, iDRAC, or a cloud API) to guarantee safe failover under split-brain conditions.
Next steps: How to Configure VLAN Tagging with 802.1Q on RHEL 9, How to Configure BGP Routing with BIRD on RHEL 9, and How to Configure Network Bonding and Teaming on RHEL 9.