LVS以及KeepAlived实现故障转移
发布于2025-03-23 10:59:07,更新于2025-08-03 11:51:59,标签:devops 文章会持续修订,转载请注明来源地址:https://meethigher.top/blog我有多个 Backend,这些 Backend 通过 Nginx 作为 LoadBalancer。当 Nginx 节点出现故障时,整个系统的流量无法正确转发,导致服务不可用。为了确保系统的高可用性,可以引入一个备份 Nginx 节点,并使用 keepalived 来实现故障转移和流量切换。本文目的是学习 keepalived,顺便将其涉及的基础知识也进行了解。
本文按如下顺序,层层递进展开。
- IP 与子网掩码
- 网络基础
- LVS
- keepalived
针对 IP 与子网掩码的基础,此处不做记录。可以参考 IP 与 CentOS7 防火墙基础
一、网络基础
1.1 网络分层模型
计算机网络中,有三种常见的网络分层模型
- OSI 七层模型
- 用途:理论标准
- TCP/IP 四层模型
- 用途:实践标准
- 五层模型
- 用途:教学标准
第一层从表格最下面开始,逐往上递增。
| 代表 | OSI 七层模型 | TCP/IP 四层模型 | 五层模型 |
|---|---|---|---|
| HTTP/HTTPS(网页)、FTP/SFTP(文件传输)、DNS(域名解析)、SSH(远程登录) | 应用层 | 应用层 | 应用层 |
| SSL/TLS(加密传输)、JPEG/PNG(图像编码)、MP4(音频编码)、JSON/XML/Protobuf(数据格式) | 表示层 | ||
| RPC(远程过程调用)、NetBIOS(网络基本输入输出系统)、PPTP(点对点隧道协议) | 会话层 | ||
| TCP(传输控制协议)、UDP(用户数据报协议)、SCTP(流控制传输协议) | 运输层 | 运输层 | 运输层 |
| IP(IPv4/IPv6)、ICMP(控制报文协议)、IGMP(组管理协议)、路由器(Router) | 网络层 | 网络层 | 网络层 |
| Ethernet(以太网)、ARP(地址解析协议)、PPP(点对点协议)、VLAN(虚拟局域网)、MAC(媒体访问控制) | 数据链路层 | 网络接口层 | 数据链路层 |
| 网线、集线器、网络适配器 | 物理层 | 物理层 |
交换机:用于局域网内部的设备互联,让同一网段内的主机能够通信。处于数据链路层。
路由器:连接不同子网,让不同网络之间的数据包能够互通。处于网络层。
1.2 路由器与网关
1.2.1 网关分类
路由器(Router) 是一个设备,用来连接不同子网,并根据 IP 地址进行数据包转发,工作在网络层。
网关(Gateway) 是一个概念,用来连接不同协议或网络,它不仅仅负责转发数据包,还能进行协议转换。可以工作在多个 OSI 层。常用网关如下
- 网络通信网关
- 代表:路由器(OSI 第三层网络层)。
- 解释:路由器作为网关,用来连接不同子网,这包括局域网(LAN)和广域网(WAN)。
- 负载均衡网关
- 代表:负载均衡器,如 Nginx(OSI 第七层应用层)、LVS(OSI 第四层运输层)。
- 解释:负载均衡器作为网关,将流量转发出去。
1.2.2 网络通信网关的触发时机

如果当前机器访问的目标 IP 在本地子网内,数据包就会直接传输,不经过默认网关。
如果当前机器访问的目标 IP 不在本地子网内,数据包就会发送给默认网关,由网关转发到其他子网。
将目标 IP 与子网掩码的二进制进行 AND 运算,如果当前 IP 与子网掩码的运算结果一致,那么就说明在同一个子网内。
就像生活中的送东西,如果近,就自己上门送;如果远,就甩给快递站。
1.3 两子网进行组网通信
1.3.1 环境安装
将以下环境在 Windows11 上按顺序进行安装。相关的内容在 B 站有很多免费的课程。参考

