Logo

Personal Ops Runbook

Personal runbook covering infrastructure operations for Cloud, Kubernetes, OpenStack, and Ceph environments. Includes deployment and teardown procedures, node management, cluster monitoring setup, and incident response workflows compiled from day-to-day operational work. Intended strictly for personal reference — configurations and scripts are environment-specific and not guaranteed to work as-is elsewhere.

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/BACKUP trong 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,  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ó nopreempt trong config không → nếu có, đây là hành vi đúng thiết kế.
  • Nếu không có nopreempt mà vẫn không preempt: kiểm tra node đó có nhận được advertisement không (mục 4.1), và xem log journalctl -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_master script gọi API (vd aws ec2 assign-private-ip-addresses hoặ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_int lên 2–3s, tăng fall của track_script, hoặc bật nopreempt.

5. Checklist thay đổi config

  1. [ ] Backup config: cp /etc/keepalived/keepalived.conf{,.bak.$(date +%F)}
  2. [ ] Validate cú pháp: keepalived -t -f /etc/keepalived/keepalived.conf
  3. [ ] Thay đổi trên node BACKUP trước, systemctl reload keepalived, quan sát 5 phút
  4. [ ] Failover thủ công sang node vừa sửa (mục 3), xác nhận VIP hoạt động
  5. [ ] Lặp lại trên node còn lại
  6. [ ] 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ông nopreempt
  • 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>