Understanding Keepalived: Architecture, Components, and Deployment Guide
Overview
Keepalived is an open-source software solution designed to provide high availability and load balancing for Linux-based systems. The application monitors services and servers, automatically failing over when primary resources become unavailable. This capability ensures continuous service delivery for critical infrastructure components.
Key Features
High Availability
Keepalived implements failover mechanisms that automatically transfer service responsibilities from a failing server to a standby unit. When configured across multiple nodes, the system continuously monitors server health and triggers failover operations when anomalies are detected.
Health Monitoring
The software performs periodic checks on server and service status using multiple verification methods:
- TCP connection tests
- HTTP/HTTPS request validation
- SMTP protocol verification
- Custom script execution
These health checks determine whether a server should remain active or be removed from the service pool.
Load Balancing
Keepalived integrates with the Linux Virtual Server (IPVS) kernel module to distribute client requests across multiple backend servers. This distribution improves overall system performance and provides horizontal scalability.
Virtual IP Address Management
The software manages virtual IP addresses (VIPs) that float between servers based on availability. Clients connect to this shared VIP rather than individual server addresses, enabling seamless failover without client-side reconfiguration.
Configuration Flexibility
Administrators can customize monitoring intervals, failover policies, server weights, notification settings, and authentication parameters to match specific operational requirements.
Architecture
Keepalived consists of several interconnected components that work together to deliver high availability services.
VRRP Protocol Implementation
The Virtual Router Redundancy Protocol (VRRP) forms the core of Keepalived's failover mechanism. Multiple servers share a common virtual IP address, with one node elected as the master to handle traffic while others remain in standby mode. When the master fails, a standby server automatically assumes the VIP and continues service delivery.
Component Structure
Userspace Components:
- VRRP Stack: Handles virtual IP advertisement and election protocols
- Health Checkers: Validates backend server availability through various methods
- System Call Interface: Executes custom scripts during VRRP state transitions
- SMTP Module: Sends email notifications for failover events
- IPVS Wrapper: Generates and manages IPVS load balancing rules
- Network Interface Handler: Manages network interface configurations
- Watchdog Processs: Monitors child processes for responsiveness
Control Plane:
The configuration parser reads and validates the keepalived.conf file, translating user settings into runtime behavior.
I/O Multiplexing Layer:
A custom thread model optimized for network operations handles concurrent connections and event processing.
Memory Management:
Memory allocation, reallocation, and cleanup utilities ensure efficient resource utilization.
Process Model
Keepalived spawns multiple worker processes after version 2.0:
/usr/sbin/keepalived -D
├─ /usr/sbin/keepalived -D (VRRP child)
└─ /usr/sbin/keepalived -D (Health checker child)
File Locations
| Component | Path |
|---|---|
| Package Name | keepalived |
| Binary | /usr/sbin/keepalived |
| Main Config | /etc/keepalived/keepalived.conf |
| Sample Configs | /usr/share/doc/keepalived/ |
| Systemd Unit | /lib/systemd/system/keepalived.service |
| Environment File (RHEL) | /etc/sysconfig/keepalived |
| Environment File (Debian) | /etc/default/keepalived |
Installation
Prerequisites
Before installing Keepalived, ensure the following conditions are met:
- System clocks synchronized across all nodes using ntp or chrony
- Firewall disabled or properly configured for VRRP traffic (multicast to 224.0.0.18)
- SELinux set to permissive mode on RHEL-based systems
- Network connectivity between all cluster nodes
Network Interface Configuration
Rocky Linux 9 and CentOS Stream 9
These distributions use keyfile-based interface naming by default:
ADAPTER=$(ip addr | awk -F'[ :]' '/^2/{print $3}')
nmcli con delete ${ADAPTER}
nmcli connection add type ethernet con-name ${ADAPTER} ifname ${ADAPTER} \
ipv4.method manual ipv4.address "10.0.0.10/24" \
ipv4.gateway "10.0.0.1" \
ipv4.dns "8.8.8.8,1.1.1.1" autoconnect yes
nmcli con reload && nmcli con up ${ADAPTER}
Rocky Linux 8, CentOS Stream 8, and CentOS 7
These versions support traditional interface naming:
# Enable traditional naming via GRUB
sed -ri.bak '/^GRUB_CMDLINE_LINUX=/s@"$&@ net.ifnames=0 biosdevname=0"@' /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
# After reboot, configure the interface
ADAPTER=$(ip addr | awk -F'[ :]' '/^2/{print $3}')
nmcli con delete ${ADAPTER}
nmcli connection add type ethernet con-name ${ADAPTER} ifname ${ADAPTER} \
ipv4.method manual ipv4.address "10.0.0.10/24" \
ipv4.gateway "10.0.0.1" \
ipv4.dns "8.8.8.8,1.1.1.1" autoconnect yes
nmcli con reload && nmcli dev up ${ADAPTER}
Ubuntu 22.04
Ubuntu uses netplan for network configuration:
cat > /etc/netplan/00-installer-config.yaml <<-EOF
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: no
dhcp6: no
addresses: [10.0.0.10/24]
routes:
- to: default
via: 10.0.0.1
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
EOF
netplan apply
Ubuntu 20.04
cat > /etc/netplan/00-installer-config.yaml <<-EOF
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: no
dhcp6: no
addresses: [10.0.0.10/24]
gateway4: 10.0.0.1
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
EOF
netplan apply
Repository Configuration
Rocky Linux 8/9
MIRROR=mirrors.sjtug.sjtu.edu.cn
sed -i.bak -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://'${MIRROR}'/rocky|g' \
/etc/yum.repos.d/[Rr]ocky*.repo
dnf clean all && dnf makecache
CentOS Stream 9
perl -i -pe 's/^metalink/# metalink/' /etc/yum.repos.d/centos*.repo
perl -i -pe 's|baseurl=.*|baseurl=https://mirrors.aliyun.com/centos-stream/\$releasever-stream/\$basearch/os/|' \
/etc/yum.repos.d/centos*.repo
dnf clean all && dnf makecache
CentOS Stream 8
MIRROR=mirrors.aliyun.com
sed -i.bak -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://mirror.centos.org/$contentdir|baseurl=https://'${MIRROR}'/centos|g' \
/etc/yum.repos.d/CentOS-*.repo
dnf clean all && dnf makecache
CentOS 7
MIRROR=mirrors.aliyun.com
sed -i.bak -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://mirror.centos.org|baseurl=https://'${MIRROR}'|g' \
/etc/yum.repos.d/CentOS-*.repo
yum clean all && yum makecache
Ubuntu
MIRROR=mirrors.aliyun.com
CURRENT_MIRROR=$(sed -rn "s@^deb http://(.*)/ubuntu/? $(lsb_release -cs) main.*@\1@p" /etc/apt/sources.list)
sed -i.bak "s/${CURRENT_MIRROR}/${MIRROR}/g" /etc/apt/sources.list
apt update
Disabling Security Services
# RHEL/CentOS/Rocky - Disable firewall
systemctl disable --now firewalld
# CentOS 7 - Disable NetworkManager if needed
systemctl disable --now NetworkManager
# Ubuntu - Disable ufw
systemctl disable --now ufw
# RHEL-based systems - Disable SELinux
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
Time Zone Configuration
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo 'Asia/Shanghai' > /etc/timezone
# Ubuntu additional settings
cat >> /etc/default/locale <<-EOF
LC_TIME=en_DK.UTF-8
EOF
Package Installation
RHEL-Based Systems (dnf/yum)
dnf -y install keepalived
systemctl enable --now keepalived
After installation on systems using predictable interface names, verify the interface referenced in the configuration matches your actual adapter:
ip addr
# Note the interface name (e.g., ens160)
vim /etc/keepalived/keepalived.conf
# Update the "interface" directive to match your adapter
systemctl restart keepalived
Ubuntu (apt)
apt -y install keepalived
cp /usr/share/doc/keepalived/samples/keepalived.conf.sample /etc/keepalived/keepalived.conf
systemctl enable --now keepalived
Building from Source
Dependency Installation
Rocky Linux 9 and CentOS Stream 9
dnf -y install make gcc ipvsadm autoconf automake openssl-devel \
libnl3-devel iptables-devel ipset file net-snmp-devel \
glib2-devel pcre2-devel libnftnl libmnl systemd-devel
Rocky Linux 8 and CentOS Stream 8
Enable PowerTools repository first:
dnf config-manager --set-enabled powertools
# Or create repository file
cat > /etc/yum.repos.d/PowerTools.repo <<-EOF
[PowerTools]
name=PowerTools
baseurl=https://mirrors.sjtug.sjtu.edu.cn/rocky/\$releasever/PowerTools/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
EOF
dnf -y install make gcc ipvsadm autoconf automake openssl-devel \
libnl3-devel iptables-devel ipset-devel file-devel net-snmp-devel \
glib2-devel pcre2-devel libnftnl-devel libmnl-devel systemd-devel
CentOS 7
yum -y install make gcc libnfnetlink-devel libnfnetlink ipvsadm \
libnl libnl-devel libnl3 libnl3-devel lm_sensors-libs \
net-snmp-agent-libs net-snmp-libs openssl openssl-devel \
automake iproute
Ubuntu 22.04 and 20.04
apt update
apt -y install make gcc ipvsadm build-essential pkg-config \
automake autoconf libipset-dev libnl-3-dev libnl-genl-3-dev \
libssl-dev libxtables-dev libip4tc-dev libip6tc-dev \
libmagic-dev libsnmp-dev libglib2.0-dev libpcre2-dev \
libnftnl-dev libmnl-dev libsystemd-dev
Compilation Process
cd /usr/local/src
wget https://keepalived.org/software/keepalived-2.2.8.tar.gz
tar xvf keepalived-2.2.8.tar.gz
cd keepalived-2.2.8/
# The --disable-fwmark flag prevents iptables rules that may block VIP access
./configure --prefix=/apps/keepalived --disable-fwmark
# Use -j flag for parallel compilation based on CPU count
make -j $(nproc) && make install
Configuration After Source Installation
mkdir -p /etc/keepalived
ADAPTER=$(ip a | awk -F'[: ]' '/^2/{print $3}')
cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived
global_defs {
notification_email {
admin@example.com
ops@example.com
}
notification_email_from keepalived@example.com
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id NODE01
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ${ADAPTER}
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.200 dev ${ADAPTER} label ${ADAPTER}:0
}
}
EOF
systemctl daemon-reload
systemctl enable --now keepalived
Configuration Directives Explained
Global Defs Block:
| Directive | Purpose |
|---|---|
| notification_email | Recipients for failover notifications |
| notification_email_from | Sender address for notifications |
| smtp_server | SMTP server for sending notifications |
| router_id | Unique identifier for this node |
| vrrp_skip_check_adv_addr | Skip comparing advertisements from same router |
| vrrp_garp_interval | Gratuitous ARP message delay (0 = immediate) |
| vrrp_gna_interval | Unsolicited NA message delay |
VRRP Instance Block:
| Directive | Purpose |
|---|---|
| state | Initial state: MASTER or BACKUP |
| interface | Physical interface for VRRP traffic |
| virtual_router_id | Unique ID (0-255) shared across cluster |
| priority | Election priority (higher = more likely to become master) |
| advert_int | Advertisement interval in seconds |
| auth_type | Authentication method (PASS or AH) |
| auth_pass | Shared secret for authentication |
| virtual_ipaddress | VIP addresses to manage |
| track_interface | Monitor additional interfaces for failures |
Verification
systemctl status keepalived
# Verify VIP is bound
ip addr show eth0
# Test VIP reachability
ping 10.0.0.200
# View process tree
ps auxf | grep keepalived
pstree -p $(pgrep keepalived | head -1)
# Check firewall rules (should be empty with --disable-fwmark)
iptables -vnL
Common Issues
Service fails to start after package installation:
The default configuration references interface names that may not exist on your system. Verify the actual interface name with ip addr and update the configuration accordingly.
VIP unreachable:
Without the --disable-fwmark flag during compilation, Keepalived may create iptables rules blocking traffic to the VIP. Either add the flag during compilation or configure proper firewall rules.
CentOS 7 systemctl restart issues:
Some CentOS 7 versions have systemd integration bugs. Use systemctl stop followed by systemctl start instead of restart, or manually terminate processes if needed.