+
+
svelte
node
cobol
+
+
flask
alpine
+
mysql
influxdb
+
+
+
+
terraform
nuxt
!
+
pandas
toml
+
https
eclipse
+
yaml
bun
+
[]
express
+
ada
vb
xml
+
bash
*
+
+
solid
+
+
+
grafana
matplotlib
+
solidity
+
mint
+
+
js
+
surrealdb
alpine
+
solid
+
jest
+
keras
+
+
pandas
+
+
termux
+
centos
oauth
next
+
hack
+
htmx
couchdb
+
+
hapi
bsd
backbone
+
+
jwt
+
+
+
Back to Blog
Setting Up High Availability Cluster with Pacemaker on AlmaLinux 🔄
almalinux pacemaker high-availability

Setting Up High Availability Cluster with Pacemaker on AlmaLinux 🔄

Published Jul 15, 2025

Build an enterprise-grade high availability cluster using Pacemaker and Corosync on AlmaLinux 9. Master cluster configuration, resource management, fencing, and implement highly available services with automatic failover.

5 min read
0 views
Table of Contents

High availability (HA) is critical for business-critical applications where downtime translates directly to lost revenue and damaged reputation. This comprehensive guide walks you through building a production-ready high availability cluster using Pacemaker and Corosync on AlmaLinux 9, covering everything from basic concepts to advanced configurations including shared storage, database clustering, and application failover.

🌟 Understanding High Availability Clustering

High availability clustering ensures that services remain accessible even when individual servers fail. By automatically detecting failures and migrating services to healthy nodes, HA clusters deliver the uptime that modern businesses demand.

Key HA Concepts

  • Active/Passive - One node serves requests while others stand by 🔄
  • Active/Active - All nodes serve requests simultaneously ⚡
  • Failover - Automatic service migration during failures 🚀
  • Fencing - Isolating failed nodes to prevent data corruption 🔒
  • Quorum - Majority voting to prevent split-brain scenarios 🗳️

📋 Prerequisites and Architecture

Hardware Requirements

# Minimum Requirements (per node)
- CPU: 2 cores (4+ recommended)
- RAM: 4 GB (8 GB+ recommended)
- Storage: 50 GB system disk
- Network: 2 NICs (cluster + management)

# Recommended 3-node cluster setup
- node1.example.com: 192.168.1.10 (management), 10.0.0.10 (cluster)
- node2.example.com: 192.168.1.11 (management), 10.0.0.11 (cluster)
- node3.example.com: 192.168.1.12 (management), 10.0.0.12 (cluster)

Network Architecture

# Network Layout
- Management Network: 192.168.1.0/24 (SSH, monitoring)
- Cluster Network: 10.0.0.0/24 (Corosync heartbeat)
- Storage Network: 10.1.0.0/24 (iSCSI/NFS - optional)
- Virtual IPs: 192.168.1.100-110 (service IPs)

🔧 Preparing AlmaLinux 9 Nodes

System Preparation (All Nodes)

# Update system
sudo dnf update -y

# Install essential packages
sudo dnf install -y \
  vim \
  net-tools \
  wget \
  curl \
  chrony \
  firewalld \
  policycoreutils-python-utils

# Set hostname (on each node)
sudo hostnamectl set-hostname node1.example.com  # Adjust for each node

# Configure /etc/hosts (on all nodes)
cat << EOF | sudo tee -a /etc/hosts
# Cluster nodes
192.168.1.10  node1.example.com node1
192.168.1.11  node2.example.com node2
192.168.1.12  node3.example.com node3

# Cluster heartbeat network
10.0.0.10  node1-hb
10.0.0.11  node2-hb
10.0.0.12  node3-hb
EOF

Time Synchronization

# Configure Chrony for time sync
sudo systemctl enable --now chronyd

# Configure Chrony
sudo tee /etc/chrony.conf << EOF
# Use public NTP servers
pool 2.pool.ntp.org iburst

# Allow NTP client access from local network
allow 192.168.1.0/24
allow 10.0.0.0/24

# Specify file for drift
driftfile /var/lib/chrony/drift

# Log files
logdir /var/log/chrony
EOF

sudo systemctl restart chronyd

# Verify time sync
chronyc sources
chronyc tracking

SELinux Configuration

# Keep SELinux enforcing but configure for HA
sudo dnf install -y policycoreutils-python-utils

