ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

解决服务单点故障!Nginx+Keepalived 双机热备,故障秒切换生产方案

2026/8/14 3:53:55 拓冰建站 浏览量
解决服务单点故障!Nginx+Keepalived 双机热备,故障秒切换生产方案

前言🤔

很多 Linux 小白学习 Keepalived 时全程混乱,普遍存在这些痛点:

  1. 看不懂 VRRP 底层协议,搞不清 VIP、Master、Backup、VRID、优先级核心概念;
  2. 实验逻辑断裂,不知道先配 IP 还是先装软件,敲完上一行完全不知道下一条命令;
  3. 配置文件几十行参数分不清含义,state/priority/nopreempt/auth 完全不懂作用;
  4. 搭建完集群出现脑裂双主抢 VIP,网站同时访问两台服务器,数据错乱找不到原因;
  5. 主节点宕机 VIP 不会自动漂移,切换失败只会盲目重启服务;
  6. 分不清抢占模式、不抢占模式适用场景,线上业务频繁抖动;
  7. 所有命令只会复制,-y、–now、cp {,.ori} 等参数不懂含义,输出结果不会解读。

📌统一实验环境 CentOS7

主机名IP 地址集群角色核心任务
web1.jhl.cloud10.1.8.11Keepalived 主节点(抢占模式)优先持有 VIP,Nginx 业务主服务
web2.jhl.cloud10.1.8.12Keepalived 备节点主故障自动接管 VIP
client1.jhl.cloud10.1.8.21测试客户端访问虚拟 IP 验证业务切换
虚拟 VIP10.1.8.100统一业务访问入口主节点持有,故障自动漂移备机

第一部分 Keepalived&VRRP 底层原理

1.1 Keepalived 是什么?线上运维核心作用⚠️

Keepalived 是 C 语言编写的 Linux 高可用软件,底层依托VRRP 虚拟路由冗余协议,核心解决服务单点故障问题。

企业生产真实价值

  1. 消除单点故障:Nginx、MySQL、Redis等单服务器服务宕机,VIP自动漂移至备机,业务无感知切换;
  2. 统一访问入口:客户端只需要访问一个固定VIP,无需区分后端多台服务器;
  3. 多层故障检测:支持3/4/7层健康检测,网卡、端口、程序故障均可触发自动切换;
  4. 轻量化部署,配置简单,无需额外复杂集群软件,中小企业HA首选;
  5. 配套nopreempt不抢占模式,避免主节点恢复后频繁切流量,保障业务稳定。

1.2 VRRP 协议核心解决的痛点

传统单网关 / 单 Web 服务器一旦宕机,所有客户端完全断网 / 网站打不开;VRRP 将把多台物理服务器,虚拟成一台逻辑上的网关 / 服务器,共用同一个虚拟 IP(VIP),主设备故障时备份设备自动接管 IP,业务不中断。

名词全称通俗解释实验示例
VRRP 组虚拟路由组同一套高可用集群,VRID 必须完全一致VRID 51
VRID虚拟路由 ID区分不同集群,1-255,同组所有机器相同51
VIP虚拟 IP对外统一访问地址,仅 Master 持有10.1.8.100/24
Master主节点优先级更高,正常持有 VIP,每秒发心跳包web1 priority=110
Backup备节点监听心跳,主失联自动升级为主web2 priority=100
Priority优先级数值 0-255,越大越优先抢占 VIP110>100
Advert_int心跳间隔Master 发送 VRRP 心跳包周期,默认 1 秒advert_int 1
组播地址VRRP 通信地址224.0.0.18,节点间心跳通信固定地址UDP 112 端口

1.3 VRRP 完整工作流程🤔

  1. 集群初始化,两台机器全部进入 Backup 状态;
  2. 各自等待 MASTER_DOWN 定时器,优先级高的 web1 更快完成等待,率先竞选 Master;
  3. web1 成为 Master,绑定 VIP 10.1.8.100,每秒向 224.0.0.18 发送心跳通告;
  4. web2 持续监听心跳包,收到则维持 Backup;
  5. web1 宕机 / 关闭 Keepalived,web2 收不到心跳,定时器超时自动升级 Master,绑定 VIP;
  6. web1 恢复服务,抢占模式下立刻夺回 VIP;不抢占模式则保持 web2 为主。

