
LVS:在内核里做负载均衡——请求改个地址就转发,响应压根不回来
前言
聊负载均衡,大多数人张口就是 Nginx。但往流量入口再退一层,还有一个更老、更快、长在 Linux 内核里的方案:LVS(Linux Virtual Server)。
它比 Nginx 老得多——章文嵩博士 1998 年发起,现在已经是内核标准的一部分。它快的原因也简单:工作在内核空间的 INPUT 链上,数据包根本没到用户态就被改写转发了,没有进程、没有 socket、没有用户态开销。 " xgfone/snippet 仓库里这篇《LVS 负载均衡原理及安装配置详解》把原理、四种转发模式、八种调度算法和 Keepalived 高可用实验整理得很完整。这篇拆开讲,重点说清楚一件事:四种模式的区别,本质是"响应走不走调度器"的区别。
一、项目身份
LVS(Linux Virtual Server)是内核级四层负载均衡,由内核模块 ipvs 和用户态规则工具 ipvsadm 组成。
一句话说清楚:
ipvs 在内核 INPUT 链上拦截发往 VIP 的请求,按调度算法挑一台真实服务器、改写或封装数据包转发出去;ipvsadm 负责告诉它规则
架构分三层:调度层(Director Server,跑 ipvs)→ Server 集群层(Real Server)→ 共享存储(保证各 RS 数据一致)。
应用方向和效果:网站/服务入口的高性能四层负载均衡。目标是"以低廉的成本实现最优的性能"——用一堆普通 Linux 机器加内核转发,替代 F5 这类硬件负载均衡设备。它只管四层转发,不管 HTTP 语义(改写 URL、按路径分流这些是七层代理的活),所以常和 Nginx 分层用:LVS 做入口分发,Nginx 在 RS 上做七层。
二、基本工作原理:包在内核里拐了个弯
一次请求的完整路径:

注意 IPVS 的位置:它不在 PREROUTING 也不在 POSTROUTING,就挂在 INPUT 链上。请求"到达本机"但没进用户态,就被劫持转走了。这是它比 Nginx(用户态反向代理)快一档的根本原因。
组成两件套:
- ipvs:内核空间的转发代码,真正干活
- ipvsadm:用户空间 CLI,定义"什么是集群服务、谁是后端"
术语五个:DS(调度器)、RS(真实服务器)、VIP(对外服务 IP)、DIP(DS 内网 IP)、RIP(后端 IP)。后面所有模式都围绕这五个 IP 做文章。
三、四种模式:响应回不回来,决定了架构形态
四种模式的调度器侧动作各不相同,但真正拉开差距的是响应报文的路径。
NAT:响应也回来,调度器是必经之路

请求改目标 IP,响应改源 IP——一来一回都过 DS。约束和后果:
- RS 网关必须指向 DIP(响应不走 DS 回不去)
- DIP 和 RIP 必须同网段
- 好处:RS 可以用任意操作系统、支持端口映射——它是四模式里约束最宽松、性能上限最低的
DR:响应直接走,调度器只看请求

改的不是 IP 是 MAC——因为 DS 和 RS 在同一个二层网络,改完 MAC 包直接送进 RS。RS 处理完以 VIP 为源地址直接回客户端。请求过 DS,响应不过,这是 DR 吞吐高的原因。代价:
- DS 和 RS 必须同一机房(二层可达)
- 不支持端口映射
- RS 的 lo 上要配 VIP,且必须用
arp_ignore/arp_announce压住 RS 别应答 VIP 的 ARP——否则交换机学到"VIP 在 RS 上",流量绕过调度器直接打到一台 RS,负载均衡整个失效。这是 DR 实战第一大坑
TUN:隧道跨机房
在原 IP 包外面再套一层 IP 头(DIP→RIP),跨三层送到远端 RS;RS 拆壳后发现内层目标是自己 lo 上的 VIP,处理完同样直接回客户端。响应不经 DS,和 DR 一样;区别是能跨机房——代价是所有 IP 都要公网地址、RS 系统必须支持隧道。
FullNAT:NAT 的增强版
在 NAT 基础上引入 Local Address,把 CIP→VIP 完整转换成 LIP→RIP(两个内网 IP),从而跨 VLAN 通讯。代价和 NAT 一样:进出全过 LVS,文档建议上万兆网卡。(FullNAT 是阿里在内核里加的特性,标准内核 ipvsadm 不带。)
一张表收拢:
| 响应过 DS | RS 网关指向 DIP | 同机房 | 端口映射 | RS 系统 | |
|---|---|---|---|---|---|
| NAT | ✅ | 必须 | 需同网段 | ✅ | 任意 |
| FullNAT | ✅ | — | 可跨 VLAN | ✅ | 任意 |
| DR | ❌ | 禁止 | 必须同二层 | ❌ | 大多数 |
| TUN | ❌ | 不可能 | 可跨机房 | ❌ | 支持隧道 |
选型逻辑一句话:一般规模 DR 就够了(响应不过调度器);跨机房选 TUN;RS 异构或要端口映射忍痛选 NAT;大规模多 VLAN 上 FullNAT。
四、核心模块

