Keepalived 服务监控四种方式详解
一、通过 killall 命令探测服务运行状态
vrrp_script check_mysqld { # 定义一个监控脚本,名为 check_mysqld
script "killall -0 mysqld" # 执行的命令:用 killall -0 检查 mysqld 进程
# killall -0 含义:
# - 信号0:不结束进程,只检查进程是否存在
# - 进程存在:返回状态码0
# - 进程不存在:返回状态码1
interval 2 # 检测间隔:每2秒执行一次
}
track_script { # 在 VRRP 实例中跟踪这个脚本
check_mysqld # 跟踪上面定义的 check_mysqld
}
killall -0 工作原理
# 当 MySQL 服务正常运行时
[root@keepalived-master ~]# killall -0 mysqld
[root@keepalived-master ~]# echo $?
0 # 返回0,表示服务正常
# 当 MySQL 服务关闭时
[root@keepalived-master ~]# killall -0 mysqld
mysqld: no process killed # 提示没有找到进程
[root@keepalived-master ~]# echo $?
1 # 返回1,表示服务故障
核心原理:
- vrrp_script 模块不关心脚本具体做什么
- 只关心脚本的返回状态码
- 返回0:认为服务正常
- 返回非0:认为服务故障
- 结合 weight 参数可触发主备切换
二、检测端口运行状态
vrrp_script check_httpd { # 定义一个监控脚本,名为 check_httpd
script "</dev/tcp/127.0.0.1/80" # 通过bash内置的/dev/tcp检测本机80端口
# 这是bash的特殊文件,用于测试TCP连接
# 能连接成功:返回0
# 连接失败:返回1
interval 2 # 每2秒检测一次
fall 2 # 【失败阈值】连续失败2次才认为真的故障
# 防止网络抖动导致误切换
rise 1 # 【成功阈值】连续成功1次就认为服务恢复
# 服务恢复后尽快加回集群
}
track_script { # 在VRRP实例中跟踪这个脚本
check_httpd
}
/dev/tcp 原理
# 这是 Bash 的特殊功能,不是真正的文件
# 语法:</dev/tcp/目标IP/目标端口
# 能建立TCP连接:成功
# 不能建立TCP连接:失败
# 测试80端口是否开放
</dev/tcp/127.0.0.1/80 && echo "端口开放" || echo "端口关闭"
三、通过 shell 语句进行状态监控
vrrp_script chk_httpd { # 定义一个监控脚本,名为 chk_httpd
script "if [ -f /var/run/httpd/httpd.pid ]; then exit 0; else exit 1; fi"
# 直接写 shell 判断语句
# 功能:检查 httpd 的 PID 文件是否存在
#
# 语句分解:
# if [ -f /var/run/httpd/httpd.pid ]; then
# exit 0 # 文件存在,服务正常
# else
# exit 1 # 文件不存在,服务故障
# fi
interval 2 # 每2秒执行一次
fall 1 # 失败1次就切换
rise 1 # 成功1次就恢复
}
track_script {
chk_httpd
}
适用场景:
- 简单的应用监控
- 只需检查 PID 文件是否存在
- 无需复杂的脚本文件
四、通过脚本进行服务状态监控(最常用)
vrrp_script chk_mysqld { # 定义一个监控脚本,名为 chk_mysqld
script "/etc/keepalived/check_mysqld.sh" # 执行外部脚本
# 脚本路径必须是绝对路径
# 脚本需要有执行权限
interval 2 # 每2秒执行一次
# weight -20 # 可选:失败时优先级减20
# fall 3 # 可选:连续3次失败才切换
# rise 2 # 可选:连续2次成功才恢复
}
track_script {
chk_mysqld
}
check_mysqld.sh 脚本详解
#!/bin/bash
# MySQL 健康检查脚本
# 定义变量
MYSQL=/usr/bin/mysql # MySQL 客户端命令路径
MYSQL_HOST=localhost # MySQL 主机地址
MYSQL_USER=root # MySQL 用户名
MYSQL_PASSWORD='xxxxxx' # MySQL 密码
# 执行 MySQL 查询测试
# -h: 指定主机
# -u: 指定用户名
# -p: 指定密码
# -e: 执行 SQL 语句
# "show status;":查询数据库状态
# > /dev/null 2>&1:将标准输出和错误输出都重定向到空设备(不显示任何输出)
$MYSQL -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD -e "show status;" > /dev/null 2>&1
# 检查上一条命令的执行结果
# $? 是上一条命令的返回状态码
# 0 表示成功,非0 表示失败
if [ $? = 0 ] ; then
MYSQL_STATUS=0 # 查询成功,MySQL 正常
else
MYSQL_STATUS=1 # 查询失败,MySQL 异常
fi
# 退出脚本,返回状态码
# vrrp_script 根据这个返回值判断服务状态
# 0:服务正常
# 1:服务故障
exit $MYSQL_STATUS
脚本权限设置
# 给脚本添加执行权限
chmod +x /etc/keepalived/check_mysqld.sh
# 测试脚本是否可执行
/etc/keepalived/check_mysqld.sh
# 查看返回值
echo $?
五、四种监控方式对比
| 监控方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| killall -0 | 简单,一行命令 | 只检查进程是否存在 | 服务进程单一、无子进程 |
| 端口检测 | 简单,无需脚本 | 只检查端口是否监听 | 所有TCP服务 |
| shell语句 | 无需额外文件 | 复杂逻辑难写 | 简单的文件/进程检查 |
| 外部脚本 | 最灵活,可做复杂检查 | 需要维护脚本文件 | 数据库、复杂应用 |
六、vrrp_script 完整参数说明
| 参数 | 作用 | 示例 | 说明 |
|---|---|---|---|
| script | 指定监控命令或脚本 | script "killall -0 httpd" | 可以是命令、shell语句、脚本路径 |
| interval | 检测间隔 | interval 2 | 每2秒执行一次 |
| weight | 优先级调整 | weight -20 | 失败时优先级减20,触发切换 |
| fall | 失败阈值 | fall 3 | 连续3次失败才认为真故障 |
| rise | 成功阈值 | rise 2 | 连续2次成功才认为恢复 |
| timeout | 脚本超时 | timeout 3 | 脚本执行超过3秒算失败 |
七、总结
vrrp_script 核心原理:
- 执行指定的命令/脚本
- 检查返回值(0成功,非0失败)
- 结合 interval/fall/rise 判断服务状态
- 通过 weight 调整优先级,触发主备切换
四种方式选择建议:
- 测试环境:用 killall -0 或端口检测,简单快速
- 生产环境:用外部脚本,可以写完整的健康检查逻辑
检测两个keepalived主机之间是否能通信的办法有:
1、停掉一个keepalived,看另外一个keepalived的日志/var/log/messages 里是否有新的日志
2、用嗅探器抓包,例如:
tcpdump -v -i eth1 host 224.0.0.18
tcpdump -vvv -n -i eth1 host 224.0.0.18
其中,224.0.0.18是VRRP组播使用的目的地址,默认为组播每秒发送一次。
另外,在做集群的时候,尽量关闭每个主机上的selinux服务和iptables服务,这样会减少很多问题。

发表回复