一篇写给自己的 LVS 学习笔记,用最直白的方式讲清楚 NAT、DR、TUN 是什么、怎么配、用在哪。
前言
最近在学习 LVS(Linux Virtual Server),过程中走了不少弯路。网上资料很多,但要么太理论看不懂,要么太零碎串不起来。
这篇文章是我学习过程的沉淀。我会用自己的理解 ,用最直白的方式,把 LVS 是什么、三种模式怎么工作、底层原理是什么、什么时候用哪个,彻底讲清楚。
如果你也在学 LVS,希望这篇文章能帮你省下一些时间。
一、LVS 是什么?
一句话:LVS 是 Linux 内核内置的四层负载均衡器。
- 四层:工作在 TCP/UDP 协议层,只关心 IP 地址和端口号,不关心 HTTP 内容
- 内核内置 :LVS 是 Linux 内核的一个模块(
ip_vs),不需要安装额外软件 - 负载均衡器:把海量请求分发到后端的多台服务器上
一个比喻:
想象你开了一家全国连锁奶茶店,生意好到一家店根本忙不过来。
- LVS = 总店前台,负责接电话并把订单分配给各分店
- VIP(虚拟 IP)= 总店的公开电话,所有客户只知道这一个号码
- RS(Real Server)= 各分店,真正制作奶茶的地方
客户打电话(发请求)到总店号码(VIP),前台(LVS)根据某种规则(轮询、最少连接等),把订单转给某个分店(RS)。分店做好奶茶后,直接寄给客户,不需要再经过前台。
这就是 LVS 的核心思想:用一个虚拟入口,把流量分散到多台真实服务器上。
二、LVS 的三种工作模式
LVS 有三种工作模式:NAT 、DR 、TUN。这是 LVS 最核心、最容易混淆的知识点。
我们先给一个总览:
| 模式 | 一句话概括 | 性能 | 网络要求 |
|---|---|---|---|
| NAT | LVS 当网关,进出都经过 LVS | 低 | 可跨网段 |
| DR | LVS 改 MAC 地址,RS 直接回客户端 | 最高 | 同一局域网 |
| TUN | LVS 套 IP 隧道,RS 直接回客户端 | 中 | 可跨网段 |
下面逐一详细讲解。
模式一:NAT(网络地址转换)
一句话:LVS 像个路由器,请求和响应都经过它。
工作流程:
客户端 -> LVS -> RS -> LVS -> 客户端
- 客户端请求发给 LVS(VIP)
- LVS 把目标 IP 从 VIP 改成某个 RS 的 IP(DNAT)
- RS 处理请求,把响应返回给 LVS(因为 RS 的网关指向 LVS)
- LVS 把源 IP 从 RS 的 IP 改回 VIP(SNAT),发给客户端
核心操作:LVS 修改 IP 地址(三层)
配置要点:
bash
# LVS 上开启路由转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# 添加 LVS 规则(-m 表示 NAT 模式)
ipvsadm -A -t 192.168.1.100:80 -s rr
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.10:80 -m
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.20:80 -m
# RS 上把网关指向 LVS
route add default gw 192.168.1.100
优缺点:
| 优点 | 缺点 |
|---|---|
| LVS 和 RS 可以跨网段 | 响应也经过 LVS,LVS 成为瓶颈 |
| RS 不需要特殊配置 | 性能相对最低 |
| 可以隐藏 RS 的真实 IP |
适用场景:
- RS 只有内网 IP,没有公网 IP
- 需要隐藏后端服务器
- 小型环境或测试环境
模式二:DR(直接路由)⭐ 最常用
一句话:LVS 只改 MAC 地址,RS 直接响应客户端,性能最高。
工作流程:
客户端 -> LVS -> RS(同网段)-> 直接返回客户端
- 客户端请求发给 LVS(VIP)
- LVS 根据调度算法选一个 RS,把目标 MAC 地址改成 RS 的 MAC,IP 地址不变
- 交换机根据 MAC 地址把包发给对应的 RS
- RS 处理请求,直接返回给客户端(不经过 LVS)
核心操作:LVS 修改 MAC 地址(二层)
关键前提:
- LVS 和所有 RS 必须在同一个局域网(同一个交换机/二层网络)
- RS 也必须配置 VIP(但配置在 lo 回环接口上,不对外响应 ARP)
配置要点:
bash
# LVS:配置 VIP 在别名接口
ifconfig eth0:2 192.168.1.200 broadcast 192.168.1.200 netmask 255.255.255.255 up
# LVS:添加 DR 规则(-g 表示 DR 模式)
ipvsadm -A -t 192.168.1.200:80 -s rr
ipvsadm -a -t 192.168.1.200:80 -r 192.168.1.10:80 -g
ipvsadm -a -t 192.168.1.200:80 -r 192.168.1.20:80 -g
# RS:配置隐藏 VIP
ifconfig lo:0 192.168.1.200 netmask 255.255.255.255 broadcast 192.168.1.200 up
route add -host 192.168.1.200 dev lo:0
# RS:抑制 ARP(关键!防止 IP 冲突)
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
为什么要抑制 ARP?
正常情况下,RS 配置了 VIP 就会在局域网里广播"VIP 是我的",导致 IP 冲突。抑制 ARP 就是让 RS 闭嘴,只乖乖接收 LVS 转发来的包,不对外宣称自己拥有 VIP。
优缺点:
| 优点 | 缺点 |
|---|---|
| 性能最高(响应不经过 LVS) | LVS 和 RS 必须在同一局域网 |
| LVS 只处理请求,吞吐量大 | RS 需要配置 VIP 和抑制 ARP |
| 支持海量并发 |
适用场景:
- 绝大多数生产环境
- 高并发 Web 服务
- 视频/文件下载服务
- DNS 负载均衡
为什么 DR 是绝对主流?
| 对比 | NAT | DR |
|---|---|---|
| LVS 处理请求 | ✅ | ✅ |
| LVS 处理响应 | ✅(瓶颈) | ❌(RS 直返) |
| 单机最大吞吐量 | ~1-2 Gbps | ~10-20 Gbps+ |
| 生产环境使用率 | ~10% | ~85% |
模式三:TUN(IP 隧道)
一句话:DR 的"跨机房版本",用 IP 隧道代替改 MAC 地址。
当 LVS 和 RS 不在同一个局域网时,无法通过改 MAC 地址来转发。TUN 模式解决了这个问题。
工作流程:
客户端 -> LVS -> [IP隧道] -> RS -> 直接返回客户端
- 客户端请求发给 LVS(VIP)
- LVS 把整个原始 IP 包封装在一个新 IP 包里,外层目标 IP 是 RS 的 IP
- RS 收到后解封装,看到里面的原始请求(目标 IP 仍是 VIP)
- RS 处理请求,直接返回给客户端(不经过 LVS)
核心操作:LVS 套一层 IP 头(IP-in-IP 隧道)
配置要点:
bash
# LVS:加载隧道模块,配置隧道 IP
modprobe ipip
ifconfig tunl0 192.168.1.200 netmask 255.255.255.255 broadcast 192.168.1.200 up
# LVS:添加 TUN 规则(-i 表示 TUN 模式)
ipvsadm -A -t 192.168.1.200:80 -s rr
ipvsadm -a -t 192.168.1.200:80 -r 192.168.1.10:80 -i
ipvsadm -a -t 192.168.1.200:80 -r 192.168.1.20:80 -i
# RS:同样加载隧道模块,配置隧道 IP,抑制 ARP
modprobe ipip
ifconfig tunl0 192.168.1.200 netmask 255.255.255.255 broadcast 192.168.1.200 up
route add -host 192.168.1.200 dev tunl0
# RS:抑制 ARP(类似 DR)
echo 1 > /proc/sys/net/ipv4/conf/tunl0/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/tunl0/arp_announce
TUN vs DR vs NAT:
| 对比 | DR | TUN | NAT |
|---|---|---|---|
| 核心操作 | 改 MAC 地址 | 套 IP 头 | 改 IP 地址 |
| 操作层级 | 二层 | 三层 | 三层 |
| 网络要求 | 同一局域网 | 可跨网段 | 可跨网段 |
| 响应路径 | RS 直返 | RS 直返 | 经过 LVS |
| 性能 | 最高 | 中等 | 最低 |
| RS 特殊配置 | 抑制 ARP | 隧道 + 抑制 ARP | 网关指向 LVS |
适用场景:
- 跨机房、跨地域负载均衡
- 云环境跨 VPC 分发
- 灾备场景(主 LVS 在北京,备用 RS 在上海)
三、LVS 的调度算法
LVS 支持多种算法来决定"下一个请求发给哪个 RS":
| 算法 | 说明 | 适用场景 |
|---|---|---|
| 轮询(RR) | 依次轮流分配 | RS 性能相近 |
| 加权轮询(WRR) | 按权重比例分配 | RS 性能不同 |
| 最少连接(LC) | 分配给当前连接数最少的 RS | 长连接场景 |
| 加权最少连接(WLC) | 考虑权重的最少连接 | 默认算法 |
| 源地址哈希(SH) | 同一源 IP 总是到同一 RS | 会话保持 |
| 目标地址哈希(DH) | 同一目标 IP 到同一 RS | 缓存服务器 |
配置示例:
bash
# -s rr 表示轮询算法
ipvsadm -A -t 192.168.1.100:80 -s rr
# -s wrr 表示加权轮询
ipvsadm -A -t 192.168.1.100:80 -s wrr
四、LVS 的底层原理:它本质上是个智能交换机
理解了三种模式之后,你会发现一个本质:
LVS 就是一个可以编程的、工作在四层的智能交换机/路由器。
- DR 模式 :LVS 在改 MAC 地址 → 像交换机
- NAT 模式 :LVS 在改 IP 地址 → 像路由器
普通交换机/路由器的"转发表"是学来的(MAC 表/路由表),而 LVS 的"转发表"是你用 ipvsadm 命令定义的调度规则。
这就是 LVS 的精髓:用软件定义的方式,实现高性能的四层流量分发。
五、LTS vs Nginx:四层 vs 七层
很多人会问:有了 LVS 还要 Nginx 吗?
答案是:它们不是替代关系,而是分层协作的关系。
| 对比 | LVS | Nginx |
|---|---|---|
| 工作层级 | 四层(IP + 端口) | 七层(HTTP/HTTPS) |
| 处理速度 | 内核态,极快 | 用户态,较快 |
| 单机吞吐量 | 百万级 QPS | 几万级 QPS |
| 内容识别 | ❌ 不能(不知 HTTP) | ✅ 能(URL、Cookie、Header) |
| SSL 终结 | ❌ 通常不支持 | ✅ 原生支持 |
实际生产架构:LVS 在前,Nginx 在后
Internet
│
▼
┌─────────────────────────────────┐
│ LVS (DR模式) - 四层入口 │ ← 处理海量 TCP 连接
│ 性能:100万+ QPS │
└─────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Nginx1 │ │ Nginx2 │ │ Nginx3 │ ← 七层处理:SSL 卸载、URL 路由
│ 5万QPS │ │ 5万QPS │ │ 5万QPS │ 缓存、动静分离
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└──────────────┼──────────────┘
▼
┌─────────────┐
│ 应用服务器 │
└─────────────┘
- LVS:扛住入口流量洪峰,做快速四层转发
- Nginx:做七层精细化分发(SSL 卸载、URL 路由、缓存)
六、LVS 与 iptables 的关系
LVS 和 iptables 都基于 Linux 内核的 Netfilter 框架。
| 概念 | 本质 |
|---|---|
| Netfilter | Linux 内核中的包过滤/修改框架 |
| iptables | 用户态工具,用来配置 Netfilter 规则 |
| ip_vs (LVS) | 内核模块,也是基于 Netfilter 实现 |
关系图:
┌─────────────────────────────────────────────────┐
│ Linux 内核 │
│ ┌─────────────────────────────────────────┐ │
│ │ Netfilter 框架 │ │
│ │ (内核中的包处理钩子) │ │
│ └─────────────┬───────────────────────────┘ │
│ │ │
│ ┌─────────────┴───────────────────────────┐ │
│ │ ip_vs (LVS 内核模块) │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────┴───────────────────────────┐ │
│ │ iptables │ │
│ │ (NAT/防火墙规则) │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
七、如何选择?决策树
开始
│
├─ LVS 和 RS 在同一个二层网络?
│ ├─ 是 ──→ 性能要求高吗?
│ │ ├─ 是 ──→ 【DR 模式】(95% 的情况选这个)
│ │ └─ 否 ──→ NAT 或 DR 都行
│ │
│ └─ 否(跨网段)──→ RS 有公网 IP 或支持隧道?
│ ├─ 是 ──→ 【TUN 模式】
│ └─ 否 ──→ 【NAT 模式】
│
└─ 需要隐藏 RS 的真实 IP?
└─ 是 ──→ 【NAT 模式】
一句话建议:
- 默认选 DR 模式(性能最高,绝大多数场景)
- 跨机房选 TUN 模式
- RS 没公网 IP 或需要隐藏 RS 选 NAT 模式
八、常用命令速查
bash
# 查看 LVS 规则
ipvsadm -ln
# 查看 LVS 统计信息
ipvsadm -ln --stats
# 添加虚拟服务(VIP)
ipvsadm -A -t 192.168.1.100:80 -s rr
# 添加真实服务器(RS)
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.10:80 -g # DR 模式
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.10:80 -m # NAT 模式
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.10:80 -i # TUN 模式
# 删除规则
ipvsadm -D -t 192.168.1.100:80
ipvsadm -d -t 192.168.1.100:80 -r 192.168.1.10:80
# 保存/恢复规则
ipvsadm-save > /etc/sysconfig/ipvsadm
ipvsadm-restore < /etc/sysconfig/ipvsadm
# 查看内核连接跟踪表
ipvsadm -lnc
九、总结
| 模式 | 一句话 | 性能 | 网络要求 | 生产使用率 |
|---|---|---|---|---|
| NAT | LVS 当网关,进出都经过 | 低 | 可跨网段 | ~10% |
| DR | LVS 改 MAC,RS 直接回 | 最高 | 同一局域网 | ~85% |
| TUN | LVS 套 IP 隧道,RS 直接回 | 中 | 可跨网段 | ~5% |
核心要点:
- LVS 是 Linux 内核内置的四层负载均衡器
- DR 模式性能最高,是生产环境绝对主流
- DR 的核心是"改 MAC 地址"+"RS 直接回客户端"
- TUN 是 DR 的跨机房版本
- LVS 和 Nginx 是协作关系,不是替代关系
- LVS 本质是个可以编程的智能交换机/路由器