八种调度算法,按"静态还是动态"分两组记:
静态(不看连接数):rr 轮询(假设所有 RS 一样强)、wrr 加权轮询(权重 0-100,B 权重 2 收到的请求是 A 的两倍)、dh 目标地址散列(同一目标 IP 固定打到同一台)、sh 源地址散列(同一客户端固定一台——会话保持的朴素实现)。
动态(看当前连接):lc 最少连接、wlc 加权最少连接(生产默认选它)、lblc 基于局部性的最少连接(同一目标 IP 尽量回同一台,兼顾缓存命中)、lblcr 复制版(维护目标 IP 到一组服务器的映射,防单点过载——防火墙场景常见)。
五、数据与状态流
数据面就是上面的转发链路;真正值得看的是状态怎么流转——健康状态和调度依据:
- 连接状态:ipvs 在内核里维护连接表(客户端→RS 的映射),四层模式有 TCP 状态跟踪,会话类调度(sh/lblc)依赖它
- 健康状态:LVS 本身没有健康检查。RS 挂了,ipvs 照样把请求往尸体上送——这是裸 LVS 最大的坑。Keepalived 的 TCP_CHECK 补上这块:探活失败摘除 RS,恢复自动加回(文档实验 1/2:关掉 RS1 的 nginx,流量全走 RS2;重启后 rr 调度恢复)
- VIP 归属:这是另一种"状态"——VIP 配在主 Keepalived 的网卡上,Master 停掉,VRRP 选举后 VIP 漂到 Backup(实验 3 验证:
ip addr能看到漂移前后)。客户端无感知,因为它们只认 VIP
六、跨端边界
四种模式各自的网络边界就是选型边界,已在第三节表格里。补充两条部署侧的:
- DR 的 ARP 抑制是跨机器的:不只在 RS 上配内核参数,文档给了三条备选路线——前端路由做静态绑定(未必有权限,设备可能是运营商的)、arptables 在 ARP 层过滤、改
arp_ignore/arp_announce(标准做法) - FullNAT 的带宽边界:进出全过 LVS,文档建议万兆网卡——转发面的天花板不在 ipvs,在网卡
七、配置边界
文档给了 NAT 和 DR 的完整可跑脚本,值得记的是几个容易踩的边界:
- NAT 必须:RS 网关指向 DIP;DS 开
ip_forward;关send_redirects(否则内核发 ICMP 重定向让客户端直连 RS,绕过调度器) - DR 必须:RS 网关不指向 DIP;VIP 用 /32 配在 lo:0 上;
arp_ignore=1、arp_announce=2四行参数一个不能少 - Keepalived 主备:同一份配置,只改
state MASTER/BACKUP和priority 100/90;VRRP 认证和virtual_router_id 51两边必须一致
八、扩展点
- 调度算法可换:改一行
-s wrr→-s wlc,规则重载即生效——算法是配置不是代码 - 集群化部署:单机 DS 是单点,文档给的进化路线是 LVS 集群 + OSPF + ECMP——同一 VIP 配在所有 LVS 上,交换机等价路由自然分流,宕机自动剔除、流量大了水平加机器。这是各大厂入口层的标准形态
- 与七层代理分层:LVS(四层)→ RS 上的 Nginx(七层)是经典组合,各干各的
- Keepalived 的 notify 机制:文档没展开,但主备切换时执行自定义脚本(告警、切 DNS)是标配扩展
九、风险点
- 裸 LVS 没有健康检查。不配 Keepalived 或等价探活,故障 RS 会持续接流量——这不是配置优化,是必配项
- DR 的 ARP 坑是静默的。
arp_ignore/arp_announce配错不报错,症状是负载"看起来不均"——实际是流量绕过了调度器直接命中某台 RS。排查手段是在 RS 上抓 VIP 的 ARP 包 - 调度器自身是单点。NAT/FullNAT 模式下响应也过 DS,它挂了整个入口没了——单机部署时,负载均衡器就是全站最大的单点,Keepalived 主备是底线
- 会话保持的脆弱性:sh 算法用源 IP 散列,NAT 出口环境下大量用户共享一个 IP,会把所有流量压到一台 RS;persistence 超时和调度算法要一起设计
- 文档本身的时代局限:这篇是老文(yum/ifconfig/route 时代),命令在 systemd/CentOS 8+ 要翻译成 ip/nmcli;
nb_get_retry等参数名在新版 Keepalived 有变动。原理不过时,命令照抄会摔 - 四层转发的天然盲区:ipvs 看不到 HTTP 状态码和 URL,后端"端口通但应用 500"在它眼里是健康——精细探活要靠七层工具补
记住
LVS 的全部魔法就一句话:在内核 INPUT 链上拦下发往 VIP 的包,改写或封装后扔给真实服务器——没有用户态,没有代理进程,这是它比 Nginx 快一档的原因。
四种模式的选型只看一个问题:响应回不回调度器。NAT 回来(RS 任意 OS,调度器成瓶颈),DR 不回来(同机房,吞吐最高),TUN 隧道跨机房,FullNAT 跨 VLAN。
还有两条铁律:裸 LVS 没有健康检查,Keepalived 必配;DR 的 arp_ignore/arp_announce 四行参数,少一行负载均衡就静默失效。
参考资源
- 原文:xgfone/snippet《LVS 负载均衡原理及安装配置详解》github.com/xgfone/snippet
- 上游来源:cnblogs liwei0526vip、lgfeng 两篇(2012-2017 年间整理)
- 官网:linuxvirtualserver.org