# Set SELinux booleans for cluster
sudo setsebool -P daemons_enable_cluster_mode on
sudo setsebool -P haproxy_connect_any on

# Allow cluster services through SELinux
sudo semanage permissive -a corosync_t
sudo semanage permissive -a pacemaker_t

Firewall Configuration

# Configure firewall for HA services
# Pacemaker/Corosync
sudo firewall-cmd --permanent --add-service=high-availability

# If using specific ports
sudo firewall-cmd --permanent --add-port=2224/tcp  # pcsd Web UI
sudo firewall-cmd --permanent --add-port=3121/tcp  # Pacemaker
sudo firewall-cmd --permanent --add-port=5403/tcp  # Corosync-qnetd
sudo firewall-cmd --permanent --add-port=5404-5412/udp  # Corosync
sudo firewall-cmd --permanent --add-port=21064/tcp  # DLM

# Management services
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=https

# Reload firewall
sudo firewall-cmd --reload

🏗️ Installing Pacemaker and Corosync

Install HA Packages (All Nodes)

# Enable HA repository
sudo dnf config-manager --set-enabled ha

# Install Pacemaker stack
sudo dnf install -y \
  pacemaker \
  corosync \
  pcs \
  fence-agents-all \
  resource-agents \
  psmisc \
  policycoreutils-python-utils

# Enable and start pcsd
sudo systemctl enable --now pcsd

# Set password for hacluster user
echo "StrongPassword123!" | sudo passwd --stdin hacluster

Initial Cluster Setup

# Authenticate nodes (from node1)
sudo pcs host auth node1 node2 node3 -u hacluster -p StrongPassword123!

# Create cluster
sudo pcs cluster setup hacluster \
  node1 addr=10.0.0.10 \
  node2 addr=10.0.0.11 \
  node3 addr=10.0.0.12 \
  --transport knet \
  --force

# Start cluster
sudo pcs cluster start --all

# Enable cluster autostart
sudo pcs cluster enable --all

# Verify cluster status
sudo pcs cluster status
sudo pcs status

🔒 Configuring Cluster Properties

Basic Cluster Configuration

# Set cluster properties
sudo pcs property set stonith-enabled=false  # Temporary, we'll configure later
sudo pcs property set no-quorum-policy=stop
sudo pcs property set default-resource-stickiness=100
sudo pcs property set symmetric-cluster=true
sudo pcs property set cluster-recheck-interval=60s

# Configure resource defaults
sudo pcs resource defaults update resource-stickiness=100
sudo pcs resource defaults update failure-timeout=60s
sudo pcs resource defaults update migration-threshold=3

# Set operation defaults
sudo pcs resource op defaults update timeout=60s
sudo pcs resource op defaults update interval=30s

Corosync Configuration

# View current corosync config
sudo cat /etc/corosync/corosync.conf

# Configure corosync for dual-ring (if using two networks)
sudo pcs cluster config update \
  transport knet \
  link linknumber=0 \
  link linknumber=1

# Set link priorities
sudo pcs cluster link update 0 priority=255
sudo pcs cluster link update 1 priority=100

# Configure encryption
sudo pcs cluster authkey corosync /etc/corosync/authkey

💾 Shared Storage Configuration

iSCSI Shared Storage

# On storage server (separate machine)
# Install iSCSI target
sudo dnf install -y targetcli

# Create iSCSI target
sudo targetcli << EOF
/backstores/fileio create disk01 /var/lib/iscsi_disks/disk01.img 20G
/iscsi create iqn.2025-07.com.example:storage
/iscsi/iqn.2025-07.com.example:storage/tpg1/luns create /backstores/fileio/disk01
/iscsi/iqn.2025-07.com.example:storage/tpg1/acls create iqn.2025-07.com.example:node1
/iscsi/iqn.2025-07.com.example:storage/tpg1/acls create iqn.2025-07.com.example:node2
/iscsi/iqn.2025-07.com.example:storage/tpg1/acls create iqn.2025-07.com.example:node3
exit
EOF

# On cluster nodes
# Install iSCSI initiator
sudo dnf install -y iscsi-initiator-utils

# Set initiator name (unique per node)
echo "InitiatorName=iqn.2025-07.com.example:node1" | sudo tee /etc/iscsi/initiatorname.iscsi

# Discover and login to target
sudo iscsiadm -m discovery -t sendtargets -p storage.example.com
sudo iscsiadm -m node --login