1.3.2 实践
“我要模拟两个子网进行组网,使用 WIFI 即可实现,还有必要使用交换机吗?”
还是有必要的。简单对照两者的优劣,如下。
| 对比点 | Wi-Fi | 有线交换机 |
|---|---|---|
| 灵活性 | 无线连接,设备自由移动,适合动态环境 | 有线固定,设备受限于网线长度与端口位置 |
| 带宽共享 | 所有设备共享局域网带宽。你在下载东西我打游戏就会卡 | 每个物理接口独立带宽,互不影响 |
| 延迟表现 | 延迟较高,易受干扰与墙壁影响 | 延迟低,稳定性强,适合高要求应用 |
| 信号范围 | 信号覆盖有限,可能存在死角 | 信号稳定,不受距离影响 |
| 成本 | 初期投入低 | 初期投入较高,需要交换机和网线 |
| 使用场景 | 家庭、移动设备多、无缝漫游 | 办公室、企业、固定设备多,需高速稳定网络 |
我通过 eNSP 这个网络拓扑模拟器,使用交换机和路由器,两者组合的方式,进行两个子网 10.0.0.0/8 和 192.168.1.0/24 的组网。
如果你安装了其他的虚拟环境,比如 VMware、Docker、WSL、Qemu 之类的,底层虚拟化冲突,可能会出现启动设备失败的问题。
配置拓扑如下

源码示例可以访问 meethigher/ensp-repo: ensp examples 下载 net-test。
下载用 ensp 打开后,针对路由器进行配置。
1 | The device is running! |
用 PC3 去访问 PC1,可以连通,证明组网成功!

1.3.3 理解原理
拓扑图如下,Server1 开启 HTTP 80 端口。

1.) 问题 1:通过 Client1 这台机器请求 Server1 的 80 端口,能否连通?
答:能。由于 Server1 不在 Client1 所处的 10.0.0.0/8 子网内,因此 Client1 会将数据包发送给网关 10.0.0.1,即路由器 1。路由器 1 有两个接口,分别处于两个子网 10.0.0.0/8 和 192.168.1.0/24,而 Server1 的 IP 属于子网 192.168.1.0/24,因此路由器 1 会将数据包发送给该子网对应的接口,最终到达 Server1。之后路由器 1 再次中转,将响应内容写回。

以上图为例,主机 1 向主机 2 发起请求,整体流程如下:
- 主机 1 的应用进程 AP1 向主机 2 的应用进程 AP2 传输数据。AP1 将数据交给本机的第 5 层(应用层)。
- 第 5 层(应用层)为数据添加必要的头信息(H5),如 HTTP 头部。
- 第 4 层(运输层)为数据添加
源/目端口头部(H4)。 - 第 3 层(网络层)为数据添加
源/目IP头部(H3)。 - 第 2 层(数据链路层)在数据首部加入
源/目 MAC(H2)、尾部加入校验和(T2)。 - 第 1 层(物理层)传输比特流时,不再添加控制信息。注意,比特流从首部开始传输。
- 当比特流离开主机 1,通过网络的物理传输介质到达路由器时:
- 路由器从第 1 层开始,逐层向上拆包,剥去控制信息后,将剩余数据传递给上一层。
- 到达第 3 层(网络层)时,路由器根据首部中的目的地址查找路由表,确定转发接口,然后将数据下传至第 2 层,加入新的首部和尾部,再传递至第 1 层,最终通过物理介质发送每一个比特。
- 比特流从路由器离开,抵达目的主机 2 时,数据依照相同流程从第 1 层开始逐层拆包,最终到达第 5 层。
- 最终,AP1 发送的数据交给主机 2 的应用进程 AP2。
ARP请求就是一种用于在局域网中查询MAC地址的广播请求。作用阶段是数据链路层。
如果源主机知道目标主机的IP地址,但不确定其MAC地址,它会广播一个ARP请求包。该请求包含了目标IP地址,并询问“谁拥有这个IP地址?请回复你的MAC地址”。
参考
2.) 问题 2:Client1 发起请求后,如果能连通,那么 Server1 收到的请求源 IP 是什么?
答:视情况而定。如果路由器启用 NAT(Network Address Translation),那么 Server1 收到的请求源 IP 为 192.168.1.1;如果未启用 NAT,则为 10.0.0.10。
像我们 WIFI 连接的路由器,默认就是开启 NAT 的。
最直接的体现是,所有连接该 WIFI 的,对外出去的互联网 IP 都是同一个。
二、LVS
2.1 背景
LVS(Linux Virtual Server) 是由中国工程师章文嵩博士于 1998 年发起并开发的开源负载均衡项目。1999 年,LVS 代码被集成到 Linux 内核 2.4 版本中,成为 Linux 生态的重要组成部分。
随着互联网流量的快速增长,传统单台服务器的性能已无法满足大规模服务的需求。章文嵩博士提出通过集群技术将多台物理服务器组合成一个“虚拟服务器”,对外表现为单一入口,从而提升服务能力和可靠性。

