资讯动态

从零搭建不依赖共享存储的高可用方案:keepalived核心原理与配置实践

发布时间:2026/10/18 9:06:19 来源:尧图企业网站定制
3-keepalived从零搭建一套不依赖共享存储的高可用方案我最早接触 keepalived是因为一台承载核心业务的服务器半夜挂了凌晨两点接到电话赶到机房重启前端客户电话已经打爆了。第二天复盘时技术负责人只问了一句为什么没有做高可用从那天开始我认真研究了 keepalived然后在多个项目里落地经历过不少奇奇怪怪的坑也对它的原理和配置有了比较深入的了解。keepalived 是一个用 C 语言编写的路由软件核心能力是在一组 Linux 服务器之间提供高可用性通过 VRRP虚拟路由冗余协议实现。简单说它就是一群服务器之间选出一个“老大”平时老大干活给外界提供一个虚拟 IP一旦老大出问题老二马上接管这个虚拟 IP继续干活。客户端访问的是一个固定的虚拟 IP不会感知到后端的任何变化。我们最常见的用法就是两台服务器一主一备通过 keepalived 管理一个 VIPVirtual IP配合 Nginx、业务系统、数据库等实现故障自动切换。这篇内容适合正在做系统高可用改造的运维工程师、开发工程师也适合刚接触 Linux 集群的初学者参考。整个方案不依赖共享存储不需要一台额外的调度机做负载均衡只要两台普通服务器就能在分钟级甚至秒级内完成故障切换实用性很强。我会从原理讲起一步步说清配置怎么写、脚本怎么调、脑裂怎么防、问题怎么查。1. 整体设计与方案思路1.1 为什么选择 keepalived很多人在做高可用时第一反应是上负载均衡集群比如 LVS、HAProxy、Nginx 反代加后端集群。但这类方案通常需要额外的调度节点而且调度器本身也存在单点故障的隐患。如果业务规模不大后端只有两三台机器最简单的目标只是“服务器别突然不可用”那么 keepalived 是最经济、最直接的选择。keepalived 本身不承担业务流量转发它的职责是判断节点的存活状态维持 VIP 的归属权。VIP 在主节点上时主节点承担所有业务请求主节点发生故障宕机、网络异常、服务进程崩溃后备节点接管 VIP对外提供服务。这个切换过程对客户端是透明的因为 VIP 本身没有变变化的只是底层绑定了哪台机器、对应哪台服务器的 MAC 地址。以我的实际项目为例某公司的一套会员服务部署在两台 ECS 服务器上前面没有额外的 SLB云负载均衡器直接用 keepalived 管理一个内网 VIP比如 192.168.20.100客户端连这个 VIP 访问会员服务。整套方案只需要两台服务器和相关软件零额外成本故障切换时应用基本无感知。1.2 VRRP 协议与 VIP 漂移原理keepalived 之所以能工作底层依赖的是 VRRP 协议。VRRP 是标准协议本质上解决的是“一组路由器如何共享一个虚拟 IP”的问题。它把多台设备组织成一个虚拟路由器对外呈现实一个 IP组内设备通过选举机制选出一台 Master 和一台或多台 Backup。VRRP 报文是组播发送的默认组播地址是 224.0.0.18源 IP 是这台机器的物理 IP目的是让同一虚拟路由器内的其他成员能收到心跳。Master 周期性地发送 VRRP 通告报文默认间隔 1 秒Backup 如果在 3 个通告周期即 3 秒内没有收到 Master 的消息就认为主节点失联自己升级为 Master。这里必须注意VRRP 是基于多播的所以两台机器的网卡必须允许组播报文通过防火墙、云安全组都要放行相关协议。VIP 漂移的本质是 MAC 地址与 IP 地址的对应关系发生变化。Master 正常时VIP 对应的 MAC 是主节点的虚拟 MAC00:00:5E:00:01:XX 这种格式切机后备节点发出免费 ARP 报文把 VIP 重新映射到自己的 MAC 地址上。局域网内的交换机、路由器、其他服务器收到免费 ARP 后会更新自己的 ARP 缓存表流量自然转向新节点。1.3 方案选型的决策逻辑很多人会问keepalived 好还是用云厂商的负载均衡好这取决于场景。如果业务本身就在物理机房或者是云上预算有限的内部系统keepalived 完全可以承担重任。但如果业务流量非常大、需要弹性扩缩容、需要多活多地域容灾那就用云上的 LB 更合适。keepalived 的定位是高可用而不是负载均衡理解这一点就不会在业务架构上做出错误决策。此外keepalived 不仅可以管理一个虚拟 IP还可以同时管理多个 VIP同一组服务器上可以跑多个独立的高可用业务只要配置多个 vrrp_instance 即可。这个特性在多业务独立高可用场景中非常有价值一台备机可以同时充当多个业务的备节点。2. 环境准备与基础安装2.1 服务器与网络规划以最常见的双节点架构为例我先列出基础环境。这里用两台 CentOS 7 或 8 系统的服务器我实测时用的 CentOS Linux release 8.4配置不需要太高2C4G 就够跑 keepalived 本身主要资源还是留给业务程序。我在某项目中采用了如下规划项目主机A主主机B备角色MASTERBACKUP物理 IPeth0192.168.20.11192.168.20.12VIP192.168.20.100192.168.20.100优先级10090业务Nginx Web服务Nginx Web服务操作系统CentOS 8.4CentOS 8.4需要注意一点VIP 必须和两台物理服务器处于同一个二层网络内也就是说它们一定在同一个网段、同一个交换机或虚拟交换机下。如果两台机器跨网段、跨机房VRRP 组播包无法直接互通keepalived 无法生效。跨机房的高可用需要换另一种思路比如 DNS 切换、双活网关等不是 keepalived 擅长的事。2.2 安装 keepalived安装步骤非常简单。CentOS/RHEL 环境直接用包管理器装sudo yum install -y keepalived nginxUbuntu/Debian 环境用 aptsudo apt install -y keepalived nginx安装完成后直接启动默认配置是没意义的因为默认配置里没有定义任何 VRRP 实例。我们要做的第一件事是备份默认配置然后写自己的配置。sudo cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak有的系统装完 keepalived 可能没有创建 keepalived.conf 文件这也不影响可以自行创建。服务启动时如果找不到配置会打印错误日志但不会退出这个会在排障部分展开。注意keepalived 的配置文件路径是 /etc/keepalived/keepalived.conf默认没有安装 web 界面或管理工具所有配置都是文本编辑。修改配置后必须重启 keepalived 服务或者给进程发送信号重载配置。2.3 开启内核转发与防火墙放行我在一次实施中漏掉了防火墙规则结果 VIP 始终无法漂移排查了很久。后来抓包才发现VRRP 的组播包被防火墙拦截了。这个坑必须提前提。如果服务器开启了 firewalld需要放行 VRRP 协议。VRRP 协议使用的 IP 协议号是 112不是 TCP/UDP 端口所以一般的端口放行规则不适用sudo firewall-cmd --add-rich-rulerule protocol valuevrrp accept --permanent sudo firewall-cmd --reload如果使用 iptables命令如下sudo iptables -I INPUT -p vrrp -j ACCEPT如果两台服务器都是内网机器访问控制层面比较宽松也可以直接关闭防火墙前提是安全合规允许。但我的建议是尽量开启防火墙但务必放行 VRRP 协议。否则你可能遇到“两台机器服务都正常但 keepalived 就是切不过去”的怪问题。云服务器还需要在安全组无论内网还是外网中放行协议类型为 VRRP 或 IP 协议号 112 的入方向流量。不同云平台叫法不同但都提供类似“自定义 IP 协议”的安全组配置项。3. 核心配置详解与实操3.1 单一实例配置分析主节点的 /etc/keepalived/keepalived.conf 文件我给出的核心配置如下! Configuration File for keepalived global_defs { router_id LVS_MASTER vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_script check_nginx { script /etc/keepalived/check_nginx.sh interval 2 weight -20 fall 2 rise 2 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.20.100/24 dev eth0 label eth0:1 } track_script { check_nginx } }备节点的配置差异非常小vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 90 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.20.100/24 dev eth0 label eth0:1 } track_script { check_nginx } }对照着看MASTER 和 BACKUP 的区别仅仅是 state 和 priority。备节点的 state 是 BACKUPpriority 是 90其他配置完全一致。这里有两个细节需要强调virtual_router_id 必须一致。两台机器的 virtual_router_id 必须相同否则 VRRP 报文无法互相识别无法选举。取值范围 0-255默认 51同一个网段内不能有多个 keepalived 集群使用相同的 router_id否则会冲突。认证密钥必须一致。auth_pass 只有前 8 位有效而且明文存于配置文件中。虽然 VRRP 的认证机制在标准里存在但并不是强加密不要把它当作安全措施它只是防止误配或同网段的意外干扰。3.2 配置项逐行解读很多新手直接复制配置但不知道每一行是干嘛的出了问题无从排查。我把关键配置项逐行解释清楚。global_defs块router_id是路由器标识理论上取一个全局唯一的名字但不参与协议协商只用于日志和告警邮件的标识。两台机器用不同名字即可。vrrp_skip_check_adv_addr跳过通告地址检查。如果网卡有多个 IP不启用此项可能因为地址冲突导致通告被拒绝建议保持启用。vrrp_strict严格遵守 VRRP 规范。这会导致 keepalived 不接收 VIP 相关的 ARP 请求以外的报文也可能限制对 VIP 的 ping 响应。生产环境中我建议关闭这个选项也就是注释掉这一行否则会出现 VIP 能漂移但是 ping 不通的现象非常迷惑。vrrp_garp_interval发送 gratuitous ARP 报文的时间间隔设为 0 表示尽快响应vrrp_gna_interval是忽略通告间隔设为 0 即可。这两个参数在每次状态变化时生效决定了客户端 ARP 表更新的快慢。vrrp_instance块state在非抢占模式下初始状态是 MASTER 还是 BACKUP 影响不大因为之后会有一次选举。在抢占模式下优先级高的会成为 MASTER。interface指定实例运行在哪个物理网卡上通常就是服务器连接业务网络的网卡比如 eth0。priority取值范围 1-254数字越大优先级越高。备节点要低于主节点差值最好在 20 以上避免因为主节点优先级抖动导致频繁切换。这里是 100 和 90差 10 也够用但我更推荐 100 和 80更保险。advert_int是 VRRP 通告间隔单位秒默认 1 秒。如果当前网络状况较差可以调大到 2 或 3减少组播包数量但故障发现时间也会相应变长。我生产环境保持 1切换快。nopreempt是非抢占模式。配置了 nopreempt 后即使原主节点恢复优先级更高它也不会立刻抢回 VIP而会继续等待当前主节点故障后再在下一轮选举中重新获得主身份。这在很多场景下很有用避免主备来回切换造成抖动。注意用了 nopreempt 后两台机器的 state 都应该设置为 BACKUP这是很多人容易忽略的细节。如果 state 还是 MASTER非抢占可能不生效。authentication配置认证方式这里用最简单的 PASS 认证key 是明文。virtual_ipaddress定义 VIP 地址。192.168.20.100/24 dev eth0 label eth0:1表示 VIP 绑定到 eth0 网卡网卡别名设置为 eth0:1。设置 label 的好处是执行ip addr show时能一眼看出哪个是 VIP 绑定的地址。track_script关联健康检查脚本我们在这一节里专门讲。3.3 抢占模式与 nopreempt 的权衡在默认配置不带 nopreempt下如果主节点恢复它会立即抢回 VIP。这在很多场景下是合理的因为主节点通常配置更高、性能更强。但若主节点是因为负载过高或网络抖动而临时失联恢复后抢占会导致一次不必要的闪断对长连接业务不够友好。我踩过一个真实案例某系统主节点发生了两秒的网络抖动备用节点接管了 VIP但随后主节点网络恢复又立刻抢回 VIP。这样一段时间内发生了两次切换前端出现间歇性连接重置。后来我启用了 nopreempt并把两台实例的 state 都设为 BACKUP此后只在真正主节点故障时才会切换切换次数明显降低。需要理解的是nopreempt 只会抑制“恢复后抢占”不会抑制“故障后接管”。所以它的代价是如果恢复的主节点的确更想工作也只能等待下一轮故障。这个取舍要根据业务场景来定如果业务更看重稳定性而不是极致性能建议开启 nopreempt。4. 健康检查脚本与业务联动4.1 为什么要写健康检查脚本默认情况下keepalived 只能通过 VRRP 报文检测对端主机是否存活它并不知道主机上的 Nginx 进程是否正常、Web 服务是否还能响应。如果 Nginx 挂了主节点还活得好好的keepalived 依然认为一切正常VIP 不漂移流量还是会打到已经无法服务的进程上。这在用户侧的表现就是“网页打不开但服务器还活着”。要解决这个问题必须引入业务层面的健康检查。常规做法是写一个脚本周期性地检查关键进程、端口或 URL把检查结果反馈给 keepalived一旦发现异常脚本返回非零值keepalived 降低本机的 priority让备用节点接管 VIP。4.2 check_nginx.sh 脚本的写法我常用的检查脚本如下#!/bin/bash nginx_process_num$(ps -ef | grep nginx | grep -v grep | wc -l) if [ $nginx_process_num -eq 0 ]; then echo nginx is down exit 1 fi exit 0这个脚本检查 nginx 是否有进程在运行。ps -ef列出所有进程grep nginx匹配进程名grep -v grep排除掉 grep 自身最后 wc -l 统计行数。如果行数为 0说明 Nginx 没有运行脚本返回 1失败否则返回 0正常。如果业务还依赖 Web 服务响应可以增加一个更严格的检查比如用 curl 去访问一个固定的健康检查地址#!/bin/bash HTTP_CODE$(curl -s -o /dev/null -w %{http_code} http://127.0.0.1/health) if [ $HTTP_CODE -ne 200 ]; then echo http check failed, code: $HTTP_CODE exit 1 fi exit 0这一段用curl -s -o /dev/null -w %{http_code}只获取 HTTP 状态码如果状态码不是 200就返回失败。需要注意curl命令的返回值如果超时也会非零脚本里可以设置超时时间HTTP_CODE$(curl -s --connect-timeout 3 --max-time 5 -o /dev/null -w %{http_code} http://127.0.0.1/health)超时设置非常重要。我在生产环境遇到过 curl 因为后端进程假死而长时间挂起脚本一直不返回keepalived 无法判断健康状态VIP 迟迟不切。加了--max-time 5之后5 秒内没响应就判定失败切换动作就果断多了。4.3 脚本权限与执行权限脚本写完后需要赋予可执行权限sudo chmod x /etc/keepalived/check_nginx.shkeepalived 执行脚本的用户是 root但如果脚本没有执行权限日志会报Track script script not found or not executable。我最初每次配置完脚本都会忘记 chmod然后看日志一脸懵。这个坑出现的频率非常高。4.4 用 track_script 和 weight 控制优先级在 keepalived 配置中vrrp_script定义一个脚本track_script在实例中引用它。关键是 weight 参数它定义了脚本检查失败后本机优先级的变化量。vrrp_script check_nginx { script /etc/keepalived/check_nginx.sh interval 2 weight -20 fall 2 rise 2 }解释一下关键参数interval 2脚本每 2 秒执行一次。weight -20检查失败后本机 priority 减 20。比如主节点 priority 100失败变成 80而备节点 priority 90它就赢过了备节点VIP 切换到备节点。fall 2连续 2 次失败后才判定脚本失败避免偶发抖动。rise 2连续 2 次成功后恢复本机原有 priority避免恢复后立即又切换。weight 的取值需要考虑一个原则权重调整后失败节点的优先级必须低于对端节点的初始优先级。如果主节点 100备节点 99而 weight 是 -1那主节点失败后变成 99与备节点相等选举规则可能进入混乱。我建议 weight 取绝对值大于对端优先级差值的负数这样切换是明确的。上面的配置主备差值 10weight 取 -20无论怎么变化备节点都能稳稳接管。我补充一个实际经验best practice 是把备节点的 priority 设得尽量低比如 50主节点 100然后 weight -60。这样即使主节点只是健康状态差一点、没有完全宕机它也会让出 VIP不会出现两个节点都不愿意放弃 VIP 的边界情况。5. 启动验证与故障切换测试5.1 启动服务与状态查看配置完成后先在主节点启动 keepalivedsudo systemctl start keepalived sudo systemctl enable keepalived在备节点上做同样的操作。然后查看 VIP 归属和 keepalived 状态ip addr show systemctl status keepalived正常状态下主节点的 eth0 上会多出一个 192.168.20.100 的地址而备节点上没有。此时用ip -d addr show eth0:1可以看到 VIP 的详细地址状态ip addr show eth0:1输出的内容类似3: eth0:1: BROADCAST, MULTICAST, UP, LOWER_UP mtu 1500 qdisc noqueue state UP group default qlen 1000 inet 192.168.20.100/24 scope global secondary eth0:1 valid_lft forever preferred_lft forever也可以查看 VRRP 的运行状态journalctl -u keepalived在日志里能看到类似Entering MASTER state或Entering BACKUP state的记录这用来确认实例选举是否正常。5.2 故障切换演练确认正常之后必须做一次实际的切换演练不能只看配置没问题就认为万事大吉。场景一停掉主节点 keepalived 服务sudo systemctl stop keepalived正常情况下3 秒左右或按 advert_int 计算备节点会检测到主节点失联自动接管 VIP。在备节点执行ip addr show eth0应该能看到 192.168.20.100 出现在备节点上。场景二只停掉 Nginx 服务sudo systemctl stop nginx这时主节点 keepalived 还会继续运行但 check_nginx 脚本会在 2 秒内检查到 Nginx 挂掉连续两次失败后4 秒左右主节点优先级降低备节点接管 VIP。这种场景模拟的是业务进程故障而不是主机宕机正是健康检查脚本存在的意义。场景三拔掉主节点网线物理断开主节点网线模拟节点不可达。备节点收不到 VRRP 通告同样会在 3 秒左右接管 VIP。如果之前只做了软件层面的切换务必补上这个硬测试。5.3 使用抓包确认 VRRP 报文如果配置一切正常但 VIP 不漂移可以用 tcpdump 抓包排查sudo tcpdump -i eth0 vrrp -n正常运行时能看到主节点周期性发送的 VRRP 通告报文12:00:01.123456 IP 192.168.20.11 224.0.0.18: VRRPv2, Advertisement, vrid 51, priority 100, authtype simple, intvl 1s, length 20 12:00:02.123456 IP 192.168.20.11 224.0.0.18: VRRPv2, Advertisement, vrid 51, priority 100, authtype simple, intvl 1s, length 20如果看到的是备节点也在发送 Advertisement说明主节点这边自己降级了很可能是健康检查脚本失败或者两个节点都认为自己是 Master出现了脑裂。抓包是排查 VRRP 问题最直接的手段。6. 脑裂问题与常见故障排查实录6.1 脑裂是怎么发生的脑裂是 keepalived 集群最危险的状态两台服务器都认为自己是主节点都绑定 VIP都在对外发送 VRRP 通告。原本的“高可用”会退化成一对不可控的节点对业务产生双重甚至冲突的访问。脑裂的根本原因在于备节点在一段时间内完全收不到主节点的 VRRP 报文。几个典型场景主节点网卡异常、交换机端口故障、网络链路中断。防火墙或云安全组拦截了 VRRP 组播报文最常见的配置型错误。主节点负载过高虽然进程在运行但无法及时发送 VRRP 通告。两台机器之间的组播路径被阻断比如 VLAN 隔离设置错误。脑裂发生后两台机器同时绑定 VIP客户端 ARP 缓存会保留最后一次收到的免费 ARP 对应的记录。如果后端业务是数据库、缓存等要求强一致性的服务脑裂会造成非常严重的数据损坏风险。所以任何高可用方案都必须把脑裂作为一个核心风险来治理。6.2 预防脑裂的常见手段手段一防火墙放行 VRRP。前面反复提过这里再强调一次。配置 keepalived 时先确认防火墙放行情况不要等到脑裂发生后才排查。手段二启用非抢占 足够的优先级差。非抢占模式下即使主节点恢复后也不会立即抢回 VIP这减少了来回切换的概率。优先级差至少要 20让备节点在健康检查失败后自动降级时也能明确让位。手段三用仲裁脚本fencing规避。如果业务允许可以在健康检查脚本里加入“dual check”逻辑如果脚本检测到本机网络故障直接强制清掉 VIP甚至关停网卡。这样可以避免两台机器同时绑定 VIP。这类仲裁逻辑在高可用方案中属于进阶做法但对依赖 keepalived 的关键业务来说值得投入时间。我在某数据库高可用项目中使用 keepalived 管理 MySQL 的 VIP。为了防止脑裂我在健康检查脚本里增加了对另一端节点的网络探测当本机 ping 不通对端节点但自己的业务进程却仍然正常时不主动让出 VIP当自己对端都探测不到且业务持续失败时才主动放弃 VIP。这套逻辑避免了多次脑裂事故。6.3 常见问题速查表下面把我遇到过的典型问题整理成一张速查表方便大家对照排查现象可能原因排查方法解决方案两台机器都是 MASTERVIP 都在防火墙拦截 VRRPutil抓包确认组播是否互通放行 VRRP 协议VIP 不漂移健康检查脚本未执行手动执行脚本查看 keepalived 日志检查脚本权限、路径VIP 可以漂移但 ping 不通vrrp_strict 限制查看日志 / 关闭 strict注释 vrrp_strict切换过于频繁抢占模式 网络抖动看系统日志和切换记录开启 nopreempt备节点没有自动接管主节点 priority 与备节点差值过小调整 weight 和 priority差值至少 20脚本检查偶发失败导致误切换fall 参数太小调整 fall 和 risefall 至少 2服务重启后 VIP 丢失keepalived 未加入开机自启执行 systemctl enable使能自启脑裂期间业务写入冲突无仲裁机制梳理链路增加 fencing 逻辑6.4 一个典型排障过程某次某公司的应用服务频繁出现“访问超时但服务器没有任何异常”的现象。检查系统日志和 nginx 日志也没有报错后来我用 tcpdump 抓包发现主节点每 1 秒正常发送 VRRP 通告备节点却在收到通告后立即也发送通告而且优先级也是 100。这说明备节点的配置文件里 virtual_router_id 和主节点相同但它的 state 被误配置成了 MASTER。两台机器同时认为自己是主节点导致 VIP 在主备之间来回抖动。修复办法很简单把备节点的 state 改成 BACKUP并降低 priority。但这次排查用了近一个小时原因就是一开始没有怀疑是 keepalived 配置问题。后来我总结出一个快速排查流程先看 keepalived 日志journalctl -u keepalived在两端同时抓 VRRP 包看谁在发通告、优先级是多少。检查两端配置文件的 virtual_router_id、state、priority 是否一致或是否符合预期。手动执行健康检查脚本确认脚本返回值和 exit code。对比 ip addr show 两端的 VIP 归属。VIP 只在主节点才生效。这个流程适用于绝大多数 keepalived 故障不是瞎猜而是有依据地逐步缩小范围。7. 进阶优化与落地经验7.1 多实例管理多个 VIP一套 keepalived 实例可以同时管理多个 vrrp_instance每个实例对应一个 VIP。我经常用这个特性把两个业务的高可用合并到同一组机器上。比如vrrp_instance VI_WEB { state BACKUP interface eth0 virtual_router_id 51 priority 100 advert_int 1 nopreempt virtual_ipaddress { 192.168.20.100/24 dev eth0 label eth0:1 } track_script { check_nginx } } vrrp_instance VI_DB { state BACKUP interface eth0 virtual_router_id 52 priority 90 advert_int 1 nopreempt virtual_ipaddress { 192.168.20.101/24 dev eth0 label eth0:2 } track_script { check_mysql } }这样两个独立的业务 VIP192.168.20.100 和 192.168.20.101在同一组机器上运行互不干扰。不同业务可以有不同的健康检查脚本一个实例的故障不会影响另一个实例。这在服务器资源受限、需要承载多个业务高可用的场景下特别实用。但注意 virtual_router_id 要区分开否则会冲突。7.2 与 Nginx 反向代理配合keepalived 最常见的落地方式就是管理 Nginx 的 VIP。架构上Nginx 本身做反向代理或静态资源服务器keepalived 负责 VIP 的漂移。整个方案没有额外的负载均衡器客户访问 VIP 时Nginx 承接请求。如果有多台后端应用服务器可以把 Nginx 的 upstream 配置为多个后端 IP本质上把负载均衡和后端高可用分离开。keepalived 只需要关注 Nginx 本身是否存活后端应用的高可用由应用自身的集群机制负责。这种分层设计是我在多个项目里的标准做法。7.3 keepalived 在云环境中的注意事项在公有云上使用 keepalived需要特别注意一点云平台的安全组过滤规则。有些云平台默认放行全部内网流量但有些默认只放行常见端口VRRP 报文需要单独放行。此外云服务器的网卡可能默认关闭组播功能特别是某些虚拟化平台或不支持 VRRP 协议这会导致 keepalived 无法正常选举。我建议在云上保留 keepalived 作为内部的低成本高可用方案但规模扩大后还是切换到云厂商的负载均衡产品原因有两个云上的 LB 具备全托管、自动扩缩容、健康检查、WAF 等功能运维成本低。keepalived 在云上受限于网络模型跨可用区、跨 VPC 的部署很困难只能做同可用区内的高可用。7.4 日志监控与告警设置keepalived 本身自带邮件告警功能但它依赖本地发送邮件配置繁琐我一般直接丢弃不用改用系统监控平台采集日志或做自定义脚本告警。关键事件是Entering MASTER state、Entering BACKUP state、Keepalived_vrrp: VRRP_Instance(VI_1) entering MASTER state等。可以在日志采集器中配置规则一旦出现关键字就触发告警通知。把切换事件实时推送到告警群是我保证关键业务平稳运行的重要手段之一。我个人的习惯是在一个专用目录比如 /etc/keepalived/scripts/存放所有健康检查脚本文件名有规律check_nginx.sh, check_mysql.sh, check_api.sh每个脚本包含注释头标注用途和检查基线。这样不管过多久回来接手都还能快速理解每段逻辑。7.5 从二次开发到扩展用 notify 脚本做业务联动keepalived 支持配置 notify 脚本在状态发生变化时执行自定义动作。这个能力很有价值比如实现主备切换时自动把 VIP 情况同步到内部 DNS、更新监控平台、发送通知等。配置方式为vrrp_instance VI_1 { notify_master /etc/keepalived/notify_master.sh notify_backup /etc/keepalived/notify_backup.sh notify_fault /etc/keepalived/notify_fault.sh }notify_master 脚本在主节点成为 MASTER 时执行notify_backup 在降级为 BACKUP 时执行notify_fault 在进入 FAULT 状态时执行。脚本里可以调用业务接口、写入标记等。我用这个功能做过一个数据同步开关只有成为 MASTER 的节点才允许写数据库BACKUP 节点保持只读。这样从架构上限制了脑裂时双写的问题效果很好。8. 我个人在实际操作中的体会放到最后说几点经验也是踩过很多次坑之后的总结。第一keepalived 的配置一定要版本化保存。我见过不少服务器配置文件和原始安装完的默认配置混在一起改来改去最后都不知道当前跑的是什么配置。建议把 /etc/keepalived/keepalived.conf 纳入配置管理仓库每次变更都记录 diff。这样排查问题时能快速确认配置是否被意外修改过。第二不要只依赖 keepalived 的默认检查。默认的 VRRP 只是机器存活检测不能代表业务可用。业务侧的健康检查脚本才是真正保障服务质量的关键。脚本要覆盖进程、端口、核心 URL而且要设置超时和失败次数阈值避免抖动导致频繁切换。第三高可用的价值体现在切换演练中。配置完成只能说明 keepalived 启动了不代表高可用真正可用。我会定期做一次切换演练每次演练都记录切换耗时和业务影响范围。切到备机之后要观察一段窗口期确认备机确实承担业务而不是仅仅 VIP 漂移过去但没有流量或服务异常。第四脑裂永远是最大的隐患。无论配置多完美网络抖动、广播风暴、防火墙漂移都可能导致备机升级为 Master。生产环境中我始终坚持给所有涉及写入业务的 keepalived 实例加仲裁或 fencing 逻辑。这个代价是值得的因为这些逻辑永远不会在有事故的时候才想起要补。keepalived 是我用过的成本最低、见效最快的高可用方案它不神秘也不复杂但要注意的细节确实不少。希望这篇文章能帮你在实施高可用方案时少走些弯路把 keepalived 用得更稳。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