1.4 脑裂(Split-Brain)致命故障解析🚨

脑裂定义:主备节点心跳通信中断,但两台服务器本身正常,两台机器同时竞选Master、同时绑定VIP,客户端流量分裂,读写业务出现数据错乱、页面交替跳转。 产生核心原因:

  1. 服务器之间UDP 112端口防火墙拦截,心跳包无法互通;
  2. 网卡故障、交换机链路断开,组播报文无法传输;
  3. 集群VRID、认证密码配置不一致,节点无法识别同组设备;
  4. 服务器CPU/内存耗尽,无法发送心跳包。

脑裂线上危害:数据库双写冲突、网站随机跳转,业务完全不可用!

5套生产脑裂预防方案表格
方案实操配置核心作用
VRRP 密码认证所有节点 auth_pass 配置完全一致拒绝非法节点加入集群,防止异常节点抢占 VIP
放行 VRRP 协议firewall-cmd --add-protocol=vrrp --permanent && firewall-cmd --reload打通 112 端口 VRRP 心跳通信,确保节点间心跳报文正常传输
多网卡心跳检测track_interface 配置多块物理网卡单网线 / 网卡故障时,自动通过备用网卡传输心跳,避免心跳中断
nopreempt 不抢占模式高优先级节点配置中添加 nopreempt 参数主节点故障恢复后,不强行抢占 VIP,避免业务流量频繁切换抖动
故障隔离脚本配置 notify_master 监控脚本检测到脑裂 / 双主异常时,自动执行关机 / 停服务脚本,实现故障隔离

1.5 Keepalived 三层检测机制

  1. 三层网络层(ICMP):ping 检测对端 IP,不通判定故障;
  2. 四层传输层(TCP 端口):检测 80/22 等端口,Nginx 宕机自动切换;
  3. 七层应用层(自定义脚本):执行业务脚本,程序异常触发 VIP 漂移。

第二部分 完整高可用集群实验

业务诉求:希望有一个永不变化的统一访问入口,一台 web 坏了,另一台自动顶上,全程不需要人工操作,用户感知不到故障。
实现这个诉求的技术方案,就是 Keepalived + VRRP 虚拟 IP(VIP)高可用架构,也就是本次实验要验证的能力。

实验最终想要验证的目标

  1. 对外提供一个固定不变的虚拟 IP VIP=10.1.8.100,用户永远只访问这个地址;
  2. 正常情况下 VIP 在主节点 web1;客户端访问 VIP,流量落到 web1 处理网页请求;
  3. 当 web1 故障(关机、断网、web 服务停止),VIP自动漂移到备机 web2
  4. 客户端继续访问 10.1.8.100,流量自动切换到 web2,用户不用修改任何地址,无感知切换
  5. web1 故障修复上线后,可以配置两种策略:
    • 抢占模式:web1 恢复后,VIP 重新抢回来;
    • 非抢占模式:VIP 继续留在 web2,避免二次波动。

实验价值:

这个实验就是模拟线上服务器故障场景,验证 VRRP 协议实现虚拟 IP 自动故障转移搭建一套具备自动容灾能力的 Web 服务集群,解决单点服务器故障导致业务中断的问题,理解生产环境高可用服务最基础、最经典的主备架构原理。

结合拓扑完整复盘整条访问链路

正常状态

client1 (10.1.8.21) →交换机 →访问 VIP (10.1.8.100) →web1 (持有 VIP) →返回网页

故障状态

web1 宕机 →VIP 自动漂移 web2

client1 (10.1.8.21) →交换机 →访问 VIP (10.1.8.100) →web2 (持有 VIP) →返回网页

用户全程只访问 10.1.8.100,后端服务器切换完全透明。

