Keepalived 高可用配置与故障排查

概述

Keepalived 是一个基于 VRRP(Virtual Router Redundancy Protocol)协议的高可用解决方案,主要用于实现服务器集群的故障转移和负载均衡。它通过监控服务状态并自动切换 VIP(Virtual IP)来保证业务连续性。

核心架构

  • VRRP 协议:主备节点间的心跳检测机制
  • VIP 管理:虚拟 IP 地址在主备节点间的自动漂移
  • 健康检查:支持 TCP、HTTP、SSL、自定义脚本等多种检查方式
  • 多层集成:可与 LVS、Nginx、HAProxy 等负载均衡器深度集成

生产环境配置示例

基础配置文件 (/etc/keepalived/keepalived.conf)

! Configuration File for keepalived

global_defs {
    router_id LVS_DEVEL
    script_user root
    enable_script_security
}

vrrp_script chk_haproxy {
    script "/usr/local/bin/check_haproxy.sh"
    interval 2
    weight -2
    fall 2
    rise 1
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.100/24 dev eth0 label eth0:1
    }
    track_script {
        chk_haproxy
    }
    notify_master "/usr/local/bin/notify.sh master"
    notify_backup "/usr/local/bin/notify.sh backup"
    notify_fault "/usr/local/bin/notify.sh fault"
}

HAProxy 健康检查脚本 (/usr/local/bin/check_haproxy.sh)

#!/bin/bash
# Check if HAProxy is running and responding
if [ $(ps -C haproxy --no-headers | wc -l) -eq 0 ]; then
    exit 1
fi

# Check if HAProxy port is listening
if ! nc -z 127.0.0.1 80; then
    exit 1
fi

# Check HAProxy stats page
if ! curl -s --head http://127.0.0.1:8404/haproxy?stats | grep "200 OK" > /dev/null; then
    exit 1
fi

exit 0

通知脚本 (/usr/local/bin/notify.sh)

#!/bin/bash
# Notify script for Keepalived state changes
STATE=$1

# Log state change
logger "Keepalived state changed to $STATE"

# Send notification via email or webhook
if [ "$STATE" = "MASTER" ]; then
    echo "Keepalived became MASTER on $(hostname)" | mail -s "[ALERT] Keepalived MASTER" admin@example.com
elif [ "$STATE" = "BACKUP" ]; then
    echo "Keepalived became BACKUP on $(hostname)" | mail -s "[INFO] Keepalived BACKUP" admin@example.com
fi

关键参数调优说明

参数 推荐值 说明
priority 主节点:100-150,备节点:90-140 优先级越高越容易成为 MASTER,主备需有足够差距
advert_int 1 VRRP 广告间隔(秒),生产环境建议 1-3 秒
preempt_delay 300 抢占延迟(秒),避免脑裂,建议 300 秒
nopreempt false 是否禁用抢占,默认 false,主恢复后应自动接管
garp_master_delay 5 MASTER 启动后发送免费 ARP 延迟(秒)
vrrp_garp_repeat 5 免费 ARP 发送次数

监控命令

实时状态监控

# 查看 Keepalived 进程状态
systemctl status keepalived

# 查看 VRRP 状态
ip addr show | grep "192.168.1.100"

# 查看 Keepalived 日志
journalctl -u keepalived -f

# 查看 VRRP 详细状态
cat /proc/net/vrrp

# 查看 Keepalived 运行状态
killall -USR1 keepalived

故障排查步骤

  1. 检查网络连通性

    # 检查 VRRP 组播通信
    tcpdump -i eth0 vrrp
    
    # 检查防火墙是否放行 VRRP 协议
    iptables -L INPUT | grep 224.0.0.18
    
  2. 验证配置语法

    # 检查配置文件语法
    keepalived -t -f /etc/keepalived/keepalived.conf
    
  3. 检查 VIP 分配

    # 查看当前 VIP 分配情况
    ip addr show | grep "inet.*192.168.1.100"
    
    # 手动添加/删除 VIP 测试
    ip addr add 192.168.1.100/24 dev eth0
    ip addr del 192.168.1.100/24 dev eth0
    
  4. 检查健康检查脚本

    # 手动执行健康检查脚本
    /usr/local/bin/check_haproxy.sh
    
    # 检查脚本权限
    ls -la /usr/local/bin/check_haproxy.sh
    

