Keepalived+Nginx高可用架构:从VRRP原理到生产环境部署实战
1. 项目概述:为什么需要 Keepalived + Nginx?
在线上业务里,最怕的就是服务突然“挂掉”。想象一下,你负责的电商网站正在搞大促,流量瞬间冲上来,结果承载所有用户请求的 Nginx 服务器因为硬件故障或者网络波动宕机了,整个网站直接无法访问。这不仅仅是技术故障,更是业务灾难,直接导致收入损失和用户口碑下滑。
这时候,“高可用”就成了必须考虑的核心架构。高可用不是让单台服务器永不宕机,那几乎不可能,而是通过冗余设计,确保当一台服务器出问题时,另一台能立刻顶上,对外提供的服务不间断,用户毫无感知。这就像给核心服务上了“双保险”。
“Keepalived + Nginx”就是实现 Web 服务高可用最经典、最直接的组合拳之一。Nginx 本身性能强悍,能处理高并发请求,但它是个单点。Keepalived 则是一个专注于实现 IP 高可用的软件,它的核心工作是管理一个“虚拟 IP”。在多台服务器上部署相同的 Nginx 服务,然后让 Keepalived 来决定这个虚拟 IP 应该“飘”在哪台服务器的网卡上。用户和上游服务都访问这个虚拟 IP,而 Keepalived 会通过健康检查机制,确保只有健康的 Nginx 服务器才能持有这个 IP。一旦主服务器故障,虚拟 IP 会在秒级内自动漂移到备服务器,完成无缝切换。
这个方案特别适合中小型团队和业务场景,它不依赖于昂贵的硬件负载均衡器,完全基于开源软件,配置清晰,运维成本相对可控。接下来,我会拆解这个组合的每一个核心环节,从设计思路到实操配置,再到避坑指南,带你彻底掌握这套高可用架构的搭建与运维。
2. 架构设计与核心原理拆解
2.1 高可用架构的两种典型模式
在动手之前,我们先理清两种最常见的部署模式,这决定了你服务器的角色和流量走向。
主备模式:这是最常用、也最易于理解的模式。我们准备两台服务器,一台是Master,另一台是Backup。在正常情况下,虚拟 IP 绑定在 Master 服务器上,所有流量都流向它。Backup 服务器上的 Nginx 和 Keepalived 虽然也在运行,但它不接收任何用户流量,处于“热备”状态。当 Master 故障,Keepalived 会触发切换,虚拟 IP 漂移到 Backup,它开始接管流量。这种模式资源利用率不是最高(备机闲置),但架构简单,切换逻辑清晰。
双主模式:这种模式要求有两台以上的服务器,并且每台服务器上都有独立的业务服务。通过配置多个虚拟 IP,并利用 DNS 轮询或上层负载均衡,让流量可以分摊到多台服务器。Keepalived 在这里的作用是确保每个虚拟 IP 在当前服务器健康时由其持有,故障时则释放。这种模式资源利用率高,但配置和运维更复杂,通常用于更大型的集群。
对于入门和大多数业务场景,我强烈建议从主备模式开始。它逻辑简单,排错容易,足以应对绝大多数的高可用需求。我们后续的讲解也将围绕主备模式展开。
2.2 Keepalived 的核心工作原理:VRRP 协议
Keepalived 的高可用能力,其基石是VRRP协议。你可以把 VRRP 理解为一个“选举协议”。
在一个 VRRP 组里,有多台路由器(在我们的场景里就是服务器)参与。它们会共同选举出一个Master,其他的成为Backup。这个 Master 负责承载虚拟 IP,并转发数据。所有的 VRRP 成员之间会通过组播报文进行心跳通信,通告自己的优先级和状态。
几个关键概念:
- 虚拟路由器 ID:一个数字,比如 51。同一个高可用组内的所有 Keepalived 节点必须配置相同的 VRID,这样它们才能相互识别,组成一个团体。
- 优先级:一个 1-254 之间的数字,数字越大,优先级越高。在初始选举中,优先级最高的节点会成为 Master。这是控制哪台机器“主”哪台“备”的核心参数。
- 虚拟 IP:对外提供服务的 IP 地址,它不属于任何一台物理服务器,而是由当前的 Master 节点“临时持有”。
- 抢占模式:当 Backup 节点发现 Master 节点的心跳丢失(故障),并且自己的优先级更高时,它是否会主动抢占成为新的 Master。默认是开启的。
工作流程简化版:
- 初始化:两台服务器都启动 Keepalived,加入同一个 VRID 组。
- 选举:比较优先级,优先级高的成为 Master,将虚拟 IP 绑定到自己的网卡上,并开始发送心跳报文。
- 稳态:Master 定期发送心跳。Backup 监听心跳。用户访问虚拟 IP,流量到达 Master 的 Nginx。
- 故障:如果 Backup 在连续几个心跳周期内都收不到 Master 的心跳,它就认为 Master 挂了。
- 切换:Backup 节点(此时可能成为新的 Master)会发送一个免费 ARP 报文到网络中,宣告“这个虚拟 IP 现在归我了!”。网络中的交换机、路由器以及其他服务器的 ARP 表会随之更新,之后发往虚拟 IP 的流量就自然导向了新的服务器。
注意:免费 ARP 是切换能成功的关键。它解决了 IP 地址和 MAC 地址映射更新的问题。如果没有这个机制,即使虚拟 IP 绑定了新网卡,网络设备也不知道该把包发给谁。
2.3 Nginx 的角色与健康检查联动
在这个架构里,Nginx 是真正干活的“业务进程”,而 Keepalived 是负责“调度和容灾”的“管家”。
但这里有个关键问题:如果 Nginx 进程本身崩溃了,但服务器操作系统和 Keepalived 进程还活着,会怎样?答案是:虚拟 IP 依然绑定在这台故障服务器上,但用户请求发过来后,Nginx 无法响应,服务依然中断。
所以,一个健壮的高可用方案,必须让“管家”能监控“工人”的健康状态。这就是Keepalived 对 Nginx 的健康检查。Keepalived 可以配置自定义的检查脚本,定期执行。比如,写一个脚本检查 Nginx 的 80 端口是否可访问,或者直接请求一个本地网页。如果检查失败,脚本返回非 0 状态码,Keepalived 就会认为本机“不健康”,从而主动降低自己的优先级(比如减去一个很大的数值),触发主备切换。
这样,无论是整机故障、网络故障,还是单纯的 Nginx 进程故障,都能被感知并触发高可用切换,实现了真正的服务层高可用。
3. 环境准备与软件安装
3.1 服务器规划与网络配置
我们以最典型的两台 CentOS 7 服务器为例进行规划。实际中请替换为你的服务器 IP。
- 服务器A (计划作为初始 Master):
- 主机名: nginx-node-01
- 系统: CentOS 7.9
- 内网 IP: 192.168.1.101
- 虚拟 IP: 192.168.1.100
- 服务器B (计划作为初始 Backup):
- 主机名: nginx-node-02
- 系统: CentOS 7.9
- 内网 IP: 192.168.1.102
- 虚拟 IP: 192.168.1.100
关键准备工作:
- 主机名与 hosts 文件:为方便管理,建议设置不同的主机名。同时,在两台服务器的
/etc/hosts文件中添加对方记录,确保能通过主机名互相解析,这在查看日志和排查问题时很有用。# 在两台服务器上分别执行 hostnamectl set-hostname nginx-node-01 # 在A上执行 hostnamectl set-hostname nginx-node-02 # 在B上执行 # 编辑 /etc/hosts,在两台服务器上都添加 192.168.1.101 nginx-node-01 192.168.1.102 nginx-node-02 - 防火墙与 SELinux:确保两台服务器之间的VRRP 组播通信(通常是 224.0.0.18 和 IP 协议号 112)以及后续 Nginx 的端口(如 80)是开放的。对于学习环境,可以临时关闭防火墙和 SELinux 以排除干扰,但生产环境务必配置精确的安全策略。
# 临时关闭防火墙(重启后失效) systemctl stop firewalld systemctl disable firewalld # 临时关闭 SELinux(重启后失效) setenforce 0 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config - 时间同步:确保两台服务器的时间基本一致,这对于日志分析至关重要。
yum install -y ntpdate ntpdate time.windows.com
3.2 Nginx 的安装与基础配置
在两台服务器上执行相同的安装操作。这里采用官方仓库安装,版本稳定且便于管理。
- 安装 EPEL 仓库和 Nginx:
yum install -y epel-release yum install -y nginx - 启动 Nginx 并设置开机自启:
systemctl start nginx systemctl enable nginx - 为了区分两台服务器,我们修改默认的欢迎页面。这有助于在测试时直观地看到请求落在了哪台服务器上。
# 在服务器A (192.168.1.101) 上执行 echo "This is Nginx Master Node - 192.168.1.101" > /usr/share/nginx/html/index.html # 在服务器B (192.168.1.102) 上执行 echo "This is Nginx Backup Node - 192.168.1.102" > /usr/share/nginx/html/index.html - 此时,分别访问
http://192.168.1.101和http://192.168.1.102,应该能看到不同的欢迎语,证明 Nginx 安装成功。
3.3 Keepalived 的安装与核心配置
同样,在两台服务器上安装 Keepalived。
yum install -y keepalived安装完成后,最重要的就是配置文件/etc/keepalived/keepalived.conf。我们先备份默认配置,然后从头编写。
服务器A (Master) 配置:
vim /etc/keepalived/keepalived.conf写入以下内容:
! Configuration File for keepalived global_defs { router_id nginx_node_01 # 标识本节点的字符串,通常为 hostname,必须唯一 } vrrp_script chk_nginx { script "/etc/keepalived/check_nginx.sh" # 健康检查脚本路径 interval 2 # 检查间隔,秒 weight -20 # 如果检查失败,优先级降低20 fall 2 # 连续失败2次才认为故障 rise 1 # 成功1次就认为恢复 } vrrp_instance VI_1 { # 定义VRRP实例,VI_1是自定义名称 state MASTER # 初始状态,设置为MASTER interface ens33 # 绑定虚拟IP的物理网卡名称,请根据实际情况修改(ifconfig查看) virtual_router_id 51 # 虚拟路由ID,主备必须相同,范围0-255 priority 100 # 初始优先级,MASTER要比BACKUP高 advert_int 1 # 心跳通告间隔,秒 authentication { # 认证机制,防止非法节点加入 auth_type PASS # 认证类型 auth_pass 1111 # 认证密码,主备必须相同 } virtual_ipaddress { 192.168.1.100/24 # 虚拟IP地址,可以多个 } track_script { # 调用上面定义的健康检查脚本 chk_nginx } }服务器B (Backup) 配置:配置文件大部分相同,关键区别在于state和priority。
global_defs { router_id nginx_node_02 # 此处改为 node_02,保持唯一 } vrrp_script chk_nginx { script "/etc/keepalived/check_nginx.sh" interval 2 weight -20 fall 2 rise 1 } vrrp_instance VI_1 { state BACKUP # 初始状态设置为BACKUP interface ens33 virtual_router_id 51 # 必须与Master相同 priority 90 # 优先级低于Master advert_int 1 authentication { auth_type PASS auth_pass 1111 # 密码与Master相同 } virtual_ipaddress { 192.168.1.100/24 } track_script { chk_nginx } }3.4 创建 Nginx 健康检查脚本
现在创建上面配置中引用的检查脚本/etc/keepalived/check_nginx.sh。这个脚本的任务是判断本机的 Nginx 是否存活。
在两台服务器上创建该文件:
vim /etc/keepalived/check_nginx.sh写入以下内容:
#!/bin/bash # 检查 Nginx 进程是否存在 # if pgrep -x "nginx" > /dev/null # then # exit 0 # else # exit 1 # fi # 更推荐的方式:检查 Nginx 端口是否可访问 if curl -s -o /dev/null -w "%{http_code}" http://localhost:80 | grep -q "200\|301\|302"; then exit 0 else # 如果检查失败,可以尝试重启一次 Nginx(根据情况决定是否开启) # systemctl restart nginx exit 1 fi给脚本添加执行权限:
chmod +x /etc/keepalived/check_nginx.sh实操心得:检查进程存在(
pgrep)是最简单的方式,但不够健壮。有可能进程还在,但已经僵死或不响应了。因此,我强烈推荐使用curl检查本地端口或特定 URL 的方式,这更能代表服务的真实可用性。-s静默模式,-o /dev/null丢弃输出内容,-w只取状态码,效率很高。
4. 配置详解与启动流程
4.1 Keepalived 配置文件深度解析
让我们回过头,仔细咀嚼一下配置文件的每个部分,理解其背后的意图。
global_defs.router_id:这个标识会出现在日志里。当你在日志中看到nginx_node_01发送了通告,你立刻就知道是哪台机器。必须确保集群内唯一,否则日志会混乱。vrrp_script:这是定义健康检查任务的地方。script:指定要执行的脚本路径。脚本必须以exit 0(成功)或exit 1(失败)返回。interval:检查间隔。太短会增加系统负担,太长则故障感知慢。2秒是一个常用折中值。weight:检查失败时的优先级调整值。这是一个关键技巧。假设 Master 初始优先级 100,检查失败一次,优先级变为 100 + (-20) = 80。此时 Backup 的优先级 90 就更高了,会触发切换。weight值通常设置为一个足够大的负数,以确保一旦业务故障,本机优先级能立刻低于备机。fall和rise:用于简单的故障降级和恢复升级判断,避免因网络瞬时抖动导致频繁切换。
vrrp_instance:VRRP 实例的核心定义。state:初始状态。这里有个常见误区:很多人认为这里写了MASTER它就永远是 Master。不对,这个状态只是启动时的“期望角色”。最终谁当 Master,是由优先级和选举决定的。即使 Backup 节点优先级更高,它启动时也会先进入 BACKUP 状态,然后通过选举抢占成为 MASTER。interface:务必填写正确!使用ip addr或ifconfig命令查看你的实际网卡名,可能是eth0、ens160、enp0s3等,填错会导致虚拟 IP 绑定失败。virtual_router_id:范围 0-255,同一组内必须完全相同。不同组的 ID 必须不同,否则会互相干扰。priority:优先级是选举的核心。Master 的优先级必须高于 Backup。通常 Master 设为 100,Backup 设为 90。通过weight机制可以实现动态调整。advert_int:心跳间隔。1秒是默认值,在网络良好的内网中完全没问题。authentication:简单的密码认证,防止网络内其他机器误配置加入同一个 VRRP 组造成混乱。生产环境建议使用。virtual_ipaddress:可以配置多个虚拟 IP,每行一个。支持指定子网掩码。track_script:将健康检查脚本与 VRRP 实例关联起来。
4.2 启动服务与验证虚拟 IP
配置完成后,在两台服务器上启动 Keepalived 并设置开机自启。
systemctl start keepalived systemctl enable keepalived检查服务状态和日志:
systemctl status keepalived journalctl -u keepalived -f # 动态查看日志关键验证步骤:
查看虚拟 IP 绑定:在初始 Master(node-01)上执行
ip addr show ens33(替换为你的网卡名)。你应该能在输出中看到两个 IP,一个是物理 IP192.168.1.101,另一个就是虚拟 IP192.168.1.100。inet 192.168.1.101/24 brd ... scope global ens33 inet 192.168.1.100/32 scope global ens33而在初始 Backup(node-02)上,应该只能看到物理 IP
192.168.1.102,没有虚拟 IP。访问虚拟 IP:在你的个人电脑或同一网络的其他机器上,打开浏览器,访问
http://192.168.1.100。你应该能看到来自Master 节点的欢迎页面:“This is Nginx Master Node - 192.168.1.101”。这说明流量通过虚拟 IP 正确路由到了 Master 服务器。检查 Keepalived 日志:在 Master 节点上查看日志,应该能看到它定期发送 VRRP 通告,并声称自己是
MASTER。在 Backup 节点上,日志会显示它处于BACKUP状态,并接收来自 Master 的通告。
至此,基础的高可用集群已经搭建成功。但搭建成功只是第一步,更重要的是验证它的故障切换能力是否可靠。
5. 高可用功能测试与故障模拟
一个不能经受考验的高可用架构是纸上谈兵。我们必须模拟各种故障场景,验证切换是否如预期般发生。
5.1 模拟主服务器 Nginx 进程故障
这是最常见的场景。Nginx 因为某种原因崩溃了,但服务器本身还在运行。
在 Master (node-01) 上停止 Nginx:
systemctl stop nginx观察健康检查脚本:等待大约 4 秒(
interval 2*fall 2),Keepalived 会执行两次检查脚本,均失败。观察 Keepalived 日志:在 Master 上执行
journalctl -u keepalived -f,你会看到类似以下的日志:... VRRP_Script(chk_nginx) failed (exited with status 1) ... VRRP_Instance(VI_1) Changing effective priority from 100 to 80因为优先级从 100 降到了 80,低于 Backup 的 90,Master 会发送一个优先级为 0 的通告(表示要放弃 Master 身份),然后进入 BACKUP 状态。
观察 Backup 节点:在 Backup (node-02) 上查看日志,会发现它收到低优先级的通告后,自己会转换到 MASTER 状态,并开始发送通告。同时,使用
ip addr命令查看,会发现虚拟 IP192.168.1.100已经绑定到了 node-02 的网卡上。验证访问:再次访问
http://192.168.1.100,页面内容应该变成了 “This is Nginx Backup Node - 192.168.1.102”。切换过程对用户来说几乎是瞬间完成的,可能只感觉到一次短暂的卡顿或刷新后内容变化。恢复测试:在 node-01 上重新启动 Nginx:
systemctl start nginx。健康检查脚本会恢复成功,优先级加回 20(注意:weight是负值,成功时不会加回,需要配置weight 20才会增加,我们这里没有配)。由于我们配置了state MASTER和更高的初始优先级,且抢占模式默认开启,当 node-01 的优先级恢复为 100 后,它会重新抢占成为 Master,虚拟 IP 又会漂移回来。你可以通过访问虚拟 IP 和查看ip addr来验证。
5.2 模拟主服务器整机故障(宕机)
这是更彻底的故障模拟,比如直接断电或强制关机。
- 直接关闭 Master (node-01) 的电源,或在虚拟机中将其强制关机。
- 观察 Backup 节点:在 node-02 上,Keepalived 会收不到来自 node-01 的心跳报文。在等待了
3 * advert_int(约3秒)的“沉默期”后,node-02 会判定 Master 失效,自己晋升为 Master,并绑定虚拟 IP。这个过程比 Nginx 进程故障稍慢一点,因为要等待心跳超时。 - 验证访问:访问虚拟 IP,服务应已切换到 node-02。
- 恢复主服务器:重新启动 node-01。它的 Keepalived 进程启动后,会发现自己处于
MASTER状态,但优先级是 100。它会发送 VRRP 通告。此时网络中存在两个 MASTER(node-02 在故障期间已成为 MASTER),但 node-01 的优先级更高(100 > 90),因此会发生抢占。node-02 收到更高优先级的通告后,会退位为 BACKUP,并释放虚拟 IP。虚拟 IP 最终会回到 node-01。
5.3 测试脑裂与避免
脑裂是指在高可用集群中,由于网络分区等原因,导致两个节点都认为自己是 Master,并且都绑定了虚拟 IP。这会造成 IP 冲突,服务混乱。
在我们的简单主备模式下,通过 VRRP 的优先级和心跳机制,脑裂通常发生在网络链路出现问题,但两台服务器本身都健康运行时。例如,连接两台服务器的交换机故障,导致它们彼此无法通信,但都能连接客户端网络。
如何测试?可以在防火墙规则中临时丢弃 VRRP 组播包,模拟网络隔离。
如何避免?
- 使用更可靠的心跳链路:如果条件允许,可以使用直连网线或独立的心跳网络用于 VRRP 通信,与业务网络分离。
- 配置多播检测:一些高级配置可以利用额外的脚本检测网络多播是否正常。
- 第三方仲裁:对于更严格的场景,可以引入第三方仲裁节点,当两节点无法通信时,由仲裁节点决定谁应该是 Master。
对于大多数内部网络环境,脑裂发生概率较低。我们的基础配置已经能应对服务器进程和整机故障。了解这个现象及其成因,在排查复杂问题时非常有用。
6. 生产环境进阶配置与优化
基础搭建完成后,我们需要考虑如何让它更稳定、更易运维,适应生产环境的要求。
6.1 增强型 Nginx 健康检查
之前的检查脚本比较简单。生产环境中,我们可能需要更精细的控制。
检查特定 URL:如果你的 Nginx 承载了多个应用,可以检查一个专用于健康检查的 URL,这个 URL 能反映核心应用的状态。
# /etc/keepalived/check_nginx.sh #!/bin/bash CHECK_URL="http://localhost/health" RESPONSE=$(curl -s -o /dev/null -w "%{http_code}\n" --connect-timeout 2 --max-time 3 ${CHECK_URL}) if [ "${RESPONSE}" = "200" ]; then exit 0 else logger -t keepalived "Nginx health check failed with code: ${RESPONSE}" exit 1 fi在 Nginx 配置中,你需要添加一个返回 200 状态的
/health路径。检查多个业务端口:如果 Nginx 同时监听 80 和 443,最好都检查。
失败后尝试重启:在脚本中,当检查失败时,可以先尝试一次本地重启 Nginx,如果重启成功则退出 0,避免不必要的切换(因为切换本身也有代价)。但要注意重启超时问题,避免脚本长时间卡住。
if [ "${RESPONSE}" != "200" ]; then systemctl try-restart nginx sleep 2 # 再次检查 RESPONSE=$(curl -s -o /dev/null -w "%{http_code}\n" --connect-timeout 2 --max-time 3 ${CHECK_URL}) if [ "${RESPONSE}" = "200" ]; then logger -t keepalived "Nginx restarted successfully." exit 0 else logger -t keepalived "Nginx health check failed even after restart." exit 1 fi fi
6.2 使用邮件或通知脚本告警
Keepalived 状态变化时,可以触发通知脚本,以便运维人员及时知晓。
在global_defs部分可以配置邮件 SMTP 服务器,并在vrrp_instance中配置通知脚本。但更灵活的方式是使用自定义的notify脚本。
vrrp_instance VI_1 { ... notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" ... }创建通知脚本/etc/keepalived/notify.sh:
#!/bin/bash TYPE=$1 NAME=$2 STATE=$3 case $STATE in "MASTER") # 执行成为Master后的操作,如启动某些服务、发送告警邮件/钉钉/企业微信 echo "$(date) - I am the MASTER now. Host: $(hostname)" >> /var/log/keepalived-state.log # 调用发送告警的函数,例如 send_alert "Keepalived MASTER" "Node $(hostname) is now MASTER for VI_1" ;; "BACKUP") echo "$(date) - I am the BACKUP now. Host: $(hostname)" >> /var/log/keepalived-state.log # 可以执行关闭非必需服务的操作 ;; "FAULT") echo "$(date) - I am in FAULT state. Host: $(hostname)" >> /var/log/keepalived-state.log # 发送严重告警 ;; *) echo "Unknown state" exit 1 ;; esac记得给脚本加执行权限chmod +x。
6.3 配置日志与监控
清晰的日志是排查问题的生命线。
调整 Keepalived 日志级别:默认日志可能在
/var/log/messages或journalctl中。你可以在/etc/sysconfig/keepalived中修改启动参数,将日志输出到独立文件。# 在 /etc/sysconfig/keepalived 中修改 KEEPALIVED_OPTIONS="-D -S 0 -l /var/log/keepalived.log"-D输出详细日志,-S指定 syslog 设备,-l指定日志文件。修改后重启服务。监控虚拟 IP:在监控系统(如 Zabbix, Prometheus)中,可以添加对虚拟 IP 的 ping 检测或端口检测,作为业务可用性的最上层监控。
监控 Keepalived 进程和状态:监控系统可以检查
keepalived进程是否存在,或者通过ip addr命令解析出本机是否持有虚拟 IP,作为集群状态的监控。
7. 常见问题排查与运维技巧
即使配置再仔细,运维中总会遇到问题。这里记录一些我踩过的坑和排查思路。
7.1 虚拟 IP 无法绑定或访问
- 症状:Keepalived 服务运行正常,但
ip addr看不到虚拟 IP,或者无法从其他机器 ping 通/访问该虚拟 IP。 - 排查步骤:
- 检查网卡名称:
interface配置错误是最常见的原因。用ip link show确认网卡名。 - 检查防火墙:VRRP 协议使用 IP 协议号112和组播地址224.0.0.18。确保防火墙放行了这些通信。可以临时关闭防火墙测试。
# 对于 firewalld,永久放行 VRRP firewall-cmd --permanent --add-rich-rule='rule protocol value="vrrp" accept' firewall-cmd --reload - 检查网络配置:确保两台服务器在同一个二层网络(同一个 VLAN/子网),VRRP 组播包才能到达对方。
- 检查日志:
journalctl -u keepalived查看是否有权限错误、配置解析错误等。 - 检查 IP 冲突:网络中是否已经存在
192.168.1.100这个 IP?可以用arping命令检查。
- 检查网卡名称:
7.2 主备切换不成功或延迟高
- 症状:主服务器明显故障(如关机),但备服务器很久才接管,或者一直不接管。
- 排查步骤:
- 查看 Backup 日志:确认 Backup 是否收到了 Master 的故障通告。如果没收到,问题出在网络或 Master 的 Keepalived 进程上。
- 调整
advert_int和超时:默认advert_int 1,超时是3 * advert_int。你可以适当调小advert_int(如 1)来加快检测,但会增加网络负担。也可以直接配置vrrp_instance中的garp_master_delay和garp_master_refresh等参数来调整免费 ARP 的发送。 - 检查抢占模式:如果不想让原 Master 恢复后抢回 VIP,可以在
vrrp_instance中设置nopreempt。但通常我们期望它抢回。 - 检查健康检查脚本:脚本执行是否超时?脚本本身是否有语法错误?在脚本中增加日志输出
echo "$(date) Check result: $?" >> /tmp/check.log来调试。
7.3 脑裂问题排查
- 症状:两台服务器上都绑定了虚拟 IP,网络中出现 IP 冲突告警,服务访问不稳定。
- 应急处理:立即登录其中一台服务器,手动停止 Keepalived (
systemctl stop keepalived),让另一台单独提供服务。然后排查网络问题。 - 根本原因排查:
- 网络链路:检查连接两台服务器的交换机、网线、物理网卡。是否有丢包、闪断?
- 防火墙规则:确认没有规则阻止了
224.0.0.0/24这个组播网段的通信。 - 配置不一致:极少数情况下,
virtual_router_id或authentication配置错误,可能导致它们加入了不同的逻辑组,但又配置了相同的虚拟 IP。
7.4 日常运维命令备忘
查看当前状态:
systemctl status keepalived ip addr show dev ens33 # 查看VIP绑定情况 journalctl -u keepalived --since "5 minutes ago" # 查看近期日志手动强制切换(谨慎使用):在 Master 上,可以通过发送信号来降低优先级,触发切换。
# 查找 Keepalived 的 master 进程 PID ps aux | grep keepalived | grep -v grep # 向该进程发送 SIGUSR1 信号,其优先级会降低(需在编译时开启相应功能,默认可能不支持) # 更安全的方式是直接修改配置文件,降低 priority,然后 reload最干净的方式是:在 Backup 上临时提高其优先级(修改配置并
systemctl reload keepalived),使其抢占。测试完成后改回。配置文件检查:在重启前,务必检查配置语法。
keepalived -t -f /etc/keepalived/keepalived.conf如果显示
Configuration file is OK,再执行systemctl reload keepalived平滑重载配置。