keepalived 通过自定义脚本(如 check_api.sh)结合 vrrp_script 实现 http 内容级健康检测,脚本以退出码 0/1 判定状态,配合 interval、fall、rise 和 weight 参数控制 vip 切换逻辑,并需注意权限、dns、日志及并发安全。

Keepalived 本身不直接支持复杂的 HTTP 内容检测(比如检查返回 JSON 中某个字段是否为 "status":"ok"),但可以通过自定义脚本 + vrrp_script 实现灵活、可靠的高级健康检测,再联动 VIP 切换。关键在于:脚本返回值决定 Keepalived 的状态判断,而 Keepalived 仅关心退出码(0 表示健康,非 0 表示异常)。
用 shell 脚本做内容级检测
例如检测后端服务的 API 是否返回预期响应:
- 脚本需使用
curl或wget发起请求,加超时和失败重试控制(如--max-time 3 --retry 2) - 用
jq解析 JSON 响应,校验关键字段(如jq -e '.status == "ok"' > /dev/null) - 若解析失败、HTTP 状态码非 2xx、或字段不匹配,脚本 exit 1;否则 exit 0
- 脚本权限设为可执行(
chmod +x /etc/keepalived/check_api.sh),并确保keepalived进程有执行权限(注意 SELinux 或 systemd 隔离限制)
在 keepalived.conf 中注册检测脚本
通过 vrrp_script 定义检测行为,并绑定到 VRRP 实例:
vrrp_script chk_api { script "/etc/keepalived/check_api.sh" interval 5 weight -2 fall 2 rise 2 }-
interval 5表示每 5 秒执行一次;fall 2表示连续 2 次失败才判定为故障;rise 2表示连续 2 次成功才恢复 -
weight -2是关键:当脚本失败时,当前节点优先级自动减 2,若低于备机,触发主备切换 - 在
vrrp_instance VI_1块中添加track_script { chk_api }即可启用该检测
避免误切与资源竞争
真实环境中需防范网络抖动或瞬时超时导致的频繁切换:
- 脚本内避免依赖外部 DNS——直接使用后端服务 IP,防止 DNS 解析失败干扰判断
- 不要在脚本里写日志到高 IO 目录(如
/var/log),可用logger交由 syslog 统一处理 - 若多个脚本共用同一后端,建议加锁(如
flock)防止并发 curl 冲突;或改用轻量级工具如httpstat或nc快速探活 - Keepalived 默认以非 root 用户运行(如
keepalived用户),脚本中若需curl或jq,确保这些命令对该用户可访问
配合 Nginx 做本地兜底检测
当 Keepalived 主机自身 Nginx 异常(如进程僵死、端口监听丢失),也可用脚本捕获:
- 检查
nginx进程是否存在:pgrep -x nginx > /dev/null - 检查 80/443 端口是否被监听:
ss -tln | grep ':80\b' > /dev/null - 发起本地 HTTP 请求验证 Nginx 响应:
curl -s http://127.0.0.1/health | grep -q "healthy" - 这类本地检测可与上游 API 检测组合使用,实现“服务进程 + 网络可达 + 业务逻辑”三层校验
不复杂但容易忽略。











