Keepalived的track_script不执行健康检查,仅周期性调用外部脚本并依据其退出码(0为健康、非0为异常)触发权重变化或VIP切换;复杂业务检查(如HTTP状态、DB连通、Redis响应、磁盘空间)须由用户编写脚本实现。

Keepalived 的 track_script 模块本身不执行健康检查,而是通过调用外部脚本(或命令)来判断服务状态,并将返回值(exit code)反馈给 Keepalived。真正“复杂业务健康检查”的能力,取决于你写的脚本——track_script 只负责周期性运行它、读取退出码、触发权重变化或状态切换。
用 track_script 调用自定义健康检查脚本
Keepalived 不内置 HTTP 探测、数据库连通性、API 响应内容校验等逻辑,这些必须由你编写 Shell/Python 脚本完成。Keepalived 只关心脚本是否成功退出:
- 退出码为 0:视为“健康”,权重保持或增加;
- 退出码为 非 0(如 1、2):视为“异常”,触发权重降低或 VIP 迁移;
- 脚本超时(由
fall/rise和interval共同控制)也会累积失败次数。
编写具备业务语义的检查脚本(示例)
比如检查一个电商订单服务是否真正可用,不能只 ping 端口,还要验证:
- 后端 API 是否返回 200;
- 响应 JSON 中
"status"字段是否为"ok"; - 数据库连接是否正常(可执行
SELECT 1); - 关键缓存(如 Redis)能否 set/get;
- 磁盘剩余空间是否大于 15%。
示例脚本 /opt/scripts/check-order-service.sh:
set -e
# 检查 API 响应
if ! resp=$(curl -s -m 5 http://localhost:8080/health | jq -r '.status' 2>/dev/null); then
exit 1
fi
if [[ "$resp" != "ok" ]]; then
exit 2
fi
# 检查 MySQL
if ! mysql -h127.0.0.1 -uroot -p$DB_PASS -e "SELECT 1" order_db >/dev/null 2>&1; then
exit 3
fi
# 检查 Redis
if ! redis-cli -h127.0.0.1 PING | grep -q "PONG"; then
exit 4
fi
# 检查磁盘
if [[ $(df / | awk 'NR==2 {print $5}' | sed 's/%//') -gt 85 ]]; then
exit 5
fi
exit 0
在 keepalived.conf 中正确配置 track_script
注意几个关键点:
-
script路径必须绝对且可执行(chmod +x); -
interval决定检查频率(如 3 秒); -
fall表示连续失败几次才判定为 down(如 3 次); -
rise表示连续成功几次才恢复 up(如 2 次); - 脚本中不要用
sudo或交互式命令,Keepalived 以root运行但无 TTY; - 避免脚本内部 sleep 或长阻塞,否则会拖慢整个 Keepalived 主进程。
配置片段示例:
vrrp_script chk_order_service {script "/opt/scripts/check-order-service.sh"
interval 3
fall 3
rise 2
timeout 10
}
vrrp_instance VI_1 {
...
track_script {
chk_order_service weight 5
}
}
结合 weight 实现精细化故障转移
不用非黑即白地“切 VIP”,可通过 weight 配合 state BACKUP 实现多级降级:
- 主节点健康:weight +5 → 优先获得 VIP;
- 主节点 DB 异常(脚本 exit 3):weight -5 → 权重低于备机,VIP 自动漂移;
- 主节点仅缓存异常(脚本 exit 4):weight -2 → 仍持有 VIP,但流量可由上层 LB 降权分发;
- 多个 track_script 可同时监控不同子系统,各自影响 weight,实现正交故障建模。
这种模式比单纯依赖 notify 更实时、更可控,也更容易与现有运维体系(如 Prometheus + Alertmanager)解耦。










