---
title: LVS 技术解析
taxonomy:
    category: docs
---

本节将深入剖析 LVS 软件的技术原理，探索其设计思想，并追踪数据包的修改和传递路径。

### 章文嵩博士创造 IPVS

1998 年，章文嵩正在读博士二年级，他发现 Cisco 的硬件负载均衡器售价昂贵，于是利用了两周的课余时间，创建并开源了 LVS（当时称为 IPVS）。如今，LVS 技术所创造的商业价值已无法估量，互联网上的绝大部分数据包都由 LVS 或承袭 LVS 思想的软件处理。

### 融入 Linux Kernel

2004 年，LVS（IPVS）被纳入了 kernel 2.4，从此之后，所有 Linux 系统都具备了变身为负载均衡器的能力。

### LVS 基本原理

LVS 的基本原理可以用一句话概括：通过修改 MAC 层、IP 层、TCP 层的数据包，实现了一部分交换机和网关的功能，从而指挥流量到达真正的服务器上。

LVS 有三种常用模式：

1. NAT 模式：即网关模式，双向流量均经过网关转发，性能开销最大。
2. TUN 模式：类似于单臂路由，性能高且可跨越机房。
3. DR 模式：仅适用于局域网，但性能惊人，因为回程流量不返回网关，直接在局域网内传输给客户端。

我们以最能体现 LVS 思想的 DR 模式为例，展示 LVS 的基本原理。

### DR 模式数据包推演

