Runbook: Vận hành Keepalived / VRRP (VIP Failover)
Phạm vi: cặp node HA dùng keepalived quản lý VIP (Virtual IP).
Nguyên tắc cốt lõi: priority cao nhất giữ VIP.state MASTER/BACKUPtrong config chỉ là trạng thái khởi đầu, không phải vai trò cố định.
1. Cấu hình chuẩn (baseline)
Node A (dự kiến giữ VIP)
# /etc/keepalived/keepalived.conf
vrrp_script chk_nginx {
script "/usr/bin/pgrep nginx" # exit 0 = OK, khác 0 = fail
interval 2 # chạy mỗi 2s
weight -50 # fail thì trừ 50 priority
fall 3 # fail 3 lần liên tiếp mới tính
rise 2 # OK 2 lần liên tiếp mới hồi
}
vrrp_instance VI_1 {
state BACKUP # khuyến nghị: cả 2 node đều BACKUP, để priority tự quyết
interface eth0
virtual_router_id 51 # PHẢI giống nhau giữa 2 node, và KHÔNG trùng với cụm VRRP khác trên cùng L2
priority 150 # node A cao hơn
advert_int 1
authentication {
auth_type PASS
auth_pass s3cret
}
virtual_ipaddress {
10.0.0.100/24 dev eth0
}
track_script {
chk_nginx
}
notify /etc/keepalived/notify.sh # gửi alert khi đổi state (tùy chọn)
}
Node B
Giống hệt, chỉ khác:
priority 100
Quy ước đội
| Mục | Quy ước |
|---|---|
state |
Cả 2 node dùng BACKUP (tránh 2 node cùng tưởng mình MASTER lúc boot) |
priority |
Node chính 150, node phụ 100. Chênh lệch phải lớn hơn tổng weight của track_script nếu muốn health check kích hoạt failover (150 − 50 = 100 = priority node B → nên để chênh 50 và weight −60, hoặc chênh 60 và weight −50, tránh bằng nhau) |
virtual_router_id |
Duy nhất trên mỗi VLAN/L2 segment. Ghi vào CMDB |
nopreempt |
Chỉ bật khi muốn tránh flapping; yêu cầu cả 2 node state BACKUP |
advert_int |
1s mặc định → failover ~3–4s. Không giảm dưới 1s nếu không có lý do |
2. Kiểm tra trạng thái (health check hằng ngày / trước-sau thay đổi)
# 1. Node nào đang giữ VIP?
ip addr show eth0 | grep 10.0.0.100
# Có dòng inet 10.0.0.100/24 → node này là MASTER
# 2. Trạng thái keepalived
systemctl status keepalived
journalctl -u keepalived -n 50 --no-pager
# 3. Xem state hiện tại (MASTER/BACKUP)
grep -i state /var/run/keepalived* 2>/dev/null || \
journalctl -u keepalived --no-pager | grep -i "entering" | tail -5
# Kỳ vọng: "Entering MASTER STATE" trên đúng 1 node
# 4. Bắt gói VRRP advertisement (chạy trên node BACKUP)
tcpdump -i eth0 -nn vrrp -c 5
# Kỳ vọng: thấy advertisement từ MASTER mỗi 1s, đúng vrid, đúng prio
# 5. Test VIP từ máy ngoài
ping -c 3 10.0.0.100
curl -sI http://10.0.0.100/ | head -1
Trạng thái khỏe mạnh: đúng 1 node có VIP, node còn lại thấy advertisement đều đặn, priority trong advertisement khớp config.
3. Failover thủ công (bảo trì có kế hoạch)
Mục tiêu: đẩy VIP từ node A sang node B để bảo trì A.
# Cách 1 (khuyến nghị): dừng keepalived trên node A
systemctl stop keepalived # trên node A
# → node B mất advertisement sau ~3s, tự lên MASTER, gửi gratuitous ARP
# Xác nhận trên node B:
ip addr show eth0 | grep 10.0.0.100
# Xác nhận từ ngoài:
ping -c 3 10.0.0.100 && arping -c 2 10.0.0.100 # MAC phải là của node B
# Cách 2: hạ priority tạm thời (không dừng service)
# Sửa priority node A xuống thấp hơn B (vd 90), rồi:
systemctl reload keepalived
# Chỉ hiệu quả nếu node B có preempt (mặc định bật)
Khi trả VIP về node A sau bảo trì:
- Nếu preempt bật (mặc định): systemctl start keepalived trên A → A tự giành lại VIP (chấp nhận 1 lần failover nữa, rớt vài giây).
- Nếu nopreempt: VIP ở lại B. Muốn trả về A thì restart keepalived trên B ngoài giờ cao điểm.
⚠️ Thông báo trước cho stakeholder: mỗi lần failover có thể rớt kết nối 1–4 giây; connection TCP đang mở sẽ bị reset trừ khi có conntrack sync (conntrackd).
4. Sự cố thường gặp & xử lý
4.1. Split-brain: cả 2 node cùng giữ VIP
Triệu chứng: ip addr trên cả 2 node đều có VIP; client chập chờn, ARP flapping trên switch.
Nguyên nhân thường gặp: 2 node không thấy advertisement của nhau — firewall chặn VRRP (protocol 112 / multicast 224.0.0.18), VLAN sai, virtual_router_id hoặc auth_pass lệch nhau, switch chặn multicast (IGMP snooping).
Xử lý:
# Trên cả 2 node, kiểm tra có nhận advertisement của nhau không
tcpdump -i eth0 -nn vrrp
# Kiểm tra firewall
iptables -L -n | grep -E "112|vrrp"
# Cần allow: -A INPUT -p vrrp -j ACCEPT (hoặc protocol 112)
# và multicast 224.0.0.18
# So khớp config 2 node
diff <(ssh nodeA cat /etc/keepalived/keepalived.conf) \
<(ssh nodeB cat /etc/keepalived/keepalived.conf)
# vrid, auth_pass, interface, advert_int phải khớp
# Xử lý tạm: dừng keepalived trên node phụ để cắt split-brain ngay
systemctl stop keepalived # trên node B
# rồi mới đi sửa nguyên nhân gốc
4.2. VIP không failover khi service chết
Triệu chứng: nginx/app trên MASTER đã chết nhưng VIP không nhảy sang BACKUP.
Nguyên nhân: track_script không được khai trong track_script {}, script lỗi quyền chạy, hoặc weight không đủ: priority MASTER sau khi trừ weight vẫn ≥ priority BACKUP.
Xử lý:
# Chạy tay script health check, kiểm tra exit code
/usr/bin/pgrep nginx; echo $?
# Xem log keepalived có dòng "Script ... failed" không
journalctl -u keepalived | grep -i script | tail
# Kiểm tra số học: prio_master - weight < prio_backup ?
# VD: 150 - 50 = 100 = prio B → KHÔNG failover (bằng nhau chưa đủ, cần NHỎ HƠN)
# Sửa: weight -60, reload keepalived
4.3. Node priority cao boot lên nhưng không lấy lại VIP
- Kiểm tra có
nopreempttrong config không → nếu có, đây là hành vi đúng thiết kế. - Nếu không có
nopreemptmà vẫn không preempt: kiểm tra node đó có nhận được advertisement không (mục 4.1), và xem logjournalctl -u keepalived | tail -30.
4.4. Failover xong nhưng client vẫn không truy cập được VIP
Nguyên nhân thường gặp: switch/router chưa cập nhật ARP (gratuitous ARP bị chặn), hoặc cloud provider không hỗ trợ VRRP L2 (AWS/GCP/Azure cần dùng API để move IP, không dùng gratuitous ARP được).
# Gửi lại gratuitous ARP thủ công từ node MASTER mới
arping -U -I eth0 -c 5 10.0.0.100
# Kiểm tra ARP table phía client/gateway
arp -n | grep 10.0.0.100 # MAC phải là của MASTER hiện tại
☁️ Trên cloud: dùng
notify_masterscript gọi API (vdaws ec2 assign-private-ip-addresseshoặc reassign ENI/route) thay vì trông chờ ARP.
4.5. VIP flapping (nhảy qua lại liên tục)
- Xem log 2 node:
journalctl -u keepalived | grep -i "entering"— nếu MASTER/BACKUP đổi liên tục → mạng chập chờn hoặc CPU quá tải khiến advertisement trễ. - Giảm nhạy: tăng
advert_intlên 2–3s, tăngfallcủa track_script, hoặc bậtnopreempt.
5. Checklist thay đổi config
- [ ] Backup config:
cp /etc/keepalived/keepalived.conf{,.bak.$(date +%F)} - [ ] Validate cú pháp:
keepalived -t -f /etc/keepalived/keepalived.conf - [ ] Thay đổi trên node BACKUP trước,
systemctl reload keepalived, quan sát 5 phút - [ ] Failover thủ công sang node vừa sửa (mục 3), xác nhận VIP hoạt động
- [ ] Lặp lại trên node còn lại
- [ ] Xác nhận trạng thái cuối: đúng 1 MASTER, log sạch, ghi lại vào change ticket
6. Thông tin cần ghi vào CMDB / tài liệu hệ thống
- VIP, interface,
virtual_router_id, priority từng node, có/khôngnopreempt - Track script làm gì, weight bao nhiêu, ngưỡng số học failover
- RTO kỳ vọng: ~3–4s (advert_int 1s × 3 + ARP)
- Lệnh xác định node đang giữ VIP:
ip a | grep <VIP>