最佳实践

部署最佳实践

  • 双网卡部署:使用专用心跳网卡(如 eth1)进行 VRRP 通信,避免业务流量干扰
  • 配置同步:主备节点配置文件必须完全一致(除 priority 外)
  • 时间同步:确保所有节点 NTP 时间同步,误差 < 100ms
  • 资源隔离:Keepalived 进程使用独立用户运行,限制资源使用
  • 日志轮转:配置 logrotate 管理 Keepalived 日志

安全最佳实践

  • 认证密钥:使用强密码作为 auth_pass,定期轮换
  • 脚本权限:健康检查脚本设置为 700 权限,仅 root 可读写执行
  • 防火墙规则:仅允许 VRRP 组播地址 224.0.0.18 和端口 112
  • SELinux:如启用 SELinux,确保 keepalived_t 类型正确配置

常见问题及解决方案

Q1:VIP 不漂移或漂移异常

原因

  • 主备节点 priority 设置相同
  • 防火墙阻止 VRRP 组播通信
  • 网络设备不支持组播或 IGMP Snooping 配置错误

解决方案

  • 检查 priority 配置,确保主节点高于备节点至少 10
  • 在交换机上禁用 IGMP Snooping 或配置为兼容模式
  • 使用 tcpdump 验证 VRRP 包是否正常收发

Q2:频繁切换(flapping)

原因

  • 健康检查过于敏感(interval 太小,fall/rise 值不合理)
  • 网络抖动导致心跳包丢失
  • 资源不足导致进程响应慢

解决方案

  • 调整 health check 参数:interval=3, fall=3, rise=2
  • 增加 preempt_delay 到 300 秒
  • 监控系统资源使用率,优化硬件配置

Q3:VIP 无法访问

原因

  • VIP 未正确绑定到接口
  • ARP 缓存未刷新
  • 后端服务未正常运行

解决方案

  • 检查 ip addr show 输出确认 VIP 绑定
  • 在客户端执行 arp -d 清除 ARP 缓存
  • 验证后端服务状态和端口监听

故障模拟与演练

模拟主节点故障

# 停止主节点 Keepalived
systemctl stop keepalived

# 观察备节点是否在 3 秒内接管 VIP
watch -n 1 "ip addr show | grep 192.168.1.100"

模拟网络分区

# 在主节点上阻断 VRRP 通信
iptables -A OUTPUT -d 224.0.0.18 -j DROP
iptables -A INPUT -s 224.0.0.18 -j DROP

# 观察是否出现脑裂现象

扩展场景

Keepalived + Nginx 高可用

# 在 Nginx 配置中添加健康检查
upstream backend {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

# Keepalived 监控 Nginx 进程
vrrp_script chk_nginx {
    script "killall -0 nginx"
    interval 2
    weight -2
}

Keepalived + MySQL 主从切换

# MySQL 主从切换脚本
#!/bin/bash
# 在 notify_master 中调用
if [ "$1" = "master" ]; then
    mysql -u root -p'password' -e "STOP SLAVE; RESET SLAVE ALL;"
    mysql -u root -p'password' -e "CHANGE MASTER TO MASTER_HOST='192.168.1.11', MASTER_USER='repl', MASTER_PASSWORD='replpass'; START SLAVE;"
fi

性能基准测试

场景 响应时间 切换时间 备注
正常网络 < 100ms < 3s 主备间 ping 延迟 < 1ms
网络抖动 < 200ms < 5s 丢包率 < 5%
高负载 < 300ms < 8s CPU 使用率 > 80%

参考资料

results matching ""

    No results matching ""