通过vrrp_script实现对集群资源的监控的四种方法

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 核心原理

  1. 执行指定的命令/脚本
  2. 检查返回值(0成功,非0失败)
  3. 结合 interval/fall/rise 判断服务状态
  4. 通过 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服务,这样会减少很多问题。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注