High availability (HA) is a fundamental operational requirement for mission-critical infrastructure, such as ingress load balancers, database clusters, and internal API gateways. When a single node crashes or requires routine maintenance, client connections must be transparently preserved without requiring manual DNS records reconfiguration or extended downtime.
Keepalived solves this challenge on Linux by implementing the Virtual Router Redundancy Protocol (VRRP) (RFC 5798). By sharing a floating Virtual IP (VIP) across multiple Ubuntu nodes and evaluating service health via automated monitoring scripts, Keepalived delivers instantaneous sub-second failover.
Architectural Overview: VRRP State Machine and Floating Virtual IPs
Keepalived coordinates two or more clustered nodes to present a single, resilient IP endpoint to the network:
| Component / Protocol | Operational Role | Implementation Details |
|---|---|---|
| VRRP Multicast | Heartbeat & node state coordination | Nodes exchange periodic multicast packets over 224.0.0.18 (IP protocol 112) at 1-second intervals. |
| MASTER Node | Primary traffic handler | Binds the Virtual IP (VIP) to its physical network interface and answers ARP requests. Configured with higher priority (e.g., 101). |
| BACKUP Node | Passive standby handler | Listens for master advertisement packets. Configured with lower priority (e.g., 100). Assumes VIP if master misses three consecutive intervals. |
| Track Scripts | Dynamic health monitoring | Executes local shell scripts to verify underlying daemons (e.g., Nginx or HAProxy). Reduces priority or forces FAULT state upon failure. |
Prerequisites & Kernel sysctl Preparation
Before installing Keepalived, you must configure the Linux kernel to permit network services to bind to an IP address that is not yet locally assigned to an interface (non-local binding). This ensures load balancers like HAProxy or Nginx can start cleanly on standby nodes before a failover occurs.
Execute the following commands on both nodes:
# Enable non-local IP binding in sysctl
sudo bash -c 'cat <<EOF > /etc/sysctl.d/99-keepalived.conf
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
EOF'
# Reload sysctl parameters
sudo sysctl --system
Step-by-Step Configuration Guide
Step 1: Install Keepalived
Update the APT package repository and install Keepalived on both primary (Node 1: 192.168.1.11) and secondary (Node 2: 192.168.1.12) servers:
sudo apt update && sudo apt install -y keepalived
Step 2: Create the Service Health Check Script
Create a script on both servers to monitor the health of your upstream web server or reverse proxy (e.g., Nginx):
sudo bash -c 'cat <<"EOF" > /usr/local/bin/check_nginx.sh
#!/bin/bash
/usr/bin/killall -0 nginx
EOF'
sudo chmod +x /usr/local/bin/check_nginx.sh
Step 3: Configure Keepalived on the Primary Node (MASTER)
Create /etc/keepalived/keepalived.conf on Node 1 (replacing eth0 with your primary network interface name and adjusting subnet IPs):
vrrp_script check_service {
script "/usr/local/bin/check_nginx.sh"
interval 2
weight -20
fall 2
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 101
advert_int 1
authentication {
auth_type PASS
auth_pass Secr3tVrrpPass!
}
virtual_ipaddress {
192.168.1.100/24 dev eth0 label eth0:vip
}
track_script {
check_service
}
}
Step 4: Configure Keepalived on the Secondary Node (BACKUP)
Create /etc/keepalived/keepalived.conf on Node 2 with matching virtual_router_id and authentication, but with lower priority:
vrrp_script check_service {
script "/usr/local/bin/check_nginx.sh"
interval 2
weight -20
fall 2
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass Secr3tVrrpPass!
}
virtual_ipaddress {
192.168.1.100/24 dev eth0 label eth0:vip
}
track_script {
check_service
}
}
Step 5: Allow VRRP Multicast Traffic Through UFW
If Uncomplicated Firewall (UFW) is active, allow VRRP protocol traffic between both cluster nodes:
sudo ufw allow proto vrrp to 224.0.0.18
sudo ufw reload
Step 6: Start and Validate the Keepalived Service
Start and enable the daemon on both nodes:
sudo systemctl enable --now keepalived
Verify that the VIP (192.168.1.100) is active on Node 1:
ip addr show dev eth0
You should see 192.168.1.100/24 scope global secondary eth0:vip bound to the primary node, whilst the backup node maintains only its base IP.
Step 7: Perform Controlled Cutover Testing
- Stop Nginx on the master node:
sudo systemctl stop nginx. - The
check_servicetrack script detects the daemon outage, reducing Node 1’s effective priority to81(101 – 20). - Node 2, with priority
100, immediately claims the VIP. - Run
ip addr show dev eth0on Node 2 to verify that the VIP has migrated instantaneously without dropped TCP connections. - Restart Nginx on Node 1 (
sudo systemctl start nginx); Node 1 reclaims the VIP as priority returns to 101.
Troubleshooting Keepalived and VRRP Deployments
Consult this diagnostic matrix to resolve split-brain incidents and configuration errors:
| Issue / Symptom | Underlying Root Cause | Remediation Procedure |
|---|---|---|
| Split-brain: Both nodes claim the Virtual IP simultaneously. | Firewalls (UFW/iptables) or network switches are blocking VRRP multicast traffic (224.0.0.18 / IP protocol 112). |
Verify network rules allow protocol 112; run tcpdump -nn -i eth0 proto 112 to confirm bi-directional packet receipt. |
| Failover does not trigger when service crashes. | The vrrp_script weight reduction is insufficient to bring the Master priority below the Backup priority. |
Calculate priority margins: ensure priority - weight < backup_priority (e.g., $101 – 20 = 81 < 100$). |
| Keepalived exits with permission denied on script execution. | Keepalived runs scripts under unprivileged user permissions or missing execute bits. | Run chmod +x /usr/local/bin/check_nginx.sh and specify script_user root inside the global Keepalived configuration if required. |
| Frequent flapping between Master and Backup states. | High network jitter or transient CPU spikes causing Keepalived to miss heartbeat intervals. | Increase advert_int to 2 seconds, or configure nopreempt on the master node to prevent automatic failback upon recovery. |
Deploying Keepalived VRRP on Ubuntu Server establishes a resilient, production-grade failover foundation that guarantees continuous service availability across enterprise infrastructure.