实验思路:

  1. 三台机器分别修改主机名、配置静态固定 IP;
  2. web1、web2 两台服务器安装 Nginx,写入区分页面;
  3. web1、web2 安装 Keepalived,备份原始配置文件;
  4. 编写主节点 web1 抢占模式配置(priority110、state MASTER);
  5. 编写备节点 web2 配置(priority100、state BACKUP);
  6. 两台服务器防火墙放行 VRRP 协议;
  7. 启动 Keepalived,验证 VIP 默认在 web1;
  8. 客户端 curl VIP 访问,页面返回 web1 内容;
  9. 停止 web1 Keepalived,验证 VIP 自动漂移 web2;
  10. web1 重启服务,抢占模式下自动夺回 VIP;
  11. 进阶不抢占模式实验:修改 web1 配置增加 nopreempt,主恢复不切流量;
  12. 配置 Keepalived 独立日志,方便故障排查;
  13. 脑裂模拟与修复实操。

实验1 三台机器初始化(主机名 + 静态 IP)

实验目的🤔

固定静态 IP 防止 DH 地址变动导致心跳通信失败,区分三台机器角色,方便后续实验操作。

线上运维作用

高可用集群必须静态 IP,动态 IP 会导致 VRRP 心跳永久中断,直接触发脑裂故障。

一、web1.jhl.cloud 全套命令(每行逐项参数解释,保留完整提示符)

# hostnamectl set-hostname:永久修改系统主机名,重启永久生效# set-hostname 后跟自定义完整主机域名[root@localhost ~]# hostnamectl set-hostname web1.jhl.cloud# nmcli connection modify:修改网卡参数,ens33为网卡设备名# ipv4.method manual:关闭DH,启用静态IP手动模式# ipv4.addresses 10.1.8.11/24:本机IP,/24代表24位子网掩码# ipv4.gateway 10.1.8.2:内网网关地址# ipv4.dns 10.1.8.2:内网DNS解析服务器# autoconnect yes:开机自动激活网卡[root@localhost ~]# nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.11/24 ipv4.gateway 10.1.8.2 ipv4.dns 10.1.8.2 autoconnect yes# nmcli connection up:重载网卡配置,无需重启立即生效# up 参数:启用网卡连接,应用刚修改的静态IP配置[root@localhost ~]# nmcli connection up ens33

二、web2.jhl.cloud 全套初始化命令

[root@localhost ~]# hostnamectl set-hostname web2.jhl.cloud[root@localhost ~]# nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.12/24 ipv4.gateway 10.1.8.2 ipv4.dns 10.1.8.2 autoconnect yes[root@localhost ~]# nmcli connection up ens33

三、client1.jhl.cloud 全套初始化命令

[root@localhost ~]# hostnamectl set-hostname client1.jhl.cloud[root@localhost ~]# nmcli connection modify ens33 ipv4.method manual ipv4.addresses 10.1.8.21/24 ipv4.gateway 10.1.8.2 ipv4.dns 10.1.8.2 autoconnect yes[root@localhost ~]# nmcli connection up ens33

实验 2 两台 Web 服务器部署 Nginx 业务

实验目的🤔

搭建后端 Web 服务,用于验证 VIP 切换后页面自动变更,直观观察故障漂移效果。

运维作用

模拟企业网站业务,完整复现线上 Web 高可用架构。

web1、web2 两台服务器统一执行全套命令

# wget:下载阿里EPEL软件源# -O 参数:指定下载文件输出路径[root@web1 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo# yum install -y:yum在线安装软件# -y 参数:自动确认所有交互提问,无需手动输入y# nginx:Web网站服务程序[root@web1 ~]# yum install -y nginx# echo 输出文本重定向写入网站首页# $(hostname) 自动获取本机主机名,区分两台服务器页面[root@web1 ~]# echo Welcome to $(hostname) > /usr/share/nginx/html/index.html# systemctl enable --now:设置开机自启并立刻启动服务# enable:开机自动运行;--now:当前会话立即启动;nginx:服务名[root@web1 ~]# systemctl enable nginx.service --now

客户端测试业务连通性