# Configure multipath (optional but recommended)
sudo dnf install -y device-mapper-multipath
sudo mpathconf --enable --with_multipathd y
sudo systemctl enable --now multipathd

GFS2 Clustered Filesystem

# Install GFS2 packages
sudo dnf install -y gfs2-utils dlm

# Create clustered LVM
sudo pvcreate /dev/sdb  # Shared iSCSI disk
sudo vgcreate --clustered y shared_vg /dev/sdb
sudo lvcreate -L 10G -n shared_lv shared_vg

# Format as GFS2
sudo mkfs.gfs2 -p lock_dlm -t hacluster:shared -j 3 /dev/shared_vg/shared_lv

# Create DLM resource
sudo pcs resource create dlm systemd:dlm op monitor interval=30s clone

# Create CLVM resource
sudo pcs resource create clvmd systemd:lvm2-clvmd \
  op monitor interval=30s \
  clone interleave=true ordered=true

# Create GFS2 filesystem resource
sudo pcs resource create shared_fs Filesystem \
  device="/dev/shared_vg/shared_lv" \
  directory="/shared" \
  fstype="gfs2" \
  options="noatime" \
  op monitor interval=10s \
  clone interleave=true

# Set ordering constraints
sudo pcs constraint order start dlm-clone then clvmd-clone
sudo pcs constraint order start clvmd-clone then shared_fs-clone
sudo pcs constraint colocation add shared_fs-clone with clvmd-clone
sudo pcs constraint colocation add clvmd-clone with dlm-clone

🌐 Virtual IP Configuration

Basic Virtual IP Resource

# Create Virtual IP resource
sudo pcs resource create VirtualIP IPaddr2 \
  ip=192.168.1.100 \
  cidr_netmask=24 \
  nic=eth0 \
  op monitor interval=10s

# Verify VIP
ip addr show | grep 192.168.1.100
sudo pcs resource status VirtualIP

Multiple Virtual IPs with Groups

# Create resource group for web services
sudo pcs resource group add web-services

# Add multiple VIPs to group
sudo pcs resource create web-vip1 IPaddr2 \
  ip=192.168.1.101 \
  cidr_netmask=24 \
  --group web-services

sudo pcs resource create web-vip2 IPaddr2 \
  ip=192.168.1.102 \
  cidr_netmask=24 \
  --group web-services

# Configure group properties
sudo pcs resource meta web-services \
  migration-threshold=3 \
  failure-timeout=60s

🌐 Web Server High Availability

Apache/Nginx HA Configuration

# Install Apache on all nodes
sudo dnf install -y httpd

# Create shared content directory
sudo mkdir -p /shared/www/html
echo "<h1>HA Cluster Website</h1>" | sudo tee /shared/www/html/index.html

# Configure Apache to use shared storage
sudo tee /etc/httpd/conf.d/ha-site.conf << 'EOF'
<VirtualHost *:80>
    ServerName ha.example.com
    DocumentRoot /shared/www/html
    
    <Directory /shared/www/html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    ErrorLog /var/log/httpd/ha-error.log
    CustomLog /var/log/httpd/ha-access.log combined
</VirtualHost>
EOF

# Create Apache resource
sudo pcs resource create WebServer apache \
  configfile="/etc/httpd/conf/httpd.conf" \
  statusurl="http://localhost/server-status" \
  op monitor interval=20s timeout=10s

# Add to web-services group
sudo pcs resource group add web-services WebServer

HAProxy Load Balancer

# Install HAProxy
sudo dnf install -y haproxy

# Configure HAProxy for HA
sudo tee /etc/haproxy/haproxy.cfg << 'EOF'
global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/lib/haproxy/stats

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option                  http-server-close
    option                  forwardfor except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

frontend web_frontend
    bind *:80
    bind *:443 ssl crt /etc/ssl/certs/haproxy.pem
    redirect scheme https if !{ ssl_fc }
    default_backend web_backend

backend web_backend
    balance roundrobin
    option httpchk GET /health
    server web1 192.168.1.20:80 check
    server web2 192.168.1.21:80 check
    server web3 192.168.1.22:80 check

listen stats
    bind *:8080
    stats enable
    stats uri /stats
    stats realm HAProxy\ Statistics
    stats auth admin:password
EOF

