简介:面向需要保障线上服务高可用性的运维工程师与架构师,这份资源聚焦Haproxy与Keepalived的联合部署,系统梳理了主主模式与主从模式两种高可用架构的搭建方式。文档从基础概念、环境规划、Haproxy负载均衡配置,到Keepalived的VRRP虚拟IP漂移、健康检查与故障切换策略,再到主备切换验证、脑裂预防和常见问题排查,均有详尽步骤与说明。整份资源为1个doc文档,约13.9MB,内容以图文混排的实操记录为主,层级清晰,便于按章节查阅和对照生产环境进行配置。文档基于真实实施整理,覆盖从规划到落地的完整链路,适合作为生产环境部署的参考蓝本。已有453人学习下载,对正在规划负载均衡高可用方案、或需要参考真实完整部署过程的技术人员,可以从中提炼配置参数、判断思路和排错方法,有效缩短环境搭建与调优周期。
1. 搜索 Haproxy+Keepalived 高可用环境部署的人,十有八九都被单机负载均衡坑过
我维护某电商入口时就有过这种经历:后端服务全部健康,数据库也正常,但线上入口全断,只因转发层只有一台 Haproxy,它一宕整条链路就瘫。Haproxy+Keepalived 这套组合解决的就是这个单点问题——Haproxy 负责把流量分发到后端,Keepalived 负责让两台节点的虚拟 IP(VIP)在故障时自动漂移。真正部署时,“主主”和“主从”两种模式差别很大:主从是一主一备、VIP 只挂主节点;主主是两台都干活,各持有自己的 VIP,互为主备。这篇按生产部署流程,把两种模式的架构选型、完整配置、切换验证和常见坑写清楚,适合需要自己搭负载均衡层的运维和架构师。
2. 部署前先定架构:VRRP 原理、模式选型与网络规划
2.1 Keepalived 的 VRRP 机制与 Haproxy 的分工边界
Keepalived 在整套方案里只做一件事:盯住虚拟 IP 的归属。它实现的 VRRP(虚拟路由器冗余协议)原理并不复杂——一组节点共享一个虚拟 IP,节点之间通过组播地址 224.0.0.18 定时互发通告报文,优先级最高的节点进入 MASTER 状态并持有 VIP,其余节点处于 BACKUP 状态持续监听通告。MASTER 每个 advert_int 周期(默认 1 秒)发一次通告,BACKUP 连续三个周期没收到对端消息,就认为 MASTER 失联,经过一个带有随机偏移的等待窗口后自己上位。这里有个容易忽略的细节:VRRP 靠的是“优先级 + 状态机”而不是传统脚本判断,所以两台机器必须能稳定收到对方的组播,否则必然脑裂,这个坑后面单独讲。
Keepalived 除了实现 VRRP,还扩展了健康检查入口:track_interface 直接盯网卡 link 状态,track_script 按指定间隔执行自定义脚本,用返回码决定本机 VRRP 状态是否降级。前者解决网线松动、网卡 down 的切换,后者解决“进程还挂着但服务实际不可用”的切换。生产环境里 Haproxy 出问题通常不是进程退出,而是监听端口异常或后端 RS 全部失联,所以 track_script 才是真正驱动 VIP 漂移的那一条,必须配。
Haproxy 的角色就纯粹了:监听端口、按负载算法把请求转发给后端 RS、对 RS 做健康检查。它不感知 VIP 属于谁,只要本机网卡上有这个地址,内核就会把包收上来。所以两者的分工是垂直的——Haproxy 管流量转发,Keepalived 管 IP 归属。我部署时习惯把 bind 写成 0.0.0.0:端口而不是绑死 VIP,原因是主主模式下每个节点要同时服务两个 VIP,bind 写具体地址会把另一个 VIP 的入口流量挡在门外。地址收敛交给防火墙做,别靠 bind 去卡。
后端健康检查建议用 option tcp-check 或 httpchk,不要只依赖进程存活判断。Haproxy 的 check 参数里有 inter、fall、rise 三个值控制探测节奏,我一般设 inter 5s、fall 3、rise 2——既不会因为单次抖动误摘 RS,也不会让故障探测拖太久。这个节奏要跟 keepalived 侧的切换时间搭配,keepalived 检测到 Haproxy 不可用到 VIP 完成漂移,通常要 3 到 6 秒,属于正常范围。
2.2 主从模式与主主模式:选型对比和适用场景
两种模式在配置上差的其实不多,差的是对“VIP 如何分布”的设计。主从模式只有一个 VIP,常态下全部流量走主节点,备机只承担 VRRP 通告和健康检查,不转发任何业务流量。主主模式拆出两个 VIP,节点 A 是 VIP1 的 MASTER、VIP2 的 BACKUP,节点 B 反过来,于是两台机器在常态下都转发流量,互相当对方的备份。
| 对比项 | 主从模式 | 主主模式 |
|---|---|---|
| VIP 数量 | 1 个 | 每节点 1 个,共 2 个 |
| 常态流量路径 | 全部走主节点 | 两个 VIP 各自分流 |
| 备机资源利用 | 闲置 | 正常承载业务 |
| 单点故障后 | 备机接管全部流量 | 对端接管故障节点的 VIP,可能单节点扛全量 |
| VRRP 实例数 | 每节点 1 个 | 每节点 2 个 |
| 典型场景 | 数据库入口、强主备业务 | Web/API 接入层、想榨干两台机器 |
选型上我的判断标准很简单:后端业务“怕双写、强主备”就用主从,比如 MySQL 读写入口,主库只有一个,VIP 也只有一个,语义完全对齐;后端业务“无状态或弱状态”就用主主,比如 API 接入层,两个 VIP 按服务拆分,或者同一个域名轮询解析到两个 VIP。需要提醒的是,主主不等于两台 Haproxy 互为负载集群,它只是入口 VIP 的分散,真正分担流量还得靠 DNS 轮询或业务侧按 VIP 分流。如果两个 VIP 指向同一组后端 RS,流量确实被摊开了,但某个用户会话在两个 VIP 之间跳动时,L7 层的登录态会掉,必须在 Haproxy 里配 stick table 或者让业务层做会话共享,否则就是给自己埋雷。
2.3 前置检查:网络、内核参数与软件安装
先把地址规划列清楚,两台 LB 的内网 IP、VIP、后端 RS 都要在部署前固定下来,后面所有配置都围绕这张表展开。
| 节点 | 角色 | 内网 IP | 用途 |
|---|---|---|---|
| LB-1 | 主从主节点 / 主主 A 节点 | 192.168.10.11 | haproxy + keepalived |
| LB-2 | 主从备节点 / 主主 B 节点 | 192.168.10.12 | haproxy + keepalived |
| VIP1 | 漂移地址 | 192.168.10.10 | 对外服务入口 |
| VIP2 | 主主模式第二个入口 | 192.168.10.20 | 对外服务入口 |
装软件前先做一遍环境核查,两台机器配置保持一致,尤其网卡名和防火墙策略。下面这组命令我在每台新机器上都会先跑一遍:
# 1. 确认网卡名一致,keepalived 的 interface 写错是低级但高频的坑 ip addr show # 2. 确认防火墙放行 VRRP 组播报文,VRRP 协议号是 112 # firewalld 环境用 rich-rule,iptables 环境对应放行 proto 112 firewall-cmd --permanent --add-rich-rule='rule protocol value="112" accept' firewall-cmd --reload # 3. 确认 SELinux 状态,建议 permissive 或为 haproxy 单独放行 getenforce # 4. 安装软件,版本用发行版仓库自带的即可 yum install -y haproxy keepalived防火墙放行 VRRP 是最容易被漏掉的一步。很多发行版默认防火墙策略里没有 protocol 112 的放行规则,Keepalived 起了一切正常,但两台机器互相收不到通告,结果就是双 MASTER 脑裂。SELinux 在 enforcing 模式下可能拦截 Haproxy 绑定非标准端口或访问日志目录,先切 permissive 跑通流程,再回头收紧策略,不要一上来就跟 SELinux 硬刚。安装完成确认 haproxy 和 keepalived 命令都在 PATH 里,haproxy -v、keepalived --version各看一眼版本号即可,keepalived 2.x 的配置项和 1.x 差得不多,但旧文档里的个别参数名已经废弃,别照抄。
3. 主从模式完整部署:配置、启动与 VIP 漂移验证
3.1 Haproxy 安装与最小可用配置
装完先写 Haproxy 配置,我以四层 TCP 转发为例,后端是两台跑同一服务的 RS,端口 8080。生产里这套配置同样适用于 MySQL、Redis 等 TCP 协议的入口转发。
# /etc/haproxy/haproxy.cfg global maxconn 50000 # 单进程最大连接数,按机器内存调整 log 127.0.0.1 local0 info # 日志走本机 syslog local0 user haproxy group haproxy daemon defaults mode tcp # 四层转发,适合数据库、RPC、TCP 长连接 timeout connect 5s # 向后端建立连接的超时 timeout client 30s # 客户端空闲超时 timeout server 30s log global frontend service_front bind *:8080 # 绑 0.0.0.0,VIP 漂移不影响监听 default_backend service_back backend service_back balance roundrobin # 轮询;长连接场景可换 source 做来源哈希 option tcp-check # TCP 层健康检查,探测端口是否可连通 server svc-1 192.168.10.31:8080 check inter 5s fall 3 rise 2 maxconn 2000 server svc-2 192.168.10.32:8080 check inter 5s fall 3 rise 2 maxconn 2000 # 本地管理 socket,后续巡检、查看 RS 状态都靠它 stats socket /var/run/haproxy/haproxy.sock mode 600 level admin几个参数展开说:maxconn 决定单进程能扛多少并发连接,50000 对应 8 核 16G 的机器绰绰有余,连接数大头在后端 RS,LB 层只是转发。timeout server 不要设得太短,TCP 长连接业务如果 30 秒空闲就断开,客户端会频繁重建连接,生产里我见过因为 timeout 设 10s 导致连接抖动的问题。balance roundrobin 适合短连接,如果是数据库这种长连接场景,建议改成 source,按客户端 IP 哈希,可以避免同一个客户端的长连接在 RS 之间乱跳。maxconn 2000 是给每台 RS 的连接上限,防止单台后端被打满后新连接全部堆积。
写完后先做配置语法检查再启动:haproxy -c -f /etc/haproxy/haproxy.cfg,输出 Config valid 再systemctl start haproxy,然后ss -lntp | grep 8080确认监听正常。这套最小配置里故意没加 HTTP 模式特有的内容,因为四层转发对上层协议透明,只要端口能通就行,排错链路最短。
3.2 Keepalived 主从配置:MASTER/BACKUP 状态机
主从模式的 Keepalived 配置是最直观的:一台 state MASTER、priority 150,另一台 state BACKUP、priority 100,两台的 virtual_router_id 必须一致,advert_int 必须一致。下面是主节点 LB-1 的完整配置。
# /etc/keepalived/keepalived.conf —— LB-1 主节点 global_defs { router_id LBSERVER_A # 唯一标识,两台不能相同 } vrrp_script chk_haproxy { script "/etc/keepalived/check_haproxy.sh" interval 2 # 每 2 秒执行一次健康检查 timeout 3 # 单次执行超过 3 秒视为失败 rise 2 # 连续成功 2 次才恢复健康 fall 2 # 连续失败 2 次才降级 } vrrp_instance VI_HA { state MASTER # 备节点这里改成 BACKUP interface eth0 virtual_router_id 51 # 两台必须一致,且在整个二层网段唯一 priority 150 # 备节点改成 100 advert_int 1 # VRRP 通告间隔,单位秒 authentication { auth_type PASS auth_pass HA51Pass # 不要超过 8 位,用字母数字组合 } virtual_ipaddress { 192.168.10.10/24 # 主从模式只需要一个 VIP } track_script { chk_haproxy # 引用上面定义的脚本 } }auth_pass 的位数限制是个老坑,很多版本里超过 8 位会告警甚至直接拒绝加载。这里别图省事用业务密码,VRRP 报文是明文带着这个密码在局域网里跑的,单独用一个 8 位以内的随机字符串。virtual_router_id 默认范围 1 到 255,同一个二层域里不同 VRRP 组必须用不同的 ID,如果公司里还有别的服务也在用 Keepalived,拿 51 之前先确认没撞车。
配合的健康检查脚本是切换动作的真入口,脚本返回 0 表示健康,返回非 0 表示本机 Haproxy 不可用,Keepalived 会据此降级并把 VIP 交出去。
#!/bin/bash # /etc/keepalived/check_haproxy.sh # 先探测 haproxy 进程是否存在,killall -0 只发信号探测,不真正杀进程 if ! killall -0 haproxy 2>/dev/null; then # 进程不在了,尝试拉起一次,给系统一个自愈机会 systemctl start haproxy sleep 2 fi # 再次确认进程状态,存活返回 0,拉起失败返回 1 if killall -0 haproxy 2>/dev/null; then exit 0 fi exit 1脚本写好后必须手动跑一遍并检查返回值:chmod +x /etc/keepalived/check_haproxy.sh,然后执行echo $?看是不是 0。脚本没加执行权限是 track_script 失效的第一大原因,Keepalived 不会报错,只会默默忽略。另外要注意 systemd 对 Keepalived 的沙箱限制,如果改过 unit 的 CapabilityBoundingSet,别把 NET_ADMIN 能力收掉,否则 Keepalived 添加 VIP 时会静默失败,VIP 永远挂不上去。
3.3 启动顺序、验证命令与故障切换实测
启动顺序我固定为先 Haproxy 后 Keepalived。先起 Haproxy 保证业务端口已经在监听,再让 Keepalived 把 VIP 挂上来,对外入口就是完整的;顺序反了的话 VIP 先出现但端口没人接,会有一段短暂的 connection refused 窗口。两台机器都起来后,按下面的步骤做一轮完整验证:
# 在主节点确认 VIP 已经挂在本机 eth0 上 ip addr show eth0 | grep 192.168.10.10 # 查看 keepalived 的当前状态和进程日志 systemctl status keepalived # 抓 VRRP 报文,确认备节点的通告能正常收到 # 输出里应能看到来源地址是 192.168.10.12 的 vrrp 包 tcpdump -i eth0 vrrp -ntcpdump 抓 VRRP 是判断“两台机器是否在正常协商”的最直接手段,比看日志快。能看到对端通告,说明组播链路没问题;看不到,直接回 2.3 检查防火墙。接下来做故障切换实测,这一步不能省:
# 模拟一:停掉主节点 LB-1 的 haproxy,触发 track_script 降级 systemctl stop haproxy # 等待 5~10 秒,在备节点 LB-2 上确认 VIP 已经漂移过来 ip addr show eth0 | grep 192.168.10.10 # 模拟二:恢复 LB-1 的 haproxy,观察 VIP 是否按预期回切 systemctl start haproxy # 若配置了 nopreempt,VIP 不会主动回切,这是正常行为 # 回切逻辑见 5.1 的说明切换验证通过的标准有三个:备节点出现 VIP、备节点日志出现 Entering MASTER STATE、用业务客户端连 VIP 能正常访问。只看到 VIP 漂移但业务连不通,说明 Haproxy 后端或防火墙还有问题,不要急着宣布部署完成。
4. 主主模式部署:双 VIP 双活的配置拆分
4.1 双 VIP 设计与流量拆分思路
主主模式本质上是把两套主从 VRRP 实例叠在同一个节点上,让每台机器在其中一个实例里当 MASTER。节点 A 是 VIP1 的 MASTER、VIP2 的 BACKUP;节点 B 是 VIP2 的 MASTER、VIP1 的 BACKUP。常态下两个 VIP 分别活跃在两台机器上,流量被拆成两个入口。
拆法我推荐按服务拆:VIP1 给 A 服务,VIP2 给 B 服务,语义清晰,出问题时直接按 VIP 定位链路。如果两个 VIP 指向同一个后端服务,靠 DNS 轮询分流,就要额外面对会话保持问题——同一个用户在两个 VIP 进来,L7 层的登录态、session 都会乱。我踩过一次:后端 Redis session 没做共享,前端轮询到两个 VIP 后用户频繁掉登录,排查了很久才定位到是会话漂移,最后改成按服务拆 VIP 才消停。所以主主模式的前提是业务无状态或已有会话共享方案,别指望 Haproxy 层的 stick table 能兜住所有场景。
两台节点的 Haproxy 配置要保持完全一致,后端 RS 列表、端口、负载算法都相同,差别只允许出现在 Keepalived 的 state 和 priority 上。否则同一个服务从不同 VIP 进来表现不一致,排错的时候非常割裂。
4.2 Keepalived 双实例配置:一套节点两套 VRRP
下面是节点 A 的完整配置,节点 B 把两个实例的 state 和 priority 对调即可。
# /etc/keepalived/keepalived.conf —— LB-1(节点 A) global_defs { router_id LBSERVER_A } vrrp_script chk_haproxy { script "/etc/keepalived/check_haproxy.sh" interval 2 timeout 3 } # 实例 VI_50 负责 VIP1,在 A 上是主 vrrp_instance VI_50 { state MASTER interface eth0 virtual_router_id 50 # 第一个 VRRP 组 ID priority 150 advert_int 1 authentication { auth_type PASS auth_pass HA50Pass } virtual_ipaddress { 192.168.10.10/24 } track_script { chk_haproxy } } # 实例 VI_60 负责 VIP2,在 A 上是备 vrrp_instance VI_60 { state BACKUP interface eth0 virtual_router_id 60 # 第二个 VRRP 组 ID,必须与 VI_50 不同 priority 100 advert_int 1 authentication { auth_type PASS auth_pass HA60Pass } virtual_ipaddress { 192.168.10.20/24 } track_script { chk_haproxy } }节点 B 的配置把 state 和 priority 对调:VI_50 改成 BACKUP、priority 100,VI_60 改成 MASTER、priority 150,router_id 改成 LBSERVER_B,其余原样。两个实例的 virtual_router_id 必须不同,并且两台机器上对应实例的 ID 要一致,否则 VRRP 会在同一个组里出现两个优先级不同的 MASTER 声明,协商直接乱掉。
这里有个关键设计要考虑清楚:两个实例共用同一个 track_script。后果是,节点 A 的 haproxy 一旦挂掉,VI_50 和 VI_60 会同时降级,两个 VIP 都会漂到节点 B,节点 B 单机扛下全量流量。这在资源上是允许的,在语义上就见仁见智了——如果希望“A 服务挂了只有 VIP1 漂走,B 服务不受牵连”,就给两个实例各配一个独立脚本,分别检测对应服务端口,实例各自 track 自己的脚本。配置量只多两行,但故障域清晰很多,我建议按服务拆的业务都这么做。
4.3 主主模式下的切换实测与回切操作
主主模式的验证比主从多一步:先确认常态下两个 VIP 各就各位,再逐个模拟故障,确认漂移方向正确。
# 常态确认:节点 A 持有 10.10,节点 B 持有 10.20 ip addr show eth0 | grep -E '192.168.10.(10|20)' # 模拟 A 节点 haproxy 故障 systemctl stop haproxy # 等待 5~10 秒,观察 B 节点是否把 10.10 也收走了 # 此时 B 同时持有两个 VIP,连接数会明显上涨 ip addr show eth0 # 恢复 A:先起 haproxy,让健康检查先恢复 systemctl start haproxy # 再观察日志,确认 VI_50 是否回切到 A tail -f /var/log/keepalived.log主主模式最考验的不是配置,是容量规划。单节点故障时对端要同时扛两个 VIP 的流量,如果平时每台只跑 60% 容量,故障瞬间就超了。我一般要求主主模式下单台的峰值负载不超过 45%,留出双倍冗余,压测也得按“单点承载全量”的场景来做,而不是按双活的 50% 分摊来评估。回切动作本身不需要人工干预,Keepalived 检测到对端恢复且优先级更高,会在抢占模式下自动把 VIP 拉回来,业务侧感知的只是 VIP 背后 MAC 的变化,新建连接不受影响,存量长连接断开是预期行为。
5. 高可用部署避坑指南:5 个真实的翻车现场
5.1 备机频繁顶替主机:抢占模式的坑
现象:主节点重启恢复后,VIP 在几十秒内来回切换,监控告警刷屏,业务连接断了一大片。
原因:Keepalived 默认开启抢占。主从配置里 state MASTER 的节点恢复后,优先级 150 高于备机的 100,会立刻把 VIP 抢回来。如果这种重启发生在业务高峰期,每抢一次,所有长连接就要断一次。
解决:主从模式下如果不想让 VIP 频繁回切,把两台节点的 state 都写成 BACKUP,并加上 nopreempt,靠 priority 高低决定谁在主。配置里 state 不再是 MASTER,而是 BACKUP + nopreempt + priority 150/100。nopreempt 必须在两台节点同时配置才生效,只配一边会行为不一致。代价是主节点故障恢复后 VIP 不会自动回位,需要人工干预或等下一次故障漂移,这是“可用性优先”还是“流量分布优先”的取舍。
5.2 Haproxy 停了 VIP 却不漂移
现象:systemctl stop haproxy 之后等了很久,VIP 纹丝不动,业务入口还是指向故障节点。
原因:这是两个常见叠加错误。要么 vrrp_instance 里压根没写 track_script,Keepalived 只盯了网卡状态,网卡是 up 的就认为节点健康;要么写了脚本但脚本没有执行权限,或者脚本路径写错,Keepalived 执行失败但不会在日志里明确告诉你。
解决:先确认配置里有没有 track_script,然后手动执行脚本并检查返回值。chmod +x /etc/keepalived/check_haproxy.sh,再跑一次echo $?确认返回 0。最后用keepalived -t -f /etc/keepalived/keepalived.conf做一次配置检查,重点看 vrrp_script 段有没有报错。记住这条排查顺序:先脚本后配置,先手动后自动。
5.3 keepalived 起来后日志一片空白
现象:Keepalived 进程正常,状态迁移也发生了,但查 /var/log/messages 和 journalctl 都看不到像样的记录,排错像对着黑匣子。
原因:Keepalived 默认走 syslog 的 local0 facility,多数发行版的 rsyslog 没有为 local0 单独分配日志文件,导致这些记录被丢进默认规则或直接被丢弃。
解决:单独给 Keepalived 建一个日志通道。
# /etc/rsyslog.d/keepalived.conf local0.* /var/log/keepalived.log然后重启 rsyslog 和 keepalived,让进程重新打开日志文件描述符。之后切换、脑裂、配置错误都会记录在 /var/log/keepalived.log 里,排错效率能提一大截。这一步建议在部署阶段就做掉,别等出故障了才想起来。
5.4 两台机器同时持有 VIP:脑裂
现象:巡检发现节点 A 和节点 B 的 eth0 上都挂着 192.168.10.10,业务访问时好时坏,部分请求到了 A,部分到了 B。
原因:两台机器之间的 VRRP 组播不通,互相收不到通告,于是都认为自己是 MASTER。最常见的原因是防火墙没放行协议 112,其次是交换机在 VLAN 里禁用了组播或 IGMP snooping 配置异常。还有一种隐蔽场景:Keepalived 绑定多播地址失败,进程起来了但根本不在组里。
解决:回 2.3 检查防火墙放行规则,再用 tcpdump -i eth0 vrrp -n 确认组播报文是否到达。恢复步骤是先把其中一台 keepalived stop 掉,让另一台稳定持有 VIP,再启动停掉的节点。日常防御靠巡检脚本双查 VIP,发现两台同时持有立刻告警。对于组播受限的网络环境,Keepalived 支持在 vrrp_instance 里配置 unicast_src_ip 和 unicast_peer 走单播通告,这是组播被禁时最可靠的后悔药。
5.5 VIP 漂移后业务迟迟连不上
现象:切换完成后 curl VIP 正常,但部分客户端持续超时,过几分钟才慢慢恢复。
原因:客户端和中间交换机缓存了旧 MAC 的 ARP 表项。Keepalived 切换后会发送 gratuitous ARP 刷新邻居,但有些交换机端口安全策略、MAC 表老化时间长的环境刷新不及时,流量还被引向已经失效的旧地址。
解决:切换后适当调大 gratuitous ARP 的发送次数和延迟,老版本参数叫 garp_master_delay,新版本是 gratuitous_arp_delay,按部署版本查对应手册。交换机侧把连接 LB 的端口 MAC 老化时间调短。业务侧是大头——数据库连接池、消息客户端这类长连接在漂移后全部断开是正常现象,关键是让应用的连接池配置快速失败重连,不要用几十秒的退避策略,否则故障恢复要被应用的重试机制拖慢。
6. 部署完成的最后一步:验证脚本与运维习惯
6.1 一套可复用的巡检命令
部署完成不等于高可用落地,日常巡检才是兜底。我每个节点放一个巡检脚本,每分钟跑一次,结果汇总到监控平台。
#!/bin/bash # 巡检脚本片段:检查本机 VIP 归属和 keepalived 状态 vips="192.168.10.10 192.168.10.20" tmp_ip=/tmp/ip_now_$(hostname).log ip addr show > "$tmp_ip" for vip in $vips; do if grep -q "$vip" "$tmp_ip"; then echo "$(date '+%F %T') $HOSTNAME 持有 $vip" fi done # 从日志里提取最近的 VRRP 状态迁移记录 grep -E "Entering (MASTER|BACKUP)" /var/log/keepalived.log | tail -3这个脚本的核心价值是抓“双持有”——两台机器同时出现同一个 VIP,优先级最高的告警条件,比任何指标都先响。单节点持有 VIP 是正常态,双持有才是事故,把监控条件写成只对双持有告警,误报率很低。
6.2 用 Haproxy stats socket 做运行观测
VIP 层面的高可用搞定了,还要盯住 Haproxy 后端的健康状态和连接数,stats socket 就是最直接的观测窗口。
# 查看所有后端 RS 的状态和实时连接数 echo "show stat" | socat stdio unix-connect:/var/run/haproxy/haproxy.sock # 看整体连接数摘要 echo "show info" | socat stdio unix-connect:/var/run/haproxy/haproxy.sock \ | grep -E "(Maxconn|CurrConns)"show stat 输出里重点看两个字段:svname 为后端服务器名的行,status 是 UP 还是 DOWN;scur 是当前连接数。如果某台 RS 频繁在 UP/DOWN 之间跳动,说明后端健康检查参数太敏感,回 3.1 调 inter 和 fall。socat 没装的话yum install -y socat补上,它是连 unix socket 最顺手的工具。
这套环境我前后搭过三轮,最后留下的习惯是:所有配置改动必须先经过haproxy -c -f和keepalived -t -f双重语法检查,再提交生产;每个月定时做一次真实的停 haproxy 演练,而不是只在文档里写“已演练”。还有一条血泪教训——生产环境千万别用 kill -9 模拟 keepalived 故障,进程被强杀时 VIP 来不及清理,状态机直接乱掉,对端接管后会出现 IP 冲突;停服务用 systemctl stop 才是真实故障的触发路径。把这些写下来,就是把踩过的坑变成下次能直接抄的作业,希望帮到你。
本文还有配套的精品资源,点击获取