2.2 工作模式
LVS(Linux Virtual Server)是一个基于 Linux 内核的负载均衡解决方案,是 Linux 内核层面的负载均衡实现,核心是 IPVS 模块(IP Virtual Server)。
ipvsadm 是 LVS 的用户空间管理工具,它用来配置和查看 LVS(IPVS)的运行状态。安装 ipvsadm
1 | yum -y install ipvsadm |
LVS 支持三种主要的工作模式,适应不同网络环境:
- LVS-NAT模式
- 全名:Network Address Translation
- 原理:网络地址转换。Client 请求 LVS,LVS 通过 DNAT 将目标地址修改为真实地址,将请求转给 RealServer 并获取响应后,LVS 通过 SNAT 将源地址修改为自己的 VIP,再转发给 Client。
- 特点:LVS 对请求和响应双向都参与处理,压力较大。
- 适用场景:要求 RealServer 与 LVS 在同一局域网;性能略差。
- LVS-DR模式
- 全名:Direct Routing
- 原理:直接路由模式。Client 请求 LVS,LVS 只修改 MAC 地址,将数据包通过数据链路层直接发给 RealServer,RealServer 不经过 LVS 直接将响应返回给 Client。
- 特点:LVS 仅负责请求方向,响应绕过,减少 LVS 负载。
- 适用场景:要求 RealServer 与 LVS 在同一局域网;要求禁用ARP;性能较高。
- LVS-TUN模式
- 全名:IP Tunneling
- 原理:IP 隧道模式。Client 请求 LVS,LVS 将请求封装成 IP 隧道包(使用 IPIP 协议)转发给 RealServer,RealServer 解封装后处理请求,直接将响应返回给 Cilent。
- 特点:LVS 只负责请求方向,且不要求与 RealServer 在同一局域网。
- 适用场景:允许后端服务器分布在不同物理网络;要求支持隧道;性能较高。
参考
2.3 实践(一知半解,该内容暂留,以后填坑)
2.3.1 LVS-NAT模式
三个核心角色
- Client(客户端)
- 含义:发起请求的主机
- 流程:访问虚拟服务地址 VIP
- Director(LVS 调度器)
- 含义:安装有 LVS(通过 ipvsadm 配置)并对外开放 VIP 作为流量入口
- 流程:接收来自 Client 请求,并转发给 RealServer
- RealServer(真实服务器)
- 含义:提供服务的主机
- 流程:与 Director 处于同一局域网内,并将默认网关设置为 Director 的内网 IP(DIP),保证响应正确返回给 LVS
三个 IP
| 名称 | 所属角色 | 含义 |
|---|---|---|
| VIP | Director | Virtual IP,对外暴露,Client 访问这个地址 |
| DIP | Director | Director IP,LVS 的内网地址,RealServer 的网关应设为此 |
| RIP | RealServer | RealServer IP,真实服务器的地址,仅 LVS 与之通信 |
我有四台机器,这四台机器在同一个局域网内。
- 10.0.0.10
- 用途:Client
- 10.0.0.101
- 用途:Director
- 10.0.0.102
- 用途:RealServer。部署 Nginx,开启 80 端口。
- 10.0.0.103
- 用途:RealServer。部署 Nginx,开启 80 端口。
Director 配置
1.) 开启 IP 转发。该内容仅需要针对 Director 开启即可。
验证是否开启 ipv4
1 | # 方式一 |
临时修改,服务器重启后失效
1 | # 方式一 |
永久修改
1 | echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf |
2.) 配置负载均衡规则。并开启一个虚拟 IP。
1 | # 添加虚拟 IP(VIP),dev 是 device 的缩写,ens33 表示网络接口 |
其他常用命令
1 | # 若需要删除 |
RealServer 配置
1.) 安装 Nginx, 开启 http 80 端口。一键安装 Nginx 脚本参考那些年,我玩过的Bash脚本
2.) 分别修改默认 index.html,返回当前的 IP 地址
1 | echo "<h1>10.0.0.102</h1>" >/usr/local/nginx/html/index.html |
3.) 最关键的一步,需要将首选网关配置为 Director,并设置较高的优先级。metric 值越小,优先级越高。
1 | # 查看当前路由 |