# Create HAProxy resource
sudo pcs resource create HAProxy systemd:haproxy \
  op monitor interval=10s \
  --group web-services

🗄️ Database High Availability

MariaDB Galera Cluster

# Install MariaDB on all nodes
sudo dnf install -y mariadb mariadb-server-galera mariadb-server

# Configure Galera (on all nodes)
sudo tee /etc/my.cnf.d/galera.cnf << 'EOF'
[mysqld]
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

# Galera Provider Configuration
wsrep_on=ON
wsrep_provider=/usr/lib64/galera-4/libgalera_smm.so

# Galera Cluster Configuration
wsrep_cluster_name="galera_cluster"
wsrep_cluster_address="gcomm://10.0.0.10,10.0.0.11,10.0.0.12"

# Galera Synchronization Configuration
wsrep_sst_method=rsync

# Galera Node Configuration
wsrep_node_address="10.0.0.10"  # Change per node
wsrep_node_name="node1"         # Change per node
EOF

# Bootstrap Galera cluster (on node1 only)
sudo galera_new_cluster

# Start MariaDB on other nodes
sudo systemctl start mariadb  # on node2 and node3

# Verify cluster status
mysql -u root -e "SHOW STATUS LIKE 'wsrep_cluster_size';"

# Create Galera resource in Pacemaker
sudo pcs resource create galera galera \
  wsrep_cluster_address="gcomm://node1,node2,node3" \
  enable_creation=true \
  wsrep_cluster_name="galera_cluster" \
  op promote interval=0s timeout=60s \
  op monitor interval=10s timeout=30s \
  master meta master-max=3 --force

PostgreSQL with Streaming Replication

# Install PostgreSQL
sudo dnf install -y postgresql postgresql-server postgresql-contrib

# Create PostgreSQL resource
sudo pcs resource create PostgreSQL pgsql \
  pgctl="/usr/bin/pg_ctl" \
  psql="/usr/bin/psql" \
  pgdata="/var/lib/pgsql/data" \
  rep_mode="sync" \
  node_list="node1 node2 node3" \
  restore_command='cp /var/lib/pgsql/pg_archive/%f %p' \
  primary_conninfo_opt="keepalives_idle=60 keepalives_interval=5 keepalives_count=5" \
  master_ip="192.168.1.103" \
  restart_on_promote="true" \
  op start timeout=60s \
  op stop timeout=60s \
  op promote timeout=60s \
  op monitor interval=10s timeout=60s \
  master notify=true

# Create VIP for PostgreSQL
sudo pcs resource create postgres-vip IPaddr2 \
  ip=192.168.1.103 \
  cidr_netmask=24

# Configure master-slave constraint
sudo pcs constraint colocation add postgres-vip with PostgreSQL-master INFINITY
sudo pcs constraint order promote PostgreSQL-master then start postgres-vip

⚡ Fencing (STONITH) Configuration

IPMI Fencing

# Install fence agents
sudo dnf install -y fence-agents-ipmilan

# Create IPMI fence devices
sudo pcs stonith create fence_node1 fence_ipmilan \
  ip="192.168.1.210" \
  username="admin" \
  password="password" \
  lanplus=1 \
  pcmk_host_list="node1"

sudo pcs stonith create fence_node2 fence_ipmilan \
  ip="192.168.1.211" \
  username="admin" \
  password="password" \
  lanplus=1 \
  pcmk_host_list="node2"

sudo pcs stonith create fence_node3 fence_ipmilan \
  ip="192.168.1.212" \
  username="admin" \
  password="password" \
  lanplus=1 \
  pcmk_host_list="node3"

# Configure fencing topology
sudo pcs stonith level add 1 node1 fence_node1
sudo pcs stonith level add 1 node2 fence_node2
sudo pcs stonith level add 1 node3 fence_node3

# Enable STONITH
sudo pcs property set stonith-enabled=true
sudo pcs property set stonith-timeout=60s

SBD (Storage-Based Death) Fencing

# Install SBD
sudo dnf install -y sbd

# Create SBD device (on shared storage)
sudo sbd -d /dev/sdb1 create

# Configure SBD on all nodes
sudo tee /etc/sysconfig/sbd << 'EOF'
SBD_DEVICE="/dev/sdb1"
SBD_DELAY_START=no
SBD_OPTS="-W"
SBD_PACEMAKER=yes
SBD_STARTMODE=always
EOF