# curl:HTTP访问工具,直接输出页面内容[root@client1 ~]# curl 10.1.8.11Welcome to web1.jhl.cloud[root@client1 ~]# curl 10.1.8.12Welcome to web2.jhl.cloud

实验 3 安装 Keepalived + 备份原始配置

实验目的🤔

安装高可用核心程序,备份默认配置防止改错无法恢复。

web1、web2 两台机器全部执行

# yum安装keepalived高可用软件包[root@web1 ~]# yum install -y keepalived# cp {,.ori} 文件备份语法# cp:复制文件;/etc/keepalived/keepalived.conf 原配置# {,.ori} 等价于复制为 keepalived.conf.ori 备份文件[root@web1 ~]# cp /etc/keepalived/keepalived.conf{,.ori}

实验 4 抢占模式 Keepalived 完整配置(web1 主节点)

实验思路

  1. global_defs 全局段设置 router_id,集群内唯一标识;
  2. vrrp_instance 定义 VRRP 集群,state 初始 MASTER;
  3. priority 110 高于备机,故障恢复自动抢占 VIP;
  4. 开启密码认证,防止脑裂;
  5. 定义虚拟 VIP 10.1.8.100/24。
# vim:文本编辑器打开Keepalived主配置文件[root@web1 ~]# vim /etc/keepalived/keepalived.conf

完整配置逐行逐字段详细注释

!Configuration Fileforkeepalived# 全局配置段 global_defsglobal_defs{router_id web1.jiang.cloud# router_id:本机集群标识,集群所有机器不能重复}# VRRP集群实例,自定义名称nginxvrrp_instance nginx{state MASTER# 机器启动初始状态,仅初始化生效,最终由priority竞选interface ens33# VRRP心跳、VIP绑定的物理网卡virtual_router_id51# VRID集群编号,同组所有机器必须完全一致(1-255)priority110# 优先级,数值越大优先成为Master,高于备机100advert_int1# Master心跳发送间隔,单位秒,默认1秒# VRRP身份认证配置,防止脑裂、非法节点接入authentication{auth_type PASS# 认证类型:PASS明文密码;AH加密认证auth_pass jhl@123# 集群统一密码,所有节点必须完全相同,最多8位有效字符}# 定义集群虚拟VIP地址virtual_ipaddress{10.1.8.100/24}}[root@web1 ~]# ip -br alo UNKNOWN127.0.0.1/8 ::1/128 ens33 UP10.1.8.11/2410.1.8.100/24

重点结论:VIP 出现在 web1机器上,代表当前 web2 已经成为 VRRP 主节点(MASTER),接管了虚拟 IP。

web2 备节点抢占模式配置

