LVS 负载均衡全解析(NAT / TUN / FullNAT 篇)
Linux Virtual Server --- 一款诞生于 1998 年的经典开源负载均衡方案,至今仍在 Linux 内核中服役。本文带你从零理解 LVS 的工作原理、三种转发模式、十种调度算法,并手把手完成 NAT 模式实战。
📖 目录
- [一、LVS 是什么?](#一、LVS 是什么?)
- 二、核心概念与角色
- [三、LVS 是如何工作的?](#三、LVS 是如何工作的?)
- 四、三种转发模式深度解析
- [4.1 NAT 模式](#4.1 NAT 模式)
- [4.2 TUN 模式(IP 隧道)](#4.2 TUN 模式(IP 隧道))
- [4.3 FullNAT 模式](#4.3 FullNAT 模式)
- 五、十种调度算法详解
- [六、ipvsadm 命令速查](#六、ipvsadm 命令速查)
- [七、实战:NAT 模式搭建](#七、实战:NAT 模式搭建)
- 八、总结
一、LVS 是什么?
LVS(Linux Virtual Server) 是章文嵩博士在 1998 年开发的一款开源负载均衡软件,现已被集成到 Linux 内核中。它工作在 OSI 第四层(传输层) ,基于 IP:Port 进行流量分发,因此也常被称为 四层负载均衡。
用一个通俗的比喻来理解:
🏨 LVS 就像一个酒店的前台。客人(客户端)只需要知道酒店的地址(VIP),前台(Director)根据房态(调度算法)把客人分配到不同的房间(Real Server)。客人最终入住了房间,但整个过程对客人是透明的------他只知道"我住进了这家酒店"。
LVS 的核心优势:
- 内核级工作:转发效率极高,稳定可靠
- 协议无关:工作在四层,HTTP/HTTPS/MySQL/TCP/UDP 通吃
- 扩展性强:支持水平扩展,后端 Real Server 可随时增减
- 成熟稳定:20+ 年历史,大规模生产环境验证
二、核心概念与角色
2.1 两大角色
| 角色 | 说明 |
|---|---|
| Director Server(调度器) | LVS 的核心节点,负责接收所有客户端请求并根据调度算法分发给后端服务器 |
| Real Server(真实服务器) | 后端真正处理请求的服务器(如 Nginx、Tomcat、Apache),对外不可见 |
┌─────────────┐
│ Client │
│ (普通用户) │
└──────┬──────┘
│ 请求 VIP
▼
┌─────────────────┐
│ Director Server │ ← 调度器(LVS)
│ (负载均衡器) │
└───┬───┬───┬─────┘
│ │ │ 分发请求
┌───────┘ │ └───────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│Real Srv 1│ │Real Srv 2│ │Real Srv 3│
│ (Nginx) │ │ (Nginx) │ │ (Nginx) │
└──────────┘ └──────────┘ └──────────┘
2.2 关键 IP 地址
理解 LVS 的关键在于掌握这几个 IP 概念:
| 缩写 | 全称 | 含义 | 类比 |
|---|---|---|---|
| VIP | Virtual IP | 虚拟 IP,对外暴露的入口地址 | 🏢 酒店对外公开的门牌号 |
| DIP | Director IP | Director 和后端通信用的 IP | 🔑 前台内部对讲用的分机号 |
| RIP | Real Server IP | 每台 Real Server 的真实 IP | 🚪 各个房间的内部编号 |
| CIP | Client IP | 客户端的真实 IP | 👤 客人的身份证号 |
⚠️ 注意:不同转发模式下,这些 IP 在数据包中的出现位置和处理方式截然不同,这是理解 LVS 的核心难点之一。
三、LVS 是如何工作的?
LVS 通过 Linux 内核的 Netfilter 框架 实现流量劫持和转发。它的工作位置在 INPUT 链 上,具体流程如下:
Client → 网卡
│
▼
[PREROUTING] ← ① 数据包到达,DNAT 前处理
│
▼
[路由判断] ← ② 判断目标 IP 是否为本机
│
▼
[INPUT] ← ③ 发往本机的包进入 INPUT 链
│
▼
╔═══════════╗
║ IPVS ║ ← ④ LVS 在这里劫持!修改目标 IP/MAC
╚═══════════╝
│
▼
[POSTROUTING] ← ⑤ 数据包发出前最后一道关卡
│
▼
→ Real Server
用更直白的语言描述整个过程:
- 客户端 发包,目标地址是 VIP
- 包到达 Director 后,进入 PREROUTING 链
- 路由判断"这个包就是给我的",送入 INPUT 链
- IPVS 模块 在 INPUT 链上拦截,按照调度算法选出一台 Real Server,修改包的目标地址
- 包经过 POSTROUTING 链发出,送往 Real Server
- Real Server 处理完返回响应(返回路径取决于转发模式)
💡 这就是 LVS 的神奇之处------它注册在 INPUT 链上,能提前"截胡"本应送到本地应用层的数据包,将它们转发给后端!
四、三种转发模式深度解析
ℹ️ LVS 共有四种转发模式:NAT、DR、TUN、FullNAT。本文聚焦 NAT、TUN、FullNAT 三种。DR(Direct Routing)模式另有专题讨论。
4.1 NAT 模式
原理
NAT(Network Address Translation)是 LVS 最简单直观 的模式。Director 像路由器一样做网络地址转换,既修改目标 IP,也修改源 IP。
数据包流转
客户端发包: Director 转发给 RS:
┌─────────────────┐ ┌─────────────────┐
│ SRC: CIP │ │ SRC: CIP │
│ DST: VIP │ ────► │ DST: RIP │ ← 改了目标地址
│ MAC_SRC: Client │ │ MAC_SRC: DIP_MAC │
│ MAC_DST: Dir_MAC │ │ MAC_DST: RS_MAC │
└─────────────────┘ └─────────────────┘
RS 回包给 Director: Director 回包给客户端:
┌─────────────────┐ ┌─────────────────┐
│ SRC: RIP │ │ SRC: VIP │ ← 改回 VIP
│ DST: CIP │ ────► │ DST: CIP │
│ MAC_SRC: RS_MAC │ │ MAC_SRC: Dir_MAC │
│ MAC_DST: DIP_MAC │ │ MAC_DST: Client │
└─────────────────┘ └─────────────────┘
完整流程(7 步)
Client ──①──► Client ◄──⑥──
│ │
│ (CIP→VIP) │ (VIP→CIP)
▼ │
┌─────────────────────┐ ┌─────────────────────┐
│ Director Server │ │ Director Server │
│ (LVS-NAT 模式) │ │ │
│ │ ⑤ │ ② 在 INPUT 链 │
│ ①进入 PREROUTING │◄─────────│ 被 IPVS 拦截 │
│ ②路由判断→INPUT │─────────►│ ③修改 DST:VIP→RIP │
│ │ ④ │ ④POSTROUTING发出 │
└─────────────────────┘ └─────────────────────┘
│
│ ③(CIP→RIP)
▼
┌──────────┐
│Real Srv │
│ (Nginx) │
└──────────┘
│
│ ⑤(RIP→CIP)
│
返回给 Director ◄────────────────┘
步骤说明:
- 客户端发送请求,CIP → VIP
- Director 在 PREROUTING 接收,路由判断发往本机,进入 INPUT 链
- IPVS 介入:改写目标 IP 为 RIP,选择一台 Real Server
- 经过 POSTROUTING,发往 Real Server
- Real Server 处理:看到 CIP→RIP,响应时包必须经由 Director 返回(因为 RS 的默认网关指向 DIP)
- Director 收到回包,执行 反向 NAT:源 IP 从 RIP 改回 VIP,转发给客户端
💡 关键洞察 :NAT 模式下,请求和响应都要经过 Director。这使得 Director 可能成为瓶颈,但在中小规模场景下已经足够。
NAT 模式的特点
| 优点 | 缺点 |
|---|---|
| ✅ 配置最简单,容易理解 | ❌ Director 承担所有流量,可能成为瓶颈 |
| ✅ Real Server 可以是任何 OS | ❌ Real Server 的默认网关必须指向 Director |
| ✅ 支持端口映射(VIP:80 → RIP:8080) | ❌ 集群规模受限(一般 ≤ 20 台 RS) |
| ✅ 内网 RS 可隐藏,安全性好 | ❌ Director 需开启 IP 转发 |
4.2 TUN 模式(IP 隧道)
原理
TUN(IP Tunneling)模式用 IP 隧道技术 将客户端请求封装后发给 Real Server。请求走 Director,响应直接返回客户端,解决了 NAT 模式下 Director 双向瓶颈的问题。
🎯 类比:就像给快递包裹再套一层快递袋。外层写 Director→RS 的地址,里层保留原始的 CIP→VIP 信息。
数据包结构
┌──────────────────────────────────┐
│ 外层 IP 头(隧道头) │
│ SRC: DIP │
│ DST: RIP │
│ ┌──────────────────────────────┐ │
│ │ 内层 IP 头(原始包) │ │
│ │ SRC: CIP │ │
│ │ DST: VIP │ │
│ │ ┌──────────────────────────┐ │ │
│ │ │ TCP/UDP 数据 │ │ │
│ │ └──────────────────────────┘ │ │
│ └──────────────────────────────┘ │
└──────────────────────────────────┘
完整流程(6 步)
Client ──①──► Director ──③──► Real Server
(CIP→VIP) IPVS 封装 (外层:DIP→RIP, 内层:CIP→VIP)
RS 解封装,看到 CIP→VIP
│
│ ④ RS 直接用 VIP→CIP 回复
│ (走自己的网络,不经过 Director!)
▼
Client ◄─────────────────┘
Direct Server Return (DSR)
步骤说明:
- Director PREROUTING 收到 CIP→VIP 的包
- INPUT 链上 IPVS 拦截
- IPVS 封装:在原始包外面再包一层 IP 头(DIP→RIP),通过 POSTROUTING 发出
- Real Server 收到后解封装,还原出原始包(CIP→VIP)
- Real Server 的
lo接口上配置了 VIP,所以它认为"这是发给我的包",正常处理 - Real Server 直接用 VIP→CIP 回复客户端,不再经过 Director!
💡 关键洞察 :TUN 模式实现了 Direct Server Return------请求走 Director,响应直接返回。这极大地减轻了 Director 的负担,适合高并发大流量场景。
TUN 模式的特点
| 优点 | 缺点 |
|---|---|
| ✅ Director 只处理入站流量,不处理出站 | ❌ 需要 RS 操作系统支持 IP 隧道(IPIP 模块) |
| ✅ 集群规模可非常大,适合跨机房部署 | ❌ 隧道封装带来额外开销(MTU 需调整) |
| ✅ RS 可分布在不同的物理网络中 | ❌ 配置比 NAT 复杂 |
| ✅ 保留客户端真实 IP | ❌ RS 的 lo 接口需绑定 VIP |
4.3 FullNAT 模式
原理
FullNAT 是 NAT 模式的增强版,由阿里在 LVS 社区版本上扩展。它 同时修改源 IP 和目标 IP:
-
NAT 模式只改目标 IP(VIP → RIP),源 IP 保持为 CIP
-
FullNAT 既改目标 IP(VIP → RIP),也改源 IP(CIP → Local IP)
原始请求: CIP → VIP
│
▼ IPVS (FullNAT)
│
转发请求: Local_IP → RIP
使用 Local IP 替代 CIP 的好处:Real Server 的默认网关不需要指向 Director 了!因为 RS 看到的是 Director 发来的包(源地址是 Director 的 Local IP),回包自然回到 Director。
FullNAT 的特点
| 优点 | 缺点 |
|---|---|
| ✅ RS 网关可灵活配置,不需要指向 Director | ❌ Real Server 看不到客户端真实 IP(需要用 TOA 等方案传递) |
| ✅ 支持跨 VLAN 部署 | ❌ 非内核主线代码,需额外编译 |
| ✅ Director 仍然是双向流量(类似 NAT) | ❌ 维护成本较高 |
三种模式对比总结
┌──────────┬────────────┬────────────┬─────────────────┐
│ 特性 │ NAT │ TUN │ FullNAT │
├──────────┼────────────┼────────────┼─────────────────┤
│ 修改对象 │ 目标 IP │ IP 封装 │ 源 IP + 目标 IP │
├──────────┼────────────┼────────────┼─────────────────┤
│ 入站路径 │ Director │ Director │ Director │
├──────────┼────────────┼────────────┼─────────────────┤
│ 出站路径 │ Director │ 直接回客户端│ Director │
├──────────┼────────────┼────────────┼─────────────────┤
│ 集群规模 │ 小~中(≤20)│ 大(可跨DC) │ 中等 │
├──────────┼────────────┼────────────┼─────────────────┤
│ RS 要求 │ 任意 OS │ 支持 IPIP │ 任意 OS │
├──────────┼────────────┼────────────┼─────────────────┤
│ 端口映射 │ ✅ 支持 │ ❌ 不支持 │ ✅ 支持 │
├──────────┼────────────┼────────────┼─────────────────┤
│ 客户端 IP│ 可见 │ 可见 │ 不可见(需 TOA) │
├──────────┼────────────┼────────────┼─────────────────┤
│ 部署难度 │ ⭐ 简单 │ ⭐⭐⭐ │ ⭐⭐ │
├──────────┼────────────┼────────────┼─────────────────┤
│ 适用场景 │ 小规模内网 │ 大流量/跨IDC│ 特殊网络环境 │
└──────────┴────────────┴────────────┴─────────────────┘
五、十种调度算法详解
LVS 的核心价值在于智能调度 ------如何把请求分配到最合适的后端服务器。它提供了 10 种调度算法,分为静态 和动态两大类。
5.1 静态调度算法
静态调度 = 按预设规则分配,不参考实时负载。
① RR(Round Robin)--- 轮询
请求1 → RS1
请求2 → RS2
请求3 → RS3
请求4 → RS1
请求5 → RS2
...
最简单的算法,一人一次,循环往复。适合所有 RS 性能一致的场景。
② WRR(Weighted Round Robin)--- 加权轮询
假设 RS1 权重=1, RS2 权重=2, RS3 权重=3
请求1 → RS1
请求2 → RS2
请求3 → RS3
请求4 → RS2
请求5 → RS3
请求6 → RS3
给性能强的 RS 更高权重,能者多劳。适合后端服务器配置不一的场景。
③ DH(Destination Hash)--- 目标地址哈希
Hash(目标 IP) → 固定映射到某台 RS
将来自同一目标 IP 的请求始终 分到同一台 RS。常用于缓存命中率优化------同一个资源的请求走同一台缓存服务器。
④ SH(Source Hash)--- 源地址哈希
Hash(客户端 IP) → 固定映射到某台 RS
将来自同一客户端的请求始终 分到同一台 RS。适合需要 Session 保持 的场景(但现在更推荐用 Redis 等集中式 Session 方案)。
5.2 动态调度算法
动态调度 = 实时监控各 RS 的连接数和负载,智能分配。
⑤ LC(Least Connections)--- 最少连接
选择"当前活跃连接数 + 非活跃连接数"最小的 RS
核心思想:谁最空闲给谁。简单有效,但没有考虑服务器性能差异。
⑥ WLC(Weighted Least Connections)--- 加权最少连接
选择"(活跃连接×256 + 非活跃连接) ÷ 权重"最小的 RS
在 LC 的基础上引入权重,性能强的服务器承担更多连接 。这是 最常用的动态调度算法。
公式解释:
×256是为了让活跃连接的权重远大于非活跃连接(网络刚断开时连接处于非活跃状态)÷ 权重使得高配服务器可以容纳更多连接
⑦ SED(Shortest Expected Delay)--- 最短预期延迟
选择"(活跃连接 + 1) ÷ 权重"最小的 RS
基于数学期望,预测每台服务器处理下一个请求的等待时间。简洁高效。
⑧ NQ(Never Queue)--- 永不排队
在 SED 基础上增加了"最小连接"规则:
如果某台 RS 当前连接数为 0,直接发给它,不计算 SED 值
避免 "大家都在忙,偏偏有一台闲着但就是收不到请求" 的问题。
⑨ LBLC(Locality-Based Least Connections)--- 基于局部性的最少连接
步骤1: 对目标 IP 做 Hash,找到"上次处理过这个目标"的 RS
步骤2: 如果该 RS 可用且未过载 → 直接复用
步骤3: 如果不可用或过载 → 用最少连接法选一台新的
兼顾了缓存命中率 (优先走老路)和负载均衡(太忙就换人)。
⑩ LBLCR(LBLC with Replication)--- 带复制的 LBLC
在 LBLC 的基础上增加了"后备集群":
同一个目标 IP 对应一组 RS(而非一台),组内用最少连接法选择
解决了 LBLC 单点过载问题------当缓存服务器拥堵时,自动在同组内寻找替代者。
调度算法选择决策树
需要 Session 保持?
├─ 是 → 源地址哈希 (SH) 或 目标地址哈希 (DH)
└─ 否 → 服务器配置一致?
├─ 是 → 轮询 (RR) 或 最少连接 (LC)
└─ 否 → 加权轮询 (WRR) 或 加权最少连接 (WLC) ⭐推荐
缓存场景?
├─ 是 → LBLC 或 LBLCR
└─ 否 → ...
追求极致低延迟?
└─ 是 → SED 或 NQ
六、ipvsadm 命令速查
LVS 通过 ipvsadm 命令行工具管理。它的核心逻辑是:先创建虚拟服务(VIP),再给虚拟服务添加后端 Real Server。
6.1 虚拟服务管理
bash
# 添加虚拟服务
ipvsadm -A -t 10.1.1.10:80 -s rr
# │ │ └─ VIP:Port └─ 调度算法(rr/wrr/lc/wlc/...)
# │ └─ -t:TCP -u:UDP -f:防火墙标记
# └─ -A:添加 -E:修改
# 指定持久连接(同一客户端持续分配到同一 RS)
ipvsadm -A -t 10.1.1.10:80 -s wrr -p 300
# └─ 持久连接超时时间(秒)
# 删除虚拟服务
ipvsadm -D -t 10.1.1.10:80
# 清空所有规则
ipvsadm -C
6.2 Real Server 管理
bash
# 添加 Real Server
ipvsadm -a -t 10.1.1.10:80 -r 10.1.8.11:80 -m -w 2
# │ │ └─ 虚拟服务 │ └─ RS_IP:Port │ └─ 权重
# │ │ │ └─ -m:NAT -g:DR -i:TUN
# │ │ └─ -a:添加 -e:修改
# │ └─ 虚拟服务标识
# └─ 操作类型
# 修改已有 RS 的权重
ipvsadm -e -t 10.1.1.10:80 -r 10.1.8.12:80 -m -w 3
# 删除某台 RS
ipvsadm -d -t 10.1.1.10:80 -r 10.1.8.13:80
6.3 查看与统计
bash
# 查看规则(带数字显示,不解析域名)
ipvsadm -Ln
# 输出示例:
# IP Virtual Server version 1.2.1 (size=4096)
# Prot LocalAddress:Port Scheduler Flags
# -> RemoteAddress:Port Forward Weight ActiveConn InActConn
# TCP 10.1.1.10:80 rr
# -> 10.1.8.11:80 Masq 1 0 0
# -> 10.1.8.12:80 Masq 2 0 0
# -> 10.1.8.13:80 Masq 3 0 0
# 查看连接统计
ipvsadm -Lnc
# 清零计数器
ipvsadm -Z
# 保存规则(重启不丢失)
ipvsadm-save -n > /etc/sysconfig/ipvsadm
# 从文件恢复规则
ipvsadm -R < /etc/sysconfig/ipvsadm
6.4 参数速查表
| 参数 | 含义 |
|---|---|
-A / -E / -D |
添加 / 修改 / 删除 虚拟服务 |
-a / -e / -d |
添加 / 修改 / 删除 Real Server |
-t / -u / -f |
TCP / UDP / 防火墙标记 |
-s |
调度算法(rr, wrr, lc, wlc, ...) |
-r |
Real Server 的 IP:Port |
-g / -i / -m |
DR 模式 / TUN 模式 / NAT 模式 |
-w |
权重(默认 1) |
-p |
持久连接超时 |
-L / -l |
查看规则 |
-n |
数字格式显示(不解析 DNS) |
-Z |
清零统计计数器 |
-C |
清空所有规则 |
七、实战:NAT 模式搭建
🎯 目标:用 4 台虚拟机搭建一个完整的 LVS-NAT 集群,访问 VIP 时轮询分发到 3 台 Web 后端。
7.1 网络拓扑
┌─────────────────────────────┐
│ VMnet1: 10.1.1.0/24 │
│ (Host-Only / 模拟公网) │
└──────────┬──────────────────┘
│
┌───────────────┴────────────────┐
│ │
┌──────▼─────┐ ┌──────▼──────┐
│ Client2 │ │ LVS-Director│
│ 10.1.1.21 │ │ ens36: │
│ (外部客户端) │ │ 10.1.1.10 │ ← VIP 在此
└────────────┘ │ │
│ ens33: │
│ 10.1.8.10 │ ← DIP
└──────┬───────┘
│
┌──────────────────────────┴──────────────┐
│ VMnet8: 10.1.8.0/24 │
│ (NAT / 模拟内网) │
└──────┬──────────────┬───────────────────┘
│ │
┌─────────▼──┐ ┌────────▼───┐ ┌─────────▼──┐
│ Client1 │ │ Web1 │ │ Web2/3 │
│ 10.1.8.21 │ │ 10.1.8.11 │ │ .12 / .13 │
│ (内网测试) │ │ (Nginx) │ │ (Nginx) │
└────────────┘ └────────────┘ └────────────┘
7.2 机器角色
| 主机 | 角色 | 网段 | IP |
|---|---|---|---|
lvs.laogao.cloud |
Director | VMnet8 / VMnet1 | 10.1.8.10 / 10.1.1.10 |
web1.laogao.cloud |
RS (Nginx) | VMnet8 | 10.1.8.11 |
web2.laogao.cloud |
RS (Nginx) | VMnet8 | 10.1.8.12 |
web3.laogao.cloud |
RS (Nginx) | VMnet8 | 10.1.8.13 |
client1.laogao.cloud |
内网客户端 | VMnet8 | 10.1.8.21 |
client2.laogao.cloud |
外网客户端 | VMnet1 | 10.1.1.21 |
💡 Director 是双网卡,分别连接内外网。所有 RS 的默认网关都指向 Director 的 DIP(10.1.8.10)。
7.3 Step 1 --- 配置各节点网络
所有节点执行:设置主机名和 IP
bash
# === client2(外网客户端)===
hostnamectl set-hostname client2.laogao.cloud
nmcli connection modify ens33 ipv4.method manual \
ipv4.addresses 10.1.1.21/24 \
ipv4.gateway 10.1.1.10 \
ipv4.dns 223.5.5.5 \
autoconnect yes
nmcli connection up ens33
# === client1(内网客户端)===
hostnamectl set-hostname client1.laogao.cloud
nmcli connection modify ens33 ipv4.method manual \
ipv4.addresses 10.1.8.21/24 \
ipv4.gateway 10.1.8.10 \
ipv4.dns 223.5.5.5 \
autoconnect yes
nmcli connection up ens33
# === lvs(Director,双网卡!)===
hostnamectl set-hostname lvs.laogao.cloud
# 内网网卡
nmcli connection modify ens33 ipv4.method manual \
ipv4.addresses 10.1.8.10/24 \
ipv4.gateway 10.1.8.2 \
ipv4.dns 223.5.5.5 \
autoconnect yes
nmcli connection up ens33
# 外网网卡(VIP 所在网段)
nmcli connection add type ethernet con-name ens36 ifname ens36 \
ipv4.method manual ipv4.addresses 10.1.1.10/24 autoconnect yes
nmcli connection up ens36
# === web1-3(Real Servers)===
# web1
hostnamectl set-hostname web1.laogao.cloud
nmcli connection modify ens33 ipv4.method manual \
ipv4.addresses 10.1.8.11/24 \
ipv4.gateway 10.1.8.10 \
ipv4.dns 223.5.5.5 \
autoconnect yes
nmcli connection up ens33
# web2
hostnamectl set-hostname web2.laogao.cloud
nmcli connection modify ens33 ipv4.method manual \
ipv4.addresses 10.1.8.12/24 \
ipv4.gateway 10.1.8.10 \
ipv4.dns 223.5.5.5 \
autoconnect yes
nmcli connection up ens33
# web3
hostnamectl set-hostname web3.laogao.cloud
nmcli connection modify ens33 ipv4.method manual \
ipv4.addresses 10.1.8.13/24 \
ipv4.gateway 10.1.8.10 \
ipv4.dns 223.5.5.5 \
autoconnect yes
nmcli connection up ens33
7.4 Step 2 --- Director 开启转发 + 防火墙配置
bash
# 在 lvs 上执行
# 1. 开启 IP 转发(这是 NAT 模式的核心!)
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
# 输出: net.ipv4.ip_forward = 1
# 2. 配置防火墙
systemctl enable firewalld.service --now
firewall-cmd --set-default-zone=trusted
# success
# 3. 开启 MASQUERADE(SNAT),让 RS 的回包能出外网
firewall-cmd --add-masquerade --permanent
# success
firewall-cmd --add-masquerade
# success
⚠️ 为什么要开启 IP 转发? Linux 默认只会处理目标 IP 是本机的包。NAT 模式下,Director 收到的包目标 IP 是 VIP(本机),但转发给 RS 后,它还需要把 RS 的回包(RIP→CIP)转发给客户端------这需要 IP 转发能力。
7.5 Step 3 --- 配置 Real Server(Web 后端)
bash
# 在三台 web 节点上都执行
# 1. 安装 EPEL 源和 Nginx
wget -O /etc/yum.repos.d/epel.repo \
http://mirrors.aliyun.com/repo/epel-7.repo
yum install -y nginx
# 2. 为每台创建不同的主页,方便验证负载均衡效果
echo "Welcome to $(hostname)" > /usr/share/nginx/html/index.html
# 3. 启动 Nginx
systemctl enable nginx.service --now
# 4. 验证(在 client1 上测试)
curl 10.1.8.11 # → Welcome to web1.laogao.cloud
curl 10.1.8.12 # → Welcome to web2.laogao.cloud
curl 10.1.8.13 # → Welcome to web3.laogao.cloud
7.6 Step 4 --- 配置 LVS 规则
bash
# 在 lvs (Director) 上执行
# 1. 安装 ipvsadm
yum install -y ipvsadm
touch /etc/sysconfig/ipvsadm
systemctl enable ipvsadm --now
# 2. 创建虚拟服务(VIP:80,使用 RR 轮询调度)
ipvsadm -A -t 10.1.1.10:80 -s rr
# 3. 添加 3 台 Real Server(-m 表示 NAT 模式)
ipvsadm -a -t 10.1.1.10:80 -r 10.1.8.11:80 -m
ipvsadm -a -t 10.1.1.10:80 -r 10.1.8.12:80 -m
ipvsadm -a -t 10.1.1.10:80 -r 10.1.8.13:80 -m
# 4. 查看规则
ipvsadm -Ln
预期输出:
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.1.1.10:80 rr
-> 10.1.8.11:80 Masq 1 0 0
-> 10.1.8.12:80 Masq 1 0 0
-> 10.1.8.13:80 Masq 1 0 0
🎉 Forward 列显示
Masq(MASQUERADE),说明这是 NAT 模式!
7.7 Step 5 --- 验证负载均衡
bash
# 在外网客户端 client2 上测试
# 发送 90 个请求,统计每台 RS 收到的次数
[root@client2 ~]# for i in {1..90}; do curl -s 10.1.1.10; done | sort | uniq -c
30 Welcome to web1.laogao.cloud
30 Welcome to web2.laogao.cloud
30 Welcome to web3.laogao.cloud
🎯 完美! 每台 RS 恰好收到 30 个请求(90÷3),证实 RR 轮询调度正在生效。
7.8 Step 6 --- 切换为加权调度(WRR)
bash
# 在 lvs 上执行
# 1. 修改调度算法为加权轮询
ipvsadm -E -t 10.1.1.10:80 -s wrr
# 2. 设置不同权重(web1=1, web2=2, web3=3)
ipvsadm -e -t 10.1.1.10:80 -r 10.1.8.11:80 -m -w 1
ipvsadm -e -t 10.1.1.10:80 -r 10.1.8.12:80 -m -w 2
ipvsadm -e -t 10.1.1.10:80 -r 10.1.8.13:80 -m -w 3
# 3. 查看更新后的规则
ipvsadm -Ln
预期输出:
TCP 10.1.1.10:80 wrr
-> 10.1.8.11:80 Masq 1 0 30
-> 10.1.8.12:80 Masq 2 0 30
-> 10.1.8.13:80 Masq 3 0 30
再次测试:
bash
[root@client2 ~]# for i in {1..90}; do curl -s 10.1.1.10; done | sort | uniq -c
15 Welcome to web1.laogao.cloud
30 Welcome to web2.laogao.cloud
45 Welcome to web3.laogao.cloud
📊 请求分布为 15 : 30 : 45 = 1 : 2 : 3,恰好等于权重比例!
7.9 补充:内网客户端访问问题
上面的测试中,内网的 client1(10.1.8.21)也可以直接访问 VIP:
bash
[root@client1 ~]# for i in {1..90}; do curl -s 10.1.1.10; done | sort | uniq -c
15 Welcome to web1.laogao.cloud
30 Welcome to web2.laogao.cloud
45 Welcome to web3.laogao.cloud
但如果 client1 想保持客户端 IP 给 RS 感知,需要给 RS 添加静态路由:
bash
# 在 3 台 web 节点上执行:
# 让发往 client1 的回包经过 LVS
nmcli connection modify ens33 \
ipv4.routes '10.1.8.21 255.255.255.255 10.1.8.10'
nmcli connection up ens33
7.10 持久化保存
bash
# 保存 LVS 规则,确保重启后不丢失
ipvsadm-save -n > /etc/sysconfig/ipvsadm
八、总结
📊 核心要点回顾
┌─────────────────────────────────────────────────────────────┐
│ LVS 知识地图 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────────────┐ │
│ │ 工作位置 │────►│ Netfilter INPUT │ 劫持发往本机的包 │
│ └──────────┘ └──────────────────┘ │
│ │
│ ┌──────────┐ ┌──────────────────┐ │
│ │ 三大模式 │────►│ NAT / TUN / FullNAT │ DR(本文未涉及) │
│ └──────────┘ └──────────────────┘ │
│ │
│ ┌──────────┐ ┌──────────────────┐ │
│ │ 十种算法 │────►│ 静态: RR/WRR/DH/SH │ │
│ └──────────┘ │ 动态: LC/WLC/SED/ │ │
│ │ NQ/LBLC/LBLCR│ │
│ └──────────────────┘ │
│ │
│ ┌──────────┐ ┌──────────────────┐ │
│ │ 管理工具 │────►│ ipvsadm │ 用户态配置接口 │
│ └──────────┘ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
🎯 选型建议
| 场景 | 推荐模式 | 推荐算法 |
|---|---|---|
| 小规模内网 Web 集群 | NAT | WRR 或 WLC |
| 大流量高并发 | TUN | WLC |
| 需要端口映射 | NAT | WRR |
| 跨机房/跨网段 | TUN | WLC |
| 缓存集群 | NAT/TUN | DH 或 LBLC |
| Session 保持需求 | 任意 | SH |
📚 延伸学习
- Keepalived --- 给 LVS 加上健康检查和主备高可用
- LVS + Nginx 组合 --- LVS 做四层入口 + Nginx 做七层反向代理
- 阿里云 SLB --- 底层就是经过大量优化的 LVS 变体
📝 本文基于 LVS 官方文档及实战经验整理,适合运维工程师和架构师入门参考。如有疑问,欢迎留言交流!