# Enable SBD
sudo systemctl enable sbd

# Create SBD STONITH resource
sudo pcs stonith create sbd-fence stonith:external/sbd \
  pcmk_delay_max=30s

📊 Monitoring and Management

Cluster Monitoring Setup

# Install monitoring tools
sudo dnf install -y pcs-snmp pacemaker-cts resource-agents-paf

# Configure SNMP monitoring
sudo tee /etc/snmp/snmpd.conf << 'EOF'
rocommunity public 192.168.1.0/24
syslocation "HA Datacenter"
syscontact [email protected]

# Pacemaker MIB
dlmod pacemakerMIB /usr/lib64/snmp/dlmodules/libpacemakerMIB.so
EOF

sudo systemctl enable --now snmpd

# Create monitoring resources
sudo pcs resource create cluster-mon ClusterMon \
  user=root \
  update=30 \
  extra_options="-E /usr/local/bin/cluster-alert.sh" \
  clone

Custom Monitoring Scripts

# Create cluster monitoring script
sudo tee /usr/local/bin/cluster-monitor.sh << 'EOF'
#!/bin/bash

# Cluster health check
LOGFILE="/var/log/cluster-health.log"
ALERTMAIL="[email protected]"

log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOGFILE
}

# Check cluster status
if ! pcs cluster status > /dev/null 2>&1; then
    log_message "ERROR: Cluster is not running"
    echo "Cluster emergency on $(hostname)" | mail -s "Cluster Alert" $ALERTMAIL
    exit 1
fi

# Check for failed resources
FAILED=$(pcs resource status | grep -c "FAILED")
if [ $FAILED -gt 0 ]; then
    log_message "WARNING: $FAILED failed resources detected"
    pcs resource status | mail -s "Failed Resources Alert" $ALERTMAIL
fi

# Check node status
OFFLINE=$(pcs status nodes | grep -c "Offline")
if [ $OFFLINE -gt 0 ]; then
    log_message "WARNING: $OFFLINE nodes offline"
    pcs status nodes | mail -s "Node Offline Alert" $ALERTMAIL
fi

# Check quorum
if ! pcs quorum status | grep -q "Quorate: Yes"; then
    log_message "CRITICAL: Cluster has lost quorum"
    echo "Cluster has lost quorum!" | mail -s "Quorum Lost Alert" $ALERTMAIL
fi

log_message "Health check completed"
EOF

sudo chmod +x /usr/local/bin/cluster-monitor.sh

# Add to crontab
echo "*/5 * * * * /usr/local/bin/cluster-monitor.sh" | sudo crontab -

Web-based Management

# Access pcsd web interface
# https://node1:2224
# Username: hacluster
# Password: [password set earlier]

# Install Hawk2 (alternative web interface)
sudo dnf install -y hawk2

# Configure Hawk2
sudo systemctl enable --now hawk

# Access Hawk2
# https://node1:7630

🔧 Advanced Configuration

Resource Constraints

# Location constraints (prefer specific nodes)
sudo pcs constraint location WebServer prefers node1=100
sudo pcs constraint location WebServer avoids node3=INFINITY

# Colocation constraints (keep resources together)
sudo pcs constraint colocation add WebServer with VirtualIP INFINITY

# Ordering constraints (start order)
sudo pcs constraint order VirtualIP then WebServer

# Resource sets for complex constraints
sudo pcs constraint colocation set \
  VirtualIP WebServer HAProxy \
  sequential=true setoptions score=INFINITY

Resource Migration

# Manual resource migration
sudo pcs resource move WebServer node2

# Clear migration constraints
sudo pcs resource clear WebServer

# Disable/enable resources
sudo pcs resource disable WebServer
sudo pcs resource enable WebServer

# Maintenance mode
sudo pcs node maintenance node1  # Put node in maintenance
sudo pcs node unmaintenance node1  # Remove from maintenance

Cluster Maintenance

# Put cluster in maintenance mode
sudo pcs property set maintenance-mode=true

# Perform maintenance tasks...

# Exit maintenance mode
sudo pcs property set maintenance-mode=false

# Backup cluster configuration
sudo pcs config backup cluster-backup

# Restore cluster configuration
sudo pcs config restore cluster-backup.tar.bz2

🚨 Troubleshooting

Common Issues and Solutions

# Check cluster logs
sudo journalctl -u corosync -u pacemaker -f
sudo tail -f /var/log/cluster/corosync.log

