好的,这是一个非常典型的Keepalived故障排查场景。当一个实例停止并进行stop
操作,而另一个实例正常,这通常意味着出问题的实例主动放弃了MASTER状态或自身遇到了严重错误,而不是整个Keepalived进程崩溃。
核心原因在于:Keepalived的每个VRRP实例都是独立运行的,其状态转变(尤其是从MASTER降级)会触发notify_stop
脚本。
以下是系统化的排查步骤和思路:
排查流程图
flowchart TD
A[Instance A 进入 STOP 状态] --> B{检查健康检测脚本<br>vrrp_script/checker}
B -- 脚本返回非0 --> C[脚本执行失败<br>或依赖服务异常]
B -- 脚本超时或无响应 --> D[检测资源不足<br>或脚本死锁]
C --> E[根据脚本逻辑<br>逐项排查依赖服务<br>如端口、进程、网络连接]
D --> F[优化脚本性能<br>调整超时时间timeout]
E -- 问题持续 --> G[检查系统资源<br>CPU, 内存, 磁盘IO]
F -- 问题持续 --> G
G -- 资源耗尽 --> H[扩容或结束无关进程]
G -- 资源正常 --> I[开启详细日志<br>重启服务并重现问题]
I --> J[分析日志重点:<br>- VRRP_Instance(...) ... to FAULT STATE<br>- ... VRRP_Script(check_xxx) failed]
1. 立即检查Keepalived日志(最快定位问题的方法)
Keepalived的日志是定位问题的首要入口。首先需要获取更详细的日志。
查看系统日志:Keepalived通常将日志记录到系统通用日志中。
# 使用journalctl查看(Systemd系统) journalctl -u keepalived --since "5 minutes ago" -f # 或者直接查看syslog/messages tail -f /var/log/messages | grep keepalived tail -f /var/log/syslog | grep keepalived
启用详细调试日志:如果默认日志信息不足,临时修改配置以获取更详细的信息。
- 编辑
/etc/keepalived/keepalived.conf
,在全局配置区块global_defs
中添加:global_defs { ... # 启用详细日志,级别0-7(7最详细) log_file /var/log/keepalived-debug.log log_local7 # 使用local7设施 # 将日志级别调到DEBUG vrrp_debug_level 3 # VRRP模块调试级别,0-3 smtp_debug_level 3 # SMTP调试级别(如果用邮件通知) script_debug_level 3 # Script模块调试级别,0-3 }
- 重启Keepalived:
systemctl restart keepalived
- 重现问题,然后查看
/var/log/keepalived-debug.log
。
- 编辑
在日志中寻找以下关键信息:
VRRP_Script(<script_name>) failed
(表明健康检查失败)VRRP_Instance(<VI_Name>) Entering FAULT STATE
(实例因为错误进入FAULT状态)Stopped
(停止信息)track_script
(追踪脚本的相关执行记录)
2. 重点排查健康检查(CHECK)脚本(最常见的原因)
既然你提到“不进行check检测”,这极大概率是因为该实例配置的健康检查(vrrp_script
) 失败了,导致实例认为自己不健康,从而主动调用notify_stop
并进入FAULT状态。
找到健康检查脚本:查看配置文件,找到为这个特定实例定义的
vrrp_script
。grep -A 10 "vrrp_script" /etc/keepalived/keepalived.conf
示例配置:
vrrp_script chk_nginx { script "/usr/bin/killall -0 nginx" # 检查nginx进程是否存在 interval 2 # 每2秒检查一次 fall 2 # 连续2次失败才认为故障 rise 1 # 成功1次就认为恢复 timeout 2 # 脚本执行超时时间 weight -20 # 失败后优先级降低20 } vrrp_instance VI_1 { ... track_script { chk_nginx # 追踪这个检查脚本 } notify_stop "/path/to/stop_script.sh" ... }
手动执行检查脚本: 以Keepalived运行的用户身份(通常是root)手动执行脚本,看其返回值(Exit Code)。
sudo /usr/bin/killall -0 nginx echo $? # 【关键】查看上一条命令的返回值
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
<br/><br/><br/><font size=1 color=#CCCCCC>内容由零声教学AI助手提供,问题来源于学员提问</font>