[root@web2 ~]# vim /etc/keepalived/keepalived.conf
!Configuration Fileforkeepalived global_defs{router_id web2.jiang.cloud}vrrp_instance nginx{state BACKUP# 备机初始状态interface ens33 virtual_router_id51priority100# 优先级低于web1,正常不会抢占advert_int1authentication{auth_type PASS auth_pass jhl@123}virtual_ipaddress{10.1.8.100/24}}[root@web2 ~]# ip -br alo UNKNOWN127.0.0.1/8 ::1/128 ens33 UP10.1.8.12/24

实验 5 放行 VRRP 防火墙规则(防脑裂核心步骤⚠️)

实验目的

放开 UDP112 端口 VRRP 组播心跳,两台机器可正常收发心跳报文,避免脑裂故障。

web1、web2 两台服务器执行

# firewall-cmd --add-protocol=vrrp:临时放行VRRP协议# --permanent 参数:永久写入防火墙规则,重启不失效[root@web1 ~]# firewall-cmd --add-protocol=vrrp --permanent# --reload:重载防火墙配置,永久规则立即生效[root@web1 ~]# firewall-cmd --reload

实验 6 启动服务,验证 VIP 抢占模式切换

步骤 1 两台机器开机自启并启动 Keepalived

# systemctl enable --now:开机自启+立即启动服务[root@web1 ~]# systemctl enable keepalived.service --now[root@web2 ~]# systemctl enable keepalived.service --now

步骤 2 查看网卡 VIP 绑定状态

# ip -br a show:简洁查看网卡IP地址# -br 参数:brief简洁输出模式,过滤冗余信息[root@web1 ~]# ip -br a show ens33ens33 UP10.1.8.11/2410.1.8.100/24 fe80::xxxx/64# 现象解读:web1持有虚拟VIP,为主节点[root@web2 ~]# ip -br a show ens33ens33 UP10.1.8.12/24 fe80::xxxx/64# 现象解读:web2无VIP,为备份节点

步骤 3 客户端访问虚拟 IP 验证业务

[root@client1 ~]# curl 10.1.8.100Welcome to web1.jhl.cloud# 输出web1页面,当前主节点正常提供服务

步骤 4 模拟主节点故障,停止 Keepalived

# stop:立即停止Keepalived服务,断开心跳发送[root@web1 ~]# systemctl stop keepalived.service# 再次查看web1网卡,VIP消失[root@web1 ~]# ip -br a show ens33ens33 UP10.1.8.11/24 fe80::xxxx/64# web2自动升级Master,绑定VIP[root@web2 ~]# ip -br a show ens33ens33 UP10.1.8.12/2410.1.8.100/24# 客户端再次访问VIP,自动切换web2页面[root@client1 ~]# curl 10.1.8.100Welcome to web2.jhl.cloud

步骤 5 恢复 web1 服务,抢占模式自动夺回 VIP

# start 启动Keepalived服务[root@web1 ~]# systemctl start keepalived.service# 查看web1重新持有VIP[root@web1 ~]# ip -br a show ens33ens33 UP10.1.8.11/2410.1.8.100/24# 客户端页面切回web1[root@client1 ~]# curl 10.1.8.100Welcome to web1.jhl.cloud

⚠️抢占模式缺点:业务高峰期主节点维护重启,流量瞬间全部切回主,会造成业务抖动,生产核心业务推荐不抢占模式!

实验 7 进阶:不抢占 nopreempt 模式(生产推荐)

实验目的🤔

高优先级主节点恢复后,不强行抢占 VIP,流量停留在当前备机,避免业务频繁切换抖动。

完整修改配置(仅 web1 操作)

[root@web1 ~]# vim /etc/keepalived/keepalived.conf

修改后核心片段(新增 nopreempt)

vrrp_instance nginx{state BACKUP# 所有节点统一写BACKUP,不再写MASTERnopreempt# 不抢占开关,高优先级机器恢复不抢VIPinterface ens33 virtual_router_id51priority110advert_int1authentication{auth_type PASS auth_pass jhl@123}virtual_ipaddress{10.1.8.100/24}}

重载配置生效

[root@web1 ~]# systemctl restart keepalived.service

验证不抢占效果

  1. 关闭 web1,web2 接管 VIP;
  2. 启动 web1,web1 优先级 110 更高,但不会抢夺 VIP;
  3. 客户端持续访问,页面始终是 web2;
  4. 只有 web2 停止服务后,web1 才会自动接管 VIP。
# 关闭web1[root@web1 ~]# systemctl stop keepalived.service# web2持有VIP,curl输出web2页面[root@client1 ~]# curl 10.1.8.100Welcome to web2.jhl.cloud# 启动web1,不抢占[root@web1 ~]# systemctl start keepalived.service# 客户端页面不变[root@client1 ~]# curl 10.1.8.100Welcome to web2.jhl.cloud# 关闭web2,web1自动接管[root@web2 ~]# systemctl stop keepalived.service[root@client1 ~]# curl 10.1.8.100Welcome to web1.jhl.cloud

实验 8 Keepalived 独立日志分离(排错必备)

实验目的

默认日志混杂在 /var/log/messages,单独拆分日志方便快速定位 VIP 漂移、脑裂、心跳报错。

1.让 keepalived 把日志发送到 local0 日志设施;
2.配置 rsyslog 抓取 local0 的所有日志,单独保存到 /var/log/keepalived.log,实现日志分离;
3.同时可选开启 debug 模式,打印 VRRP 详细交互过程,方便排错。

步骤 1 修改 keepalived 启动参数

# vim编辑服务启动配置文件[root@web1 ~]# vim /etc/sysconfig/keepalived

修改内容:

# 这个文件是 systemd 启动 keepalived 服务时读取的启动命令行参数。KEEPALIVED_OPTIONS="-D -S 0"# 参数逐项解释:# -D:后台守护进程运行,默认必选# -S 0:指定syslog日志输出通道为local0。keepalived 输出日志时,统一打上 local0.* 标签发给系统 rsyslog 服务。# 补充:-d 开启debug调试日志,排错临时使用,生产不要长期开启

简单类比:
keepalived 生产日志,并盖上一个邮戳 local0;
rsyslog 根据邮戳,决定这份日志投递到哪个文件。

步骤 2 配置 rsyslog 分流日志

rsyslog 格式标准

格式:设施.优先级 存储目标

  • local0:设施(对应上面-S 0),Linux 预留出来给自定义程序使用(local0~local7 共 8 组)
  • *:代表所有优先级(info、notice、warning、error、debug 全部收下)
  • /var/log/keepalived.log:日志写入的独立文件

rsyslog 是 CentOS/RHEL 系统里默认的系统日志服务
服务器上所有程序(systemd、ssh、nginx、keepalived 等)产生的日志,理论上都交给 rsyslog 统一接收、筛选、保存。
默认主配置文件:
/etc/rsyslog.conf

# /etc/rsyslog.d/keepalived.conf,专门给 keepalived 自定义的一条日志过滤规则文件。[root@web1 ~]# vim /etc/rsyslog.d/keepalived.conf# local0通道日志全部输出到独立文件local0.* /var/log/keepalived.log

步骤 3 重启日志服务 + Keepalived

# restart 重启rsyslog日志服务,加载新分流规则,keepalived 日志策略[root@web1 ~]# systemctl restart rsyslog# 让 keepalived 读取 /etc/sysconfig/keepalived 里面新的启动参数 -D -d -S 0。不重启 keepalived,新参数不会生效,依然使用旧的日志输出方式![root@web1 ~]# systemctl restart keepalived.service# 实时监控高可用切换日志# tail -f:实时追踪日志输出[root@web1 ~]# tail -f /var/log/keepalived.log

第三部分 Keepalived 高频故障排查指南🚨

1. 脑裂双主同时持有 VIP

故障根因完整解决方案
防火墙未放行 VRRP 协议执行 firewall-cmd --add-protocol=vrrp --permanent && reload
两台机器 VRID / 认证密码不一致统一 virtual_router_id、auth_pass jhl@123
跨网段组播 224.0.0.18 不通同网段部署,或配置单播 VRRP

2 主节点宕机 VIP 不漂移

  1. 备机防火墙拦截 VRRP 心跳;
  2. advert_int 心跳间隔过大,MASTER_DOWN 超时久;
  3. 网卡名称 interface 配置错误。

3 主恢复频繁抢占,业务抖动

解决方案:主节点配置 nopreempt 不抢占模式。

核心排错命令全注释

# 实时查看Keepalived切换日志tail-f/var/log/keepalived.log# 查看网卡VIP绑定状态ip-bra# 重启服务重载配置systemctl restart keepalived# 查看服务运行状态systemctl status keepalived

文末总结💬

  1. Keepalived 基于 VRRP 协议实现 Linux 服务高可用,虚拟 VIP 是统一业务访问入口;
  2. Master 由 priority 优先级竞选,抢占模式主恢复自动切流量,生产优先 nopreempt 不抢占;
  3. 集群所有节点 VRID、VRRP 密码必须完全一致,防火墙放行 VRRP 协议防止脑裂;
  4. 故障切换逻辑:Master 停止发送心跳→Backup 超时升级为主,自动绑定 VIP;
  5. 线上 Web / 数据库高可用,双机热备是最低成本消除单点故障方案。

互动提问💬 你们线上 Keepalived 用抢占还是不抢占模式?搭建集群踩过脑裂故障吗?评论区交流排坑经验!