LVS深度解析:从原理到实战的负载均衡完全指南
1.LVS基础:核心概念与工作机制
LVS 的全称是 Linux Virtual Server,即 Linux 虚拟服务器。它是一个由章文嵩博士发起和领导的优秀开源项目,现在已经是 Linux 内核标准的一部分。
核心目标:使用负载均衡技术将多台真实的服务器(Real Server)构成一个高性能、高可用的虚拟服务器。客户端访问这个虚拟的 IP 地址(VIP),由 LVS 将请求透明地转发到后端的真实服务器上,从而扩展网络设备和服务的吞吐量、提高应用的处理能力,并保护后端服务器不被直接暴露在公网上。
如果把互联网服务比作一家热门餐厅,客户端就是上门的顾客,后端服务器就是厨房里的厨师,而 LVS(Linux 虚拟服务器)就是那个站在门口的 “智能调度员”。它的核心活儿很简单:不让顾客都挤在一个厨师面前,而是把订单均匀分到各个厨师手里,既能让上菜速度变快,也能避免某个厨师累垮;更重要的是,顾客从头到尾只认 “餐厅大门”(也就是 VIP,虚拟 IP),根本不知道后厨有多少个厨师,这就给后端服务器加了层保护。在这个 “餐厅” 里,除了 LVS 这个调度员,还有几个关键角色:顾客的地址(CIP)、调度员自己的工位(DIP)、厨师们的工位(RIP),少了哪个都没法顺畅运转。
1.1 必知术语:LVS 网络架构中的关键角色与地址标识
- VS:Virtual Server ,虚拟服务
- Director: Balancer ,也叫DS(Director Server)负载均衡器、分发器
- RS:Real Server ,后端请求处理服务器,真实服务器
- CIP: Client IP ,客户端IP
- VIP:Director Virtual IP ,负载均衡器虚拟IP
- DIP:Director IP ,负载均衡器IP
- RIP:Real Server IP ,后端请求处理的服务器IP
1.2 底层运行原理:Netfilter 框架与 IPVS 模块的协同工作
LVS 的核心工作依赖于 Netfilter 框架(Linux 内核的数据包过滤框架,iptables 也基于此)和 IPVS 模块。
- IPVS 模块:这是 LVS 的核心。它工作在内核态,实现了高效的负载均衡功能。当内核编译了 IPVS 模块后,它会在 Netfilter 的
INPUT
链上挂载一个钩子函数。 - Netfilter工作机制:
Netfilter中有五个内置链(chain)对应内核中的五个勾子函数。
(1)当一个数据包进入网卡时,数据包首先进入PREROUTING链,内核根据数据包目的IP判断是否需要传送出去;
(2)如果数据包是进入本机的,则会进入INPUT链,然后交由本机的应用程序处理;
(3)如果数据包是要转发的,且内核允许转发,则数据包在PREROUTING链之后到达FORWARD链,再经由POSTROUTING链输出;
(4)本机的应用程序往外发送数据包,会先进入OUTPUT链,然后到达POSTROUTING链输出。
数据流入:PREROUTING --> INPUT
数据流出:OUTPUT --> POSTROUTING
数据转发:PREROUTING --> FORWARD --> POSTROUTING
LVS 是基于Netfilter框架,主要工作于 INPUT 链上,在 INPUT 上注册 ip_vs_in HOOK 函数,进行 IPVS 主流程,大概原理如图所示:
1.2.1 数据包流转全流程:从客户端请求到后端响应
-
请求到达:客户端请求
[CIP -> VIP]
到达负载均衡器。 -
路由判断:内核发现目标是本机VIP,准备送交INPUT链。
-
IPVS拦截:IPVS模块在INPUT链拦截此包,根据算法选中一台真实服务器(RS)。
-
**LVS转发请求,RS返回响应。**如下四种模式,四种转发模式的核心差异(DR/NAT/TUN/FULL NAT)
DR模式
-
转发:如果DR模式下,只修改目标MAC为RS的MAC地址,然后将包从OUTPUT链送出。
-
RS接收:RS看到MAC是自己,且VIP也在本地,于是处理请求。
-
直接响应:RS将响应包
[VIP -> CIP]
直接发回客户端,不经过负载均衡器。
NAT 模式
- 转发请求:LVS 直接修改请求包的目标IP,从 VIP 改为选中的 RS 的 IP。
- 返回响应:RS 将响应包发回给 LVS,LVS 再修改响应包的源IP,从 RS 的 IP 改回 VIP,然后发给客户端。
- 简记:LVS 是“中介”,请求和响应都要经过它,它要做两次地址转换。性能瓶颈。
TUN 模式
- 转发请求:LVS 将整个客户端请求包再套一层IP头(封装隧道),新包的目标IP是 RS 的 IP。RS 收到后拆掉外层IP头,看到原始的
[CIP -> VIP]
请求。 - 返回响应:RS 直接拿着原始请求包里的 VIP 和 CIP 信息,直接将响应发回给客户端。
- 简记:LVS 是“快递打包站”,RS 是“拆包点”。请求需要封装,响应直接返回。可以跨网络。
FULL NAT 模式
- 转发请求:LVS 同时修改请求包的源IP和目标IP。源IP从 CIP 改为 LVS 的内网IP,目标IP从 VIP 改为 RS 的 IP。
- 返回响应:RS 将响应包发回给 LVS,LVS 再同时修改响应包的源IP和目标IP。源IP从 RS 的 IP 改回 VIP,目标IP从 LVS 的内网IP 改回 CIP。
- 简记:NAT模式的升级版。进出都经过LVS并做两次地址转换,但解决了LVS和RS必须在同一网段的问题。RS看不到真实客户IP。
-
所以,如果不是 DR 模式,LVS 就不会只改MAC地址那么简单,它要么改IP地址(NAT),要么封装IP包(TUN)
1.3 四大工作模式深度解析:原理、流程与适用场景
以上简单提到了LVS的四种工作模式,接下来详细的介绍一下这四种模式
1.3.1 NAT 模式:基于地址转换的 “中介式” 转发
-
核心原理:通过网络地址转换,调度器重写请求和响应数据包的地址。
-
数据流:
- 请求:客户端发送数据包
[CIP -> VIP]
到调度器。 - 调度器:接收到包后,根据算法选择一台 Real Server(RS),将数据包的目标 IP 改为 RS 的 IP(RIP),端口也可能改变。数据包变为
[CIP -> RIP]
。注意,源 IP 仍然是 CIP。 - RS:收到数据包
[CIP -> RIP]
,处理请求。 - 响应:RS 将响应数据包发回,由于源 IP 是 CIP,所以 RS 会直接将响应包发回给调度器(因为 RS 的网关必须指向调度器)。响应包为
[RIP -> CIP]
。 - 调度器:收到 RS 的响应包后,将源 IP 地址从 RIP 改回 VIP,数据包变为
[VIP -> CIP]
,然后发回给客户端。
NAT 模式特点:
- RIP和DIP 应在同一个IP网络,且应使用私网地址;
- RS 的网关要指向 DIP;
- 请求报文和响应报文都必须经由 LVS 转发,LVS 易成为系统瓶颈;
- 支持端口映射,可修改请求报文的目标PORT;
- VS 必须是 Linux 系统,RS 可以是任意 OS 系统;
- LVS 主机需要开启 ip_forward 转发。
- 请求:客户端发送数据包
1.3.2 DR 模式:通过 MAC 改写实现的高性能转发
核心原理:通过改写请求数据包的 MAC 地址,将请求直接转发给 RS,而 RS 处理后直接响应客户端,不再经过调度器。
数据流:
- 请求:客户端发送数据包
[CIP -> VIP]
到调度器。 - 调度器:选择一台 RS,不修改目标 IP(仍然是 VIP),而是修改目标 MAC 地址为 RS 的 MAC 地址。然后将数据包在局域网内发送出去。
- RS:由于数据包的目标 MAC 是自己的 MAC,所以它会接收这个包。接着,它解开数据包,发现目标 IP(VIP)也配置在自己本机的某个网卡上(通常是 lo:0 接口)。于是,RS 处理这个请求。
- 响应:RS 处理完毕后,构建响应数据包
[VIP -> CIP]
。由于它知道源 IP 是 VIP,目标 IP 是 CIP,并且 CIP 不在本地网络,所以它会通过默认网关直接将该响应包发回给客户端,完全不经过调度器。
DR模式特点:
-
RS 必须在同一物理局域网内。
-
需要在所有 RS 上配置 ARP 抑制,让它们不会响应来自网络的对 VIP 的 ARP 请求,否则会导致混乱。通常通过修改内核参数实现。
-
不支持端口映射
-
LVS 服务器只处理请求报文,不处理响应报文,相对于 NAT 模式其负载性能会大幅提升,响应由RS 服务器自行完成
1.3.3 TUN 模式:跨网络的 IP 隧道转发方案
- 核心原理:通过 IP 隧道技术,将客户端的请求包封装在一个新的 IP 包中,发送给 RS,RS 解封装后直接响应客户端。
- 数据流:
- 请求:客户端发送
[CIP -> VIP]
到调度器。 - 调度器:对原始数据包进行 IP 封装,外面再加一个 IP 头,目标 IP 是 RIP,源 IP 是 DIP。数据包变为
[DIP -> RIP]
,内部封装着[CIP -> VIP]
。 - RS:收到这个封装包后,解封装,得到内部的
[CIP -> VIP]
数据包。它发现 VIP 就在自己本地,于是处理请求。 - 响应:RS 直接构建响应包
[VIP -> CIP]
,并通过自己的路由直接发回给客户端。
- 请求:客户端发送
- TUN模式特点:
- RS 可以分布在互联网的任何地方,可以跨越 VLAN。调度器只处理入站请求。
- RS 需要支持 IP 隧道协议,需要安装相应的隧道模块。封装和解封装数据包有额外的 CPU 开销。
- 不支持端口映射
- LVS 服务器只处理请求报文,不处理响应报文,相对于 NAT 模式其负载性能会大幅提升,响应由RS 服务器自行完成;
1.3.4 FULL NAT 模式:突破网段限制的 NAT 增强版
- 核心原理:NAT 模式的增强版。在 NAT 模式中,调度器只修改目标地址。在 FULL NAT 中,调度器同时修改源地址和目标地址。
- 数据流:
- 请求:客户端发送
[CIP -> VIP]
到调度器。 - 调度器:将源 IP 从 CIP 改为 DIP(调度器自己的内网 IP),将目标 IP 从 VIP 改为 RIP。数据包变为
[DIP -> RIP]
。 - RS:收到
[DIP -> RIP]
,处理请求。 - 响应:RS 发送响应
[RIP -> DIP]
给调度器。 - 调度器:将响应包的源 IP 从 RIP 改回 VIP,目标 IP 从 DIP 改回 CIP,变为
[VIP -> CIP]
发回客户端。
- 请求:客户端发送
- FULL NAT模式特点:
- 解决了 NAT 模式下 RS 和调度器必须在同一 VLAN,且 RS 网关必须指向调度器的问题。在 FULL NAT 下,调度器和 RS 可以跨越 VLAN,RS 的网关也不需要指向调度器。极大提升了部署灵活性。
- RS 看不到真实的客户端 IP(CIP),因为源 IP 被改成了 DIP。需要通过
TOA
等内核模块从 TCP 选项中将真实 IP 带给 RS。 - 支持端口映射
- LVS 主机需要开启 ip_forward 转发。
1.3.5 四种模式核心特性对比表
特性 | NAT | DR | TUN | FULL NAT |
---|---|---|---|---|
RS 操作系统 | 任意 | 任意 | 需支持隧道 | 任意 |
RS 网络 | 私有网络 | 同一局域网 | 可跨地域 | 可跨 VLAN |
RS 网关 | 必须指向 DIP | 不能指向 DIP | 不能指向 DIP | 可指向任意 |
性能 | 低(瓶颈在调度器) | 非常高 | 高(有封装开销) | 中 |
CIP 可见性 | 可见 | 可见 | 可见 | 不可见(需 TOA) |
部署复杂度 | 简单 | 中等(需配置ARP抑制) | 复杂(需隧道支持) | 中等 |
端口映射 | 支持 | 不支持 | 不支持 | 支持 |
LVS主机是否开启ip_forward转发 | 是 | 否 | 是 | 否 |
NAT 与 FULL NAT:请求报文和响应报文都经由 LVS,NAT 模式下的 RIP 网关要指向 DIP,FULL NAT 模式下无此要求;DR 与 TUN:请求报文经由 LVS,响应报文由 RS 自行转发;DR 模式通过修改 MAC 首部实现,通过 MAC 网络转发; TUN 模式通过在原 IP 报文之外封装新的 IP 首部实现转发,支持跨公网通信。
生产环境推荐:DR 模式 因其极高的性能而被广泛使用。当网络拓扑受限时,FULL NAT 是一个很好的备选
1.4 负载调度算法:静态与动态策略的选型
1.4.1 四种静态算法:轮询、加权轮询与哈希策略
仅根据算法本身进行分配,不考虑 RS 的当前负载。
- 轮询(rr):将请求依次、循环地分发给每个 RS。绝对公平,但假设所有 RS 性能相同。
- 加权轮询(wrr):给性能好的 RS 分配更高的权重,它将收到更多的请求。权重是解决 RS 性能不均的关键。
- 源地址哈希(sh):对请求的源 IP 进行哈希计算,同一个 IP 的请求总是被发往同一台 RS。用于实现会话保持。
- 目标地址哈希(dh):对请求的目标 IP 进行哈希计算。常用于缓存服务器集群,将相同目标(如缓存文件)的请求发往同一台缓存服务器。
1.4.2 六种动态算法:基于实时负载的智能调度
根据 RS 的实时负载状态(如连接数)进行调度。
- 最少连接(lc):将新请求分配给当前活动连接数最少的 RS。
- 加权最少连接(wlc):默认算法。在 lc 的基础上考虑权重。
Overhead = (Active Conns * 256 + Inactive Conns) / Weight
,选择 Overhead 最小的 RS。最智能、最常用。 - 最短期望延迟(sed):WLC 的改进版,避免 WLC 在连接数为 0 时的缺陷。
Overhead = (Active Conns + 1) * 256 / Weight
。不考虑非活动连接。 - 永不排队(nq):在 SED 基础上改进。首先寻找活动连接数为 0 且权重最高的 RS,如果找不到,再使用 SED 算法。
- 基于位置的最少连接(lblc):针对局部性的负载均衡,适用于缓存场景。尝试将来自同一 IP 的请求发送到上次连接的那台 RS,如果该服务器负载过重,则选择连接数最少的。
- 带复制的基于位置的最少连接(lblcr):lblc 的带缓存副本的版本,更复杂。
1.4.3 高版本内核新增算法:FO/OVF/MH 的应用场景
- FO:Weighted Fail Over,权重过载算法,在此算法中,LVS 会遍历关联的后端 RS 服务器列表,找到未过载(未设置 IP_VS_DEST_F_OVERLOAD 标志)且权重最高的RS服务器进行调度,属于静态算法;可以用于灰度发布。
- OVF:Overflow-connection,溢出连接算法,该算法基于真实服务器的活动连接数量和权重值实现,将新的请求调度到权重最高的 RS 服务器,直到其活动连接数超过权重值,后续请求将调度到下一个权重最高的 RS 服务器上,属于动态算法;
- MH:Masquerading Hashing,源 IP 地址 hash,将来自于同一个 IP 地址的请求调度到后端同一台 RS 服务器上,hash 计算方式与 SH 算法不同;
1.5 LVS 管理工具:ipvsadm 命令详解
LVS 本身是内核功能,我们管理它需要使用用户空间的工具 ipvsadm
。
1.5.1 ipvsadm 工具
这是配置和管理 LVS 的核心命令。
(1)管理虚拟服务
#常用选项
-A|-E|-D #添加/编辑/删除虚拟服务
-t | -u #TCP/UDP协议的虚拟服务
-s #配置负载均衡算法,如:rr, wrr, lc,wlc等
-p #配置持久化时间
-C #清除所有的虚拟服务规则
-R #重载虚拟服务规则
#添加一个虚拟服务器,使用轮询算法
ipvsadm -A -t 192.168.168.200:80 -s rr
#修改虚拟服务的算法为加权轮询
ipvsadm -E -t 192.168.168.200:80 -s wrr
#删除虚拟服务
ipvsadm -D -t 192.168.168.200:80
(2)管理真实服务
#常用选项
-a|-e|-d #在一个虚拟服务中添加/编辑/删除一个新的真实服务器
-t|-u #虚拟服务监听集群写法,一般是VIP
-r #指定rs服务器
-g | -m | -i #LVS模式为:DR | NAT | TUN
-w #配置真实服务器的权重
#添加一个真实服务器172.24.24.60,使用nat工作模式,使用rr算法
ipvsadm -a -t 192.168.168.200:80 -r 172.24.24.60 -m
#添加一个真实服务器172.24.24.60,使用DR工作模式,权重2
ipvsadm -a -t 192.168.168.200:80 -r 172.24.24.60 -g -w 2
#修改真实服务器的权重
ipvsadm -e -t 192.168.168.200:80 -r 172.24.24.60 -g -w 5
#删除真实服务器
ipvsadm -d -t 192.168.168.200:80 -r 172.24.24.60
(3)查看统计
#查看当前配置的虚拟服务和各个RS的权重(当前运行的规则在文件/proc/net/ip_vs中)
ipvsadm -ln
#查看当前ipvs模块中记录的连接(可用于观察转发情况,在文件/proc/net/ip_vs_conn中),超时后会消失
ipvsadm -lnc
#查看当前超时时长值,单位为秒
ipvsadm -l --timeout
#清空计数器
ipvsadm -Z -t 192.168.168.200:80
–stats选项和–rate选项
[root@director ~]# ipvsadm -ln --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes
#说明:
1. Conns (connections scheduled) 已经转发过的连接数
2. InPkts (incoming packets) 入包个数
3. OutPkts (outgoing packets) 出包个数
4. InBytes (incoming bytes) 入流量(字节)
5. OutBytes (outgoing bytes) 出流量(字节)
[root@director ~]# ipvsadm -ln --rate
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port CPS InPPS OutPPS InBPS OutBPS
#说明:
1. CPS (current connection rate) 每秒连接数
2. InPPS (current in packet rate) 每秒的入包个数
3. OutPPS (current out packet rate) 每秒的出包个数
4. InBPS (current in byte rate) 每秒入流量(字节)
5. OutBPS (current out byte rate) 每秒出流量(字节)
(4)保存ipvsadm的配置并恢复
#将配置保存至文件(ipvsadm --save等同于ipvsadm-save等同于ipvsadm -S)
[root@lvs ~]# ipvsadm -Sn > lvs_nat.conf
#恢复规则
[root@director ~]# ipvsadm -R < lvs_nat.conf
lvs不会检测后端RS服务器状态。
权重为0的RS服务器不会被调度,一般用作平滑升级。
-
示例命令:
# 添加一个虚拟服务(VIP),端口80,使用加权最小连接调度算法 ipvsadm -A -t 192.168.1.100:80 -s wlc# 向该虚拟服务添加两台Real Server,使用DR模式,并设置权重 ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.11:80 -g -w 1 ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.12:80 -g -w 2# 查看当前配置的连接和统计 ipvsadm -ln# 开启持久连接,3600秒内同一客户端的请求会发往同一台RS ipvsadm -E -t 192.168.1.100:80 -s wlc -p 3600
2.LVS 负载均衡实战:集群搭建与验证
主机名 | IP | 作用 |
---|---|---|
client | 192.168.2.40/24 | 使用客户端测试 |
lvs | 192.168.2.41/24 | 提供负载均衡服务 |
rs1 | 192.168.2.42/24 | 提供web服务 |
rs2 | 192.168.2.43/24 | 提供web服务 |
2.1 NAT 模式集群构建:从网络拓扑到功能验证
2.1.1 环境准备:IP 规划与角色分配(客户端 / LVS/RS)
1. 三个网络角色
- 客户端:位于
192.168.2.0/24
网段 - LVS(负载均衡器):有两个网卡,分别连接两个不同网段
- RS1、RS2(真实服务器):位于
172.16.16.0/24
网段
2. IP地址分配
- 客户端:
192.168.2.40/24
- LVS:
- 外网卡:
192.168.2.41/24
(与客户端同网段) - 内网卡:
172.16.16.16/24
(与RS同网段)
- 外网卡:
- RS1:
172.16.16.10/24
- RS2:
172.16.16.11/24
3. 关键配置
- RS1和RS2的网关都指向LVS的内网IP:
172.16.16.16
2.1.2 核心配置:LVS 路由转发开启与 RS 网关设置
#RS1IP地址配置
[root@rs1 ~]# nmcli connection modify ens160 ipv4.addresses 172.16.16.10/24 ipv4.gateway 172.16.16.16
[root@rs1 ~]# nmcli connection up ens160
[root@rs1 ~]# ip a show ens160
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:0c:29:1e:65:4d brd ff:ff:ff:ff:ff:ffaltname enp3s0inet 172.16.16.10/24 brd 172.16.16.255 scope global noprefixroute ens160valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe1e:654d/64 scope link noprefixroute valid_lft forever preferred_lft forever
#RS2IP地址配置
[root@rs2 ~]# nmcli connection modify ens160 ipv4.addresses 172.16.16.11/24 ipv4.gateway 172.16.16.16
[root@rs2 ~]# nmcli connection up ens160
[root@rs2 ~]# ip a show ens160
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:0c:29:26:29:d8 brd ff:ff:ff:ff:ff:ffaltname enp3s0inet 172.16.16.11/24 brd 172.16.16.255 scope global noprefixroute ens160valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe26:29d8/64 scope link noprefixroute valid_lft forever preferred_lft forever
#RS1web测试页面配置
[root@rs1 ~]# systemctl start nginx
[root@rs1 ~]# echo "RS1 172.16.16.10" > /usr/share/nginx/html/index.html
[root@rs1 ~]# curl 172.16.16.10
RS1 172.16.16.10
#RS2web测试页面配置
[root@rs2 ~]# systemctl start nginx
[root@rs2 ~]# echo "RS2 172.16.16.11" > /usr/share/nginx/html/index.html
[root@rs2 ~]# curl 172.16.16.11
RS2 172.16.16.11
LVS配置(添加一张网卡作为仅主机模式,后端RS的网关):
#LVSIP配置
[root@lvs ~]# nmcli device
DEVICE TYPE STATE CONNECTION
ens160 ethernet 已连接 ens160
lo loopback 连接(外部) lo
ens192 ethernet 已断开 --
[root@lvs ~]# nmcli connection add type ethernet con-name ens192 ifname ens192 ipv4.addresses 172.16.16.16/24 ipv4.method manual autoconnect yes
[root@lvs ~]# nmcli connection up ens192
[root@lvs ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:0c:29:d4:26:54 brd ff:ff:ff:ff:ff:ffaltname enp3s0inet 192.168.2.41/24 brd 192.168.2.255 scope global noprefixroute ens160valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fed4:2654/64 scope link noprefixroute valid_lft forever preferred_lft forever
3: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:0c:29:d4:26:5e brd ff:ff:ff:ff:ff:ffaltname enp11s0inet 172.16.16.16/24 scope global noprefixroute ens192valid_lft forever preferred_lft foreverinet6 fe80::5304:7d26:961c:83e8/64 scope link noprefixroute valid_lft forever preferred_lft forever#NAT模式下LVS主机一定要开启路由转发
[root@lvs ~]# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
[root@lvs ~]# sysctl -p
net.ipv4.ip_forward = 1
2.1.3 负载规则配置:ipvsadm 命令实操与测试
[root@lvs ~]# yum install ipvsadm -y
[root@lvs ~]# ss -lntup | grep 80
[root@lvs ~]# ipvsadm -A -t 192.168.2.41:80 -s rr
[root@lvs ~]# ipvsadm -a -t 192.168.2.41:80 -r 172.16.16.10:80 -m
[root@lvs ~]# ipvsadm -a -t 192.168.2.41:80 -r 172.16.16.11:80 -m
[root@lvs ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.2.41:80 rr-> 172.16.16.10:80 Masq 1 0 0 -> 172.16.16.11:80 Masq 1 0 0 #发现LVS不会监听80端口
[root@lvs ~]# ss -lntup | grep 80
2.1.4 数据流向分析:请求与响应的完整路径
[root@client ~]# for i in {1..10};do curl 192.168.2.41;done
RS2 172.16.16.11
RS1 172.16.16.10
RS2 172.16.16.11
RS1 172.16.16.10
RS2 172.16.16.11
RS1 172.16.16.10
RS2 172.16.16.11
RS1 172.16.16.10
RS2 172.16.16.11
RS1 172.16.16.10
数据流向(NAT模式工作原理)
请求过程:
- 客户端发送请求到
192.168.2.41:80
(LVS的外网IP) - LVS收到请求,根据负载均衡算法选择一台RS(比如RS1)
- LVS将请求包的目标IP从
192.168.2.41
改为172.16.16.10
- LVS通过内网卡将修改后的请求发送给RS1
响应过程:
- RS1处理完请求,准备返回响应
- 由于RS1的网关指向
172.16.16.16
,所以响应包自动发回给LVS - LVS收到响应包,将源IP从
172.16.16.10
改回192.168.2.41
- LVS通过外网卡将响应返回给客户端
192.168.2.40
2.2 DR 模式集群构建:高性能场景的部署方案
2.2.1 网络架构设计:Route 节点的中转作用
结合图中信息,把流量路径拆分为「客户端 → Route → LVS → RS → 原路返回」:
- 客户端:
- 网络模式:仅主机模式(与 Route 的 “仅主机网卡” 通信)。
- IP:
172.24.24.10/24
,网关:172.24.24.3/24
(指向 Route 的 “仅主机网卡”)。
- Route(路由 / 中转节点):
- 两块 “逻辑网卡”:
- 仅主机模式:
172.24.24.3/24
(与客户端同网段,作为客户端网关)。 - NAT 模式:
192.168.2.45/24
+172.16.16.1/24
(连接 LVS 的 NAT 网段,同时关联 VIP 所在网段)。
- 仅主机模式:
- 作用:接收客户端请求,转发到 LVS;同时接收 RS 的响应,NAT 后回传给客户端。
- 两块 “逻辑网卡”:
- LVS(Director,负载均衡器):
- 虚拟 IP(VIP):
lo:172.16.16.16/24
(对外提供服务的统一 IP)。 - NAT 模式 IP:
192.168.2.41/24
,网关:192.168.2.45
(指向 Route 的 NAT 网卡)。 - 作用:接收 Route 转发的请求,通过负载均衡算法选择 RS,做 DNAT(目标 IP 改为 RS 的 NAT IP)后转发给 RS。
- 虚拟 IP(VIP):
- RS(Real Server,真实后端服务):RS1 和 RS2 结构一致,以 RS1 为例:
- 虚拟 IP(VIP):
lo:172.16.16.16/24
(与 LVS 的 VIP 一致,用于 “认请求”)。 - NAT 模式 IP:
192.168.2.42/24
,网关:192.168.2.45
(指向 Route 的 NAT 网卡)。 - 作用:处理 LVS 转发的请求,响应后通过网关(Route)回传。
- 虚拟 IP(VIP):
(1)route配置
需要再添加一个仅主机网卡,与客户端同网段,作为客户端网关
#route需要开启路由转发功能
[root@router ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@router ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@router ~]# ip a a 172.16.16.1/24 dev ens160
[root@router ~]# ip a
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:0c:29:3a:98:0b brd ff:ff:ff:ff:ff:ffaltname enp3s0inet 192.168.2.45/24 brd 192.168.2.255 scope global noprefixroute ens160valid_lft forever preferred_lft foreverinet 172.16.16.1/24 brd 172.16.16.255 scope global noprefixroute ens160valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe3a:980b/64 scope link noprefixroute valid_lft forever preferred_lft forever
3: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:0c:29:3a:98:15 brd ff:ff:ff:ff:ff:ffaltname enp11s0inet 172.24.24.3/24 brd 172.24.24.255 scope global noprefixroute ens192valid_lft forever preferred_lft foreverinet6 fe80::e4b5:a331:68c9:90e3/64 scope link noprefixroute valid_lft forever preferred_lft forever
2.2.2 关键配置:RS 的 ARP 抑制与 VIP 绑定
#在每台RS上执行(ARP抑制)
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce#配置VIP地址在lo接口,且将网关设置为192.168.2.45(RS2同配置)
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@rs1 ~]# ip a a 172.16.16.16/24 dev lo
[root@rs1 ~]# nmcli connection up lo
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/5)
[root@rs1 ~]# nmcli connection modify ens160 ipv4.gateway 192.168.2.45
[root@rs1 ~]# nmcli connection up ens160
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/6)
[root@rs1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet 172.16.16.16/24 brd 172.16.16.255 scope global lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:0c:29:1e:65:4d brd ff:ff:ff:ff:ff:ffaltname enp3s0inet 192.168.2.42/24 brd 192.168.2.255 scope global noprefixroute ens160valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe1e:654d/64 scope link noprefixroute valid_lft forever preferred_lft forever
[root@rs1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.2.45 0.0.0.0 UG 100 0 0 ens160
127.0.0.0 0.0.0.0 255.0.0.0 U 30 0 0 lo
172.16.16.0 0.0.0.0 255.255.255.0 U 30 0 0 lo
192.168.2.0 0.0.0.0 255.255.255.0 U 100 0 0 ens160#测试web服务是否正常
[root@rs1 ~]# curl 192.168.2.42
RS1 192.168.2.42
[root@rs1 ~]# curl 192.168.2.43
RS2 192.168.2.43
2.2.3 LVS 规则配置:DR 模式转发与加权调度
#IP配置
[root@lvs ~]# ip a a 172.16.16.16/24 dev lo
[root@lvs ~]# nmcli connection up lo
[root@lvs ~]# nmcli connection modify ens160 ipv4.gateway 192.168.2.45
[root@lvs ~]# nmcli connection up ens160
[root@lvs ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet 172.16.16.16/24 brd 172.16.16.255 scope global lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 00:0c:29:d4:26:54 brd ff:ff:ff:ff:ff:ffaltname enp3s0inet 192.168.2.41/24 brd 192.168.2.255 scope global noprefixroute ens160valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fed4:2654/64 scope link noprefixroute valid_lft forever preferred_lft forever
[root@lvs ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.2.45 0.0.0.0 UG 100 0 0 ens160
127.0.0.0 0.0.0.0 255.0.0.0 U 30 0 0 lo
172.16.16.0 0.0.0.0 255.255.255.0 U 30 0 0 lo
192.168.2.0 0.0.0.0 255.255.255.0 U 100 0 0 ens160
DR模式配置
[root@lvs ~]# ipvsadm -C
[root@lvs ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@lvs ~]# ipvsadm -A -t 172.16.16.16:80 -s rr
[root@lvs ~]# ipvsadm -a -t 172.16.16.16:80 -r 192.168.2.42:80 -g
[root@lvs ~]# ipvsadm -a -t 172.16.16.16:80 -r 192.168.2.43:80 -g
[root@lvs ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.16.16:80 rr-> 192.168.2.42:80 Route 1 0 0 -> 192.168.2.43:80 Route 1 0 0 #Route表示使用的DR模式
(4)客户端配置
[root@client ~]# nmcli connection modify ens160 ipv4.addresses 172.24.24.10/24 ipv4.gateway 172.24.24.3
[root@client ~]# for i in {1..10};do curl 172.16.16.16;done
RS2 192.168.2.43
RS1 192.168.2.42
RS2 192.168.2.43
RS1 192.168.2.42
RS2 192.168.2.43
RS1 192.168.2.42
RS2 192.168.2.43
RS1 192.168.2.42
RS2 192.168.2.43
RS1 192.168.2.42
如果想要修改算法,比如加权轮询
#使用ipvsadm -E(编辑虚拟服务)命令,将调度算法从rr改为wrr
[root@lvs ~]# ipvsadm -E -t 172.16.16.16:80 -s wrr
# 格式:ipvsadm -e -t 虚拟服务IP:端口 -r RS的IP:端口 -g -w 权重值
# 修改RS1(192.168.2.42)的权重为2
[root@lvs ~]# ipvsadm -e -t 172.16.16.16:80 -r 192.168.2.42:80 -g -w 2
[root@lvs ~]# ipvsadm -e -t 172.16.16.16:80 -r 192.168.2.43:80 -g -w 1
[root@lvs ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.16.16:80 wrr-> 192.168.2.42:80 Route 2 0 0 -> 192.168.2.43:80 Route 1 0 0
2.2.4 流量走向验证:请求改写 MAC 与响应直连客户端
[root@client ~]# for i in {1..10};do curl 172.16.16.16;done
RS2 192.168.2.43
RS1 192.168.2.42
RS1 192.168.2.42
RS2 192.168.2.43
RS1 192.168.2.42
RS1 192.168.2.42
RS2 192.168.2.43
RS1 192.168.2.42
RS1 192.168.2.42
RS2 192.168.2.43
总结
流量走向
以 “客户端请求 VIP → RS 响应” 为例,完整流程:
一、请求流量走向(客户端 → RS)
- 客户端发请求:客户端发起 HTTP 请求,目标地址为
VIP: 172.16.16.16:80
。由于客户端的网关配置为172.24.24.3
(Route 的 “仅主机模式” 网卡),请求首先被发送到 Route。 - Route 转发到 LVS:Route 根据自身路由表,识别到目标网段
172.16.16.0/24
需转发给 LVS(LVS 的 “NAT 模式” 网卡 IP 为192.168.2.41
,与 Route 的192.168.2.45
同网段,可达),因此将请求转发给 LVS。 - LVS 的 DR 模式处理(核心!):LVS 收到请求后,发现目标 IP 是自身
lo
接口绑定的VIP: 172.16.16.16
,触发DR 模式的关键操作:- 保持目标 IP(VIP)不变(客户端仍认为请求发往 VIP);
- 修改数据包的 MAC 地址:将目标 MAC 地址改写为选中的 RS(如 RS1)的 MAC 地址,同时将源 MAC 地址设置为 LVS 自身的 MAC 地址;
- 然后将修改后的数据包转发到 RS 所在的网络(与 LVS 同网段)。
- RS 处理请求:RS(如 RS1)收到数据包后,看到目标 IP 是自身
lo
接口绑定的VIP: 172.16.16.16
,于是处理该 HTTP 请求。
二、响应流量走向(RS → 客户端)
- RS 生成响应:RS(如 RS1)处理完请求后,生成响应数据包,源 IP 为 VIP(172.16.16.16),目标 IP 为客户端 IP(172.24.24.10)。
- RS 通过网关 Route 回传:由于 RS 的网关配置为
192.168.2.45
(Route 的 “NAT 模式” 网卡),RS 将响应数据包发送给 Route。 - Route 转发给客户端:Route 根据路由表,识别到目标网段
172.24.24.0/24
(客户端所在网段),将源为VIP: 172.16.16.16
、目标为客户端 IP 的响应流量,转发回客户端所在的 “仅主机模式” 网络。 - 客户端接收响应:客户端收到响应数据包,完成一次通信。
2.3 持久连接配置:保障会话一致性的三种方案
2.3.1 客户端持久连接:同一 IP 的请求定向至固定 RS
在短期内,将来自于同一个客户端的所有请求通通定向至此前选定的 RS;也就是只要 IP 相同,分配的服务器始终相同 。
ipvsadm -A -t 172.16.0.8:0 -s wlc -p 120
# 添加一个 tcp 负载集群,集群地址为 172.16.0.8 ,0表示的是端口号,算法为 wlc,持久化时间为 120s
2.3.2 端口持久连接:同一服务端口的会话保持
将来自于同一个客户端对同一个服务(端口)的请求,始终定向至此前选定的RS。
ipvsadm -A -t 172.16.0.8:80 -s rr -p 120
# 添加一个 tcp 负载集群,集群地址为 172.16.0.8:80 ,算法为 rr,持久化时间为 120s
2.3.3 防火墙标记持久连接:多端口服务的统一调度
将来自于同一客户端对指定服务(端口)的请求,始终定向至此选定的 RS;不过它可以将两个毫不相干的端口定义为一个集群服务。
iptables -t mangle -A PREROUTING -d 172.16.0.8 -p tcp --dport 80 -j MARK --set-mark 10 # 添加一个防火墙规则,当目标地址为 172.16.0.8 并且目标端口为 80 时给数据包打一个标记,设置mark 值为 10
iptables -t mangle -A PREROUTING -d 172.16.0.8 -p tcp --dport 443 -j MARK --set-mark 10
# 添加一个防火墙规则,当目标地址为 172.16.0.8 并且目标端口为 443 时给数据包打一个标记,设置mark 值为 10
service iptables save # 保存防火墙规则持久化生效
ipvsadm -A -f 10 -s wlc -p 120 # 添加一个负载调度器,当 mark 值为 10 时进行负载均衡使用wlc 算法,持久化生效时间为 120s
ipvsadm -a -f 10 -r rs的地址 -m
3. 总结
LVS(Linux 虚拟服务器)是 Linux 系统下的负载均衡工具,主要功能是将客户端的请求分发到多台后端真实服务器(RS),以此提升服务的处理能力与可用性,同时对外隐藏后端服务器的具体信息,增强系统安全性。它依靠虚拟 IP(VIP,对外提供服务的统一入口)、调度器(LVS 服务器,负责请求分发)、后端服务器(RS,处理实际请求)等角色,以及客户端 IP(CIP)、调度器 IP(DIP)、后端服务器 IP(RIP)来完成流量的流转。
LVS 有四种工作模式。NAT 模式下,调度器会修改请求和响应的 IP 地址,请求与响应都需经过调度器,适合小规模场景,但调度器易成为性能瓶颈;DR 模式中,调度器仅修改数据包的 MAC 地址,后端服务器处理完请求后可直接向客户端响应,无需经过调度器,性能较高,不过要求后端服务器与调度器处于同一局域网;TUN 模式通过 IP 隧道封装请求,支持后端服务器跨网段部署,后端响应直接返回给客户端,但封装与解封装过程存在性能开销;FULL NAT 模式会同时修改请求的源 IP 和目标 IP,能突破网段限制,然而后端服务器无法直接获取客户端的真实 IP。
LVS 的调度算法分为静态和动态两类。静态算法(如轮询、加权轮询、源 IP 哈希)不考虑后端服务器的负载情况,仅按固定规则分发请求;动态算法(如最少连接、加权最少连接)则依据后端服务器的实时负载进行智能调度。配置 LVS 主要使用 ipvsadm 工具,通过该工具可创建虚拟服务(指定 VIP、端口及调度算法),添加后端服务器并设置转发模式、权重等参数,进而实现负载均衡规则的定义与管理。