Keepalived — High Availability z VRRP
Opublikowano: 10 kwietnia 2026 · Kategoria: Bezpieczeństwo
Jeden serwer to jeden punkt awarii (Single Point of Failure — SPOF). Gdy pada, pada cały serwis. Keepalived rozwiązuje ten problem przez VRRP (Virtual Router Redundancy Protocol): dwa lub więcej serwerów współdzieli jeden wirtualny adres IP, a w razie awarii głównego (MASTER) wirtualne IP automatycznie przechodzi na zapasowy (BACKUP) w ciągu kilku sekund. Klienci nic nie zauważają — łączą się cały czas z tym samym adresem IP.
1. Instalacja Keepalived
# Ubuntu / Debian sudo apt update && sudo apt install keepalived -y # CentOS / Rocky Linux / AlmaLinux sudo dnf install keepalived -y # Uruchom i włącz przy starcie sudo systemctl enable --now keepalived # Sprawdz status sudo systemctl status keepalived
2. Konfiguracja VRRP — Master i Backup
Scenariusz: dwa serwery (192.168.1.10 — MASTER, 192.168.1.11 — BACKUP) z wirtualnym IP 192.168.1.100. Klienci zawsze łączą się z 192.168.1.100 — nie wiedzą który fizyczny serwer aktualnie go trzyma.
# ===== SERWER 1 (MASTER) — /etc/keepalived/keepalived.conf =====
global_defs {
notification_email {
[email protected]
}
router_id LVS_MASTER
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
preempt
authentication {
auth_type PASS
auth_pass TAJNEHASLO123
}
virtual_ipaddress {
192.168.1.100/24 dev eth0
}
notify_master "/etc/keepalived/notify.sh MASTER"
notify_backup "/etc/keepalived/notify.sh BACKUP"
notify_fault "/etc/keepalived/notify.sh FAULT"
}
# ===== SERWER 2 (BACKUP) — /etc/keepalived/keepalived.conf =====
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass TAJNEHASLO123
}
virtual_ipaddress {
192.168.1.100/24 dev eth0
}
} 3. Health checks — monitorowanie usług
Keepalived może nie tylko monitorować dostępność serwera przez VRRP, ale też sprawdzać czy konkretna usługa (Nginx, HAProxy) działa i inicjować failover gdy usługa pada, nawet jeśli serwer fizycznie żyje:
# /etc/keepalived/check_nginx.sh
#!/bin/bash
if ! curl -s -f --max-time 5 http://127.0.0.1/health > /dev/null; then
logger -t keepalived "Nginx health check FAILED"
exit 1
fi
exit 0
chmod +x /etc/keepalived/check_nginx.sh
# W keepalived.conf — vrrp_script do monitorowania nginx
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -50
fall 2
rise 2
}
# W vrrp_instance — dodaj track_script
vrrp_instance VI_1 {
# ... reszta konfiguracji ...
track_script {
chk_nginx
}
} 4. Keepalived z HAProxy — aktywno-pasywny load balancer
# Architektura:
# Klienci -> Wirtualne IP (192.168.1.100)
# -> MASTER: HAProxy (192.168.1.10)
# |-> App Server 1 (192.168.1.20:8080)
# |-> App Server 2 (192.168.1.21:8080)
# (BACKUP: HAProxy 192.168.1.11 — gotowy)
# /etc/haproxy/haproxy.cfg — NA OBU SERWERACH
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/
default_backend http_back
backend http_back
balance roundrobin
option httpchk GET /health
server app1 192.168.1.20:8080 check inter 2s
server app2 192.168.1.21:8080 check inter 2s
# W keepalived.conf — monitoruj HAProxy
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 2
weight -50
fall 3
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
authentication {
auth_type PASS
auth_pass HAPROXY_SECRET
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
chk_haproxy
}
} 5. VRRP Unicast — praca w chmurze bez multicast
# Standardowy VRRP uzywa multicast 224.0.0.18
# W wiekszosci chmur multicast jest zablokowany — uzywaj unicast
vrrp_instance VI_1 {
state MASTER
interface ens3
virtual_router_id 51
priority 100
advert_int 1
# Unicast zamiast multicast
unicast_src_ip 192.168.1.10
unicast_peer {
192.168.1.11
}
authentication {
auth_type PASS
auth_pass SECRET
}
virtual_ipaddress {
192.168.1.100/24
}
}
# Dla Hetzner Cloud — skrypt przenoszacy Floating IP przez API
# /etc/keepalived/hetzner-failover.sh
#!/bin/bash
HETZNER_TOKEN="YOUR_API_TOKEN"
FLOATING_IP_ID="123456"
SERVER_ID="654321"
if [ "$1" == "MASTER" ]; then
curl -s -X POST \
"https://api.hetzner.cloud/v1/floating_ips/${FLOATING_IP_ID}/actions/assign" \
-H "Authorization: Bearer ${HETZNER_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"server\": ${SERVER_ID}}"
fi 6. Monitorowanie i testowanie failover
# Sprawdz czy wirtualne IP jest aktywne na tym serwerze
ip addr show eth0 | grep 192.168.1.100
# Jesli IP pojawia sie w wyniku — ten serwer jest MASTER
# Logi VRRP (zmiany stanu, failovery)
journalctl -u keepalived -f
systemctl status keepalived
# Test failover — zatrzymaj usługe na MASTER
sudo systemctl stop nginx
# Obserwuj na BACKUP: ip addr show (wirtualne IP powinno pojawic sie na BACKUP)
sudo systemctl start nginx # Przywroc usluge
# Skrypt powiadomien — /etc/keepalived/notify.sh
#!/bin/bash
STATE=$1
INSTANCE=$2
PRIORITY=$3
logger -t keepalived "State change: $STATE on $INSTANCE"
# Powiadomienie Discord
curl -s -X POST "https://discord.com/api/webhooks/YOUR_HOOK" \
-H "Content-Type: application/json" \
-d "{\"content\": \"Keepalived: Node przeszedl w stan $STATE\"}" Porównanie rozwiązań High Availability
| Rozwiązanie | Typ HA | Złożoność | Kiedy używać |
|---|---|---|---|
| Keepalived + VRRP | Active/Passive IP failover | Niska | 2 serwery, prosta HA bez load balancingu |
| Keepalived + HAProxy | HA + Load Balancing | Średnia | Produkcja: HA load balancer przed aplikacjami |
| Pacemaker + Corosync | Klaster ogólnego przeznaczenia | Wysoka | Złożone klastry (bazy danych, NFS, SAP) |
| Kubernetes | Container orchestration HA | Bardzo wysoka | Mikroserwisy, skalowanie, GitOps |
| Managed Load Balancer | Chmura (AWS ALB, GCP LB) | Niska (konfiguracja) | Chmura publiczna, brak własnej infrastruktury |