![](https://qn.lvwenhan.com/2023-01-08-16731922967424.jpg)
<center>图 6-4 LVS DR 模式架构图</center>

LVS 在 DR 模式时，运行架构如图 6-4 所示。在 DR 模式下，LVS 只负责修改数据包，不充当网关的角色。因此，我们仍然需要一个网关来执行公网 IP 和私网 IP 之间的 NAT 转换。假设客户端 IP 为 123.123.123.123，它向 110.242.68.3 的 80 端口发起了一个 HTTP 请求。

当网关接收到一个发送给 110.242.68.3 的数据包时，发现协议为 TCP，目标端口为 80。通过查询自己的 NAT 表，网关发现内部 IP 为 10.0.0.100（即虚拟 IP），内部端口为 80。于是，网关向局域网发送了一个 IP 包。由于端口和协议保持不变，本次网络请求中的关键数据有四个：源 IP 地址、目的 IP 地址、源 MAC 地址和目的 MAC 地址。

1. 客户端发给网关的数据包情况为：
    1. 源 ip：123.123.123.123
    2. 目的 ip：110.242.68.3
    3. 源 MAC：客户端 MAC
    4. 目的 MAC：网关 MAC
2. 网关向局域网发出的数据包情况为：
    1. 源 ip：123.123.123.123
    2. 目的 ip：10.0.0.100（变了）
    3. 源 MAC：网关 MAC（变了）
    4. 目的 MAC：LVS MAC（变了）
3. LVS 接到该数据包后，会选择一个后端服务器，假设它选中的是 10.0.0.1 来真正处理请求，则 LVS 会对数据包进行如下修改后，再发送给 10.0.0.1：
    1. 源 ip：123.123.123.123
    2. 目的 ip：10.0.0.100
    3. 源 MAC：LVS MAC（变了）
    4. 目的 MAC：10.0.0.1 的 MAC（变了）
4. 10.0.0.1 在收到该数据包后，发现这个包的目的 MAC 地址确实是自己，而且目的 ip 10.0.0.100（VIP）也是自己，于是对该数据包进行正常的处理，然后将处理结果发送出去：
    1. 源 ip：10.0.0.100
    2. 目的 ip：123.123.123.123
    3. 源 MAC：10.0.0.1 的 MAC
    4. 目的 MAC：网关 MAC（因为目的 ip 不在“ip+子网掩码”所确定的局域网范围内，所以该数据包会被发送给网关）
5. 网关收到返回的数据包后，通过查询“五元组关系表”，对端口和 ip 信息做出正常的 NAT 修改后，将数据包发送回 123.123.123.123，请求结束。

### DR 模式的特点

通过前面的推演过程，大家可以看出 DR 模式的特点：

1. LVS 只需处理正向数据包，通常正向数据包（请求）远小于反向数据包（响应），因此带宽占用较低。
2. 反向数据包通过标准的二层以太网传输，每台上游服务器都能达到自己的线速（网络设备接口协商速率，理论上的最大数据传输速率）。
3. 只能在相同的二层网络下工作（即同一个局域网），架构上有局限，同时安全性较差。
4. 需要在每台上游服务器上将 VIP（10.0.0.100）配置为 lo（本地回环）接口的 IP。
5. 需要让每台上游服务器只响应真实 IP（如 10.0.0.1）的 ARP 查询请求，如果不小心回复了针对 VIP 的 ARP 请求，将会引发混乱：局域网内有多台机器同时声称自己拥有 10.0.0.100 这个 IP，交换机会崩溃。

在生产环境部署中，由于 LVS 集群是所有流量的入口，所以其可用性需要非常高，一般不会只部署在一个机房里，因此最常用的是 NAT 模式：双向流量都经过 LVS 集群，这样可以实现多地多中心的跨公网多活。

### LVS 设计思想

通过上述过程，你应该能理解 LVS 的运行原理：它通过在 LVS 和上游服务器上配置虚拟 IP，以修改数据包后再发送为手段，在标准以太网模型下构建了一个可行的负载均衡系统。它不像交换机那样完全不修改数据包，也不像网关那样维持一个对应关系并修改很多东西，它修改了数据包，但不多，因此可以实现非常高的性能。

#### 内核态

LVS 的数据处理组件 IPVS 运行在内核态，避免了用户态 IPVS 进程和内核态 Linux 网络进程之间频繁的状态切换导致的内存读写开销，在高并发下这种设计可以带来非常高的性能收益。由于有内核态支持，LVS 比 HAProxy 和 Nginx 的单机性能都要强很多。

2014 年，eBPF 首次被引入了 Kernel 3.18，它的出现让新时代的 LVS 不再需要合并进内核才能使用内核态，让普通软件也能直接进入内核态，为高性能软件打开了一扇大门。eBPF 是目前最热门的内核相关技术，它为我们自行开发属于自己的内核态软件提供了可能——除了合并进内核之外，Kernel 的用户有了自己“热加载”内核代码的能力。

### 专业的负载均衡协议：OSPF/ECMP

LVS 是运行在标准以太网模型下的负载均衡软件，配合 Keepalived 可以实现高可用。而 OSPF/ECMP 协议是专业的多链路路由协议，可以实现不丢包的多活。

OSPF：开放式最短路径优先协议，一种基于链路状态的内部网关协议。每个 OSPF 路由器都包含了整个网络的拓扑，并计算通过网络的最短路径。OSPF 会通过多播的方式自动对外传播检测到的网络变化。

ECMP：等价多路径协议。当存在多条不同的链路到达同一目的地址时，利用 ECMP 可以同时使用多条链路，不仅增加了传输带宽，还可以无时延、无丢包地备份失效链路的数据传输。如果使用传统的路由算法，只能利用其中的一条链路进行数据的传输，还存在丢包的可能性。

#### LVS 拆分了网关单点

LVS 是网关型负载均衡继续拆单点的结果：LVS 将网关这个单点拆分成了“重定向”和“转发”，自己只承担数据包重定向工作，将转发留给基础网以太网来解决，在单机上实现了非常高的系统容量。在最新的 x86 服务器上，单个 LVS 即使在开销更大的 NAT 模式下也可以实现大约 20G 的 TCP 带宽—— [用 dperf 测试 LVS 的性能数据](http://s8u.cn/pRFcV)。