运行结果
修改了网关后,要等一会。不会立马生效。

2.3.2 LVS-DR模式
同样是三个角色,Director、RealServer、Client,也同样是上述四台机器。具体含义可以参考上述说明。
Director 配置
1 | # 为 Director(负载均衡器)上的 ens33 网络接口添加 IP 地址 10.0.0.200,/32 表示这是一个单一的 IP 地址 |
RealServer 配置
1.) 安装 Nginx, 开启 http 80 端口。一键安装 Nginx 脚本参考那些年,我玩过的Bash脚本
2.) 分别修改默认 index.html,返回当前的 IP 地址
1 | echo "<h1>10.0.0.102</h1>" >/usr/local/nginx/html/index.html |
3.) 配置
1 | # 为 RealServer 上的 lo 网络接口添加 Director 的虚拟 IP 地址 10.0.0.200,确保其能够与 Director 进行 ARP 通信 |
2.3.3 LVS-TUN模式
同样是三个角色,Director、RealServer、Client,也同样是上述四台机器。具体含义可以参考上述说明。
问题1:Director与Realserver之间,只需要开启一个IP隧道吗?那怎么负载均衡?
问题2:如果只需要开启一个IP隧道是正确的,那么不配置ip隧道是不是也可以?
Director 配置
1 | # 启用IP转发,允许流量转发到真实服务器 |
RealServer 配置
三、keepalived
3.1 工作原理
keepalived 用于应用服务的高可用,当应用服务出现故障时,可以将请求转移到正常的服务上面。
keepalived 由以下部分组成:
- VRRP(Virtual Router Redundancy Protocol)
- 负责虚拟 IP(VIP)的主备切换,保证服务高可用。
- 健康检查(Health Check)
- 支持编写自定义脚本,检测服务的存活状态,避免流量转发到故障节点。
VRRP 主备切换,其核心原理如下:
- 角色划分
- Master(主):持有 VIP,负责对外提供服务,并定期发送 VRRP 广播
- Backup(备):监听 Master 的心跳消息,在 Master 故障时接管 VIP。
- 选举机制
- VRRP 采用 优先级(Priority) 进行主备选举,默认范围 1-255,值越大优先级越高。
- 默认情况下,优先级高的节点成为 Master。
- Master 会 周期性发送 VRRP 广播包,告诉 Backup “我还活着”。
- Backup 监听 Master 的 VRRP 包,如果一定时间内收不到心跳,则触发故障转移(Failover):
- 最高优先级的 Backup 变为 Master,接管 VIP。
- 旧的 Master 恢复后,如果优先级较低,则作为 Backup。
问:当 VIP 进行故障转移时,局域网内其他机器如何知道这个 VIP 被哪台机器接管了?
答:局域网内其他机器,在访问这个 IP 时,如果当前
arp -a缓存里面不存在该 IP 对应 MAC 地址。则会发送 ARP 请求,询问同一子网内的机器:拥有这个 IP 地址的机器需要将 MAC 地址返回。
3.2 安装
直接运行 i-keepalived.sh
1 |
|

运行日志查看
1 | journalctl -u keepalived -f |
3.3 实践
我有四台机器,这四台机器在同一个局域网内。
- 10.0.0.10
- 用途:Client
- 10.0.0.101
- 用途:Keepalived + Nginx (HTTP 80)
- 主机名:node1
- 10.0.0.102
- 用途:Keepalived + Nginx (HTTP 80)
- 主机名:node2
- 10.0.0.103
- 用途:Keepalived + Nginx (HTTP 80)
- 主机名:node3
我现在要实现将 node1、node2、node3 组建成一个支持故障转移的高可用集群,要点如下。
- 对外的 VIP 为 10.0.0.200。
- node1 为 master 节点,其他的为 backup 节点,并且 node1、node2、node3 的优先级分别为 100、99、98。
node1 的 /etc/keepalived/keepalived.conf 完整配置如下
1 | global_defs { |
在此基础上,针对 node2 进行配置调整。
- state 调整为 BACKUP
- priority 调整为 99
针对 node3 进行配置调整。
- state 调整为 BACKUP
- priority 调整为 98
依次在 node1、node2、node3 机器上进行 keepalived的服务启动。关闭 nginx 进行验证即可。
- 验证脚本执行:查看 nginx 访问日志
- 验证 VIP 漂移:查看 keepalived 日志,或者,执行
ip addr查看