# Verify cluster communication
sudo corosync-cfgtool -s
sudo corosync-cmapctl | grep members

# Check for configuration errors
sudo crm_verify -L -V

# Resource debugging
sudo pcs resource debug-start WebServer --full

# Clear resource failures
sudo pcs resource cleanup WebServer

# Force resource restart
sudo pcs resource restart WebServer

Split-Brain Recovery

# Identify split-brain situation
sudo pcs status nodes
sudo corosync-quorumtool

# On the node to keep:
sudo pcs cluster stop --all
sudo pcs cluster start --all

# Force quorum on single node (emergency only)
sudo pcs quorum unblock

Performance Tuning

# Adjust token timeout for slow networks
sudo pcs cluster config update totem token=5000

# Optimize resource monitoring
sudo pcs resource op defaults update interval=60s

# Tune Pacemaker for large clusters
sudo pcs property set batch-limit=30
sudo pcs property set migration-limit=5

🎯 Best Practices

HA Design Principles

  1. Redundancy at Every Level

    • ✅ Multiple network paths
    • ✅ Redundant power supplies
    • ✅ RAID storage
    • ✅ Multiple cluster nodes
    • ✅ Geographic distribution
  2. Regular Testing

    • ✅ Failover testing
    • ✅ Disaster recovery drills
    • ✅ Load testing
    • ✅ Security audits
    • ✅ Backup verification
  3. Monitoring and Alerting

    • ✅ Real-time monitoring
    • ✅ Predictive analytics
    • ✅ Automated alerting
    • ✅ Trend analysis
    • ✅ Capacity planning
  4. Documentation

    • ✅ Architecture diagrams
    • ✅ Runbooks
    • ✅ Change procedures
    • ✅ Recovery procedures
    • ✅ Contact information

Security Considerations

# Secure cluster communication
sudo pcs cluster authkey --force

# Configure firewall zones
sudo firewall-cmd --new-zone=cluster --permanent
sudo firewall-cmd --zone=cluster --add-source=10.0.0.0/24 --permanent
sudo firewall-cmd --zone=cluster --add-service=high-availability --permanent

# Enable cluster communication encryption
sudo pcs cluster config update totem crypto_cipher=aes256 crypto_hash=sha256

# Audit cluster changes
sudo auditctl -w /var/lib/pacemaker/cib -p wa -k cluster_changes

📚 Advanced Topics

Geo-Clustering

# Install booth for geo-clustering
sudo dnf install -y booth booth-site booth-arbitrator

# Configure booth ticket manager
sudo tee /etc/booth/booth.conf << 'EOF'
transport = UDP
port = 9929

site = 192.168.1.10
site = 192.168.2.10
arbitrator = 192.168.3.10

ticket = "service-a"
  expire = 600
  timeout = 60
  retries = 5
  weights = "node1=100,node2=100"
EOF

# Create booth resources
sudo pcs resource create booth-ip IPaddr2 ip=192.168.1.110
sudo pcs resource create booth-site booth-site \
  config=/etc/booth/booth.conf \
  op monitor interval=10s

# Configure geo-constraints
sudo pcs constraint ticket add service-a WebServer

Containerized Workloads

# Create Podman container resource
sudo pcs resource create web-container podman \
  image=docker.io/nginx:latest \
  name=ha-nginx \
  run_opts="--net=host -v /shared/www:/usr/share/nginx/html:ro" \
  op monitor interval=30s

# Docker Swarm integration
sudo pcs resource create docker-swarm systemd:docker \
  op monitor interval=30s \
  clone interleave=true

🌐 Resources and Next Steps

Learning Path

  1. Linux HA Fundamentals - Understanding clustering concepts
  2. Pacemaker Deep Dive - Advanced resource management
  3. Corosync Internals - Cluster communication
  4. Disaster Recovery - Backup and recovery strategies
  5. Performance Optimization - Scaling and tuning

Useful Resources


Building a high availability cluster with Pacemaker on AlmaLinux 9 provides enterprise-grade reliability for critical services. From basic failover to complex multi-site deployments, the flexibility of Pacemaker allows you to design solutions that meet your specific availability requirements. Remember that high availability is not just about technology – it requires careful planning, regular testing, and ongoing maintenance. Start small, test thoroughly, and gradually build your HA expertise. Stay available! 🔄