Press "Enter" to skip to content

LVS负载均衡1-NAT、FULLNAT、DR、TUN模型原理

LVS(Linux Virtual Server)是一个虚拟服务器集群系统。工作在 OSI 模型的传输层,即四层负载均衡。LVS 本身实现了 NAT、DR、TUN 模型,这些模型仅做数据包的转发,而不会与客户端建立连接,成本低效率高。FULLNAT 基于 NAT 实现,LVS 本身不支持,需要额外对内核打补丁后才能使用。

本系列按照负载均衡器对数据包的处理方式分类,从计算机间通信的角度出发,浅谈 NAT、FULLNAT、DR、TUN 模型的实现原理。

1. 两台计算机如何在互联网中通信

在了解 LVS 负载均衡之前,先要搞清楚两台计算机如何在互联网中通信。茫茫互联网中,两台计算机如何才能找到对方?

我们先来看看,快递是如何被快递小哥完美地送到你手上的。根据你填写的地址,快递先送到你所在的省市区,接着在当前省市区找到你的门牌号,最后根据门牌号和姓名,再亲手把快递交给你。

两台计算机在互联网中的通信也是如此。首先需要知道双方的 IP 地址,即省市区,其次需要知道双方的 MAC 地址,即门牌号。MAC 地址标志着唯一的计算机。在同一台计算机上,可能有多个不同的服务,如何能像快递小哥按照姓名找到你一样,在计算机上找到对应的服务呢?没错,就是按照端口号。

这样,通信中每台计算机需要提供的信息就很清晰了,即 IP 地址、MAC 地址、端口号。总结一下,计算机之间通信必需的六个要素就是,源 IP 地址、端口号、源 MAC 地址,目标 IP 地址、端口号、目标 MAC 地址。

假设计算机 A 和计算机 B 在上述的网络拓扑图(不在同一局域网)中。可以很清晰地看到 计算机 A 和 计算机 B 通信需要五个步骤,其中 ①② 和 ④⑤ 的原理相同。现在我们来看看具体的每个步骤在计算机的世界中是如何实现的。

首先 A 和 B 的 IP 地址和端口号是已知的,即一个数据包从哪来要发往哪去。所以现在的问题是:A 如何能知道 B 的 MAC 地址?

最简单的方式就是 A 保存网络中全部设备的 MAC 地址,在发送时查询一下,这样就能得到 B 的 MAC 地址。但是网络中的设备有几十亿个,还在不断地增长,显然这种方式是不可取的。如果按照快递发送过程中,在每个驿站之间进行转移,这样只需要知道该发往的下一目的地在哪里,最终也能将快递成功地交到你的手上。在实际网络中发送数据包也是这样,现在的目标就是确定 “下一个目的地” 的 MAC 地址。

步骤 ①②:发送数据包至网关A 不知道 B 的 MAC 地址,且 A 和 B 也不在同一个局域网中。这时 A 会根据 ARP 协议先发出一个广播包,即目标 MAC 地址是 FF:FF:FF:FF:FF:FF 的数据包。当 交换机1 收到这个广播包之后,会将这个数据包转发给其他端口,并且记录 A 的 MAC 地址和交换机端口之间的映射关系,后续再看到这个 MAC 地址,就知道该从哪个端口转发出去。当 路由器1 收到广播包后,会将自己的 MAC 地址返回。A 接收到返回后,就知道 “下一个目的地” 的 MAC 地址了。A 重新发送数据包,将目标 MAC 地址填写为 路由器1 的 MAC 地址,并在本地的缓存表中记录返回的 MAC 地址。

查看当前设备缓存表里已存的 MAC 地址:arp -a

ARP 协议的目的就是找到“下一个目的地”的 MAC 地址,即 IP 地址和 MAC 地址之间的映射关系。当两台设备同处于一个局域网时,“下一个目的地” 就是目标设备的 MAC 地址,当两台设备不处于同一个局域网时,“下一个目的地” 就是网关的 MAC 地址。

步骤 ③:网关间跳转经过步骤 ①②,此时 路由器1 收到的数据包为 { A_IP、PORT、A_MAC } ➡ { B_IP、PORT、路由器1_MAC } 。收到数据包后,路由器1 查看自己的路由表,如下图所示。

查看当前设备设置的路由表:route -n

路由器1 会将 B_IP 与 路由表中每条记录的子网掩码(Genmask)做按位与运算。如果得到的结果和目的网络(Destination)相同,那么 “下一个目的地“ 的 MAC 地址,就是配置的网关(Gateway)的 MAC 地址,这种找到相邻网络的方式叫做 “下一跳机制”。如果网关的地址为 0.0.0.0,说明可以在局域网中直接通信,不需要 “下一跳”。至此,再次找到了 “下一个目的地” 的 MAC 地址,即 路由器2 的 MAC 地址。此时 路由器2 收到的数据包为 { A_IP、PORT、路由器1_MAC } ➡ { B_IP、PORT、路由器2_MAC } 。步骤 ④⑤ 和 ①② 的原理相同,在这里就不赘述了。

下一跳的目的就是找到“下一个目的地”,即下一步该到达哪里,侧重 “路线” 的选择,并由此获取到对应的 MAC 地址,继续传送数据包。

总结一下

  • 1.使用 ARP 协议找到网关出口或同一局域网内设备的 MAC 地址
  • 2.按照路由表的每条规则和 目标 IP 地址做按位与运算,找到相邻网关入口的 MAC 地址
  • 3.“下一个目的地” 和当前地址都仅仅相邻一步,且每次 “跳跃” 后的源 MAC 地址 和 目标 MAC 地址都会发生对应的替换
  • 4.数据包中,IP 地址指明起点终点,MAC 地址指明跳跃的节点,端口号指明对应的应用服务当然,光是找到对方还不够,还需要一个约定的交流方式,平时我们所熟知的各种协议,都是计算机「约定的交流方式」。

2. LVS 负载均衡

随着使用互联网的设备不断增长,服务端对应接收到的 HTTP 请求更是呈指数型的增长。当一台服务器无法承载非常大的请求量时,使用多台服务器来分摊请求。将请求分摊给多台服务器的行为,就称之为负载均衡

从网络中计算机通信的角度,而非使用更上层的应用(如 Nginx)出发,搭建四层负载均衡器后,数据包的发送链路为:CIP ➡ VIP ➡ DIP ➡ RIP,即 客户端 IP ➡ 虚拟 IP ➡ 分发 IP ➡ 真实服务器 IP。对于客户端来说,只需要知道请求到达的地址是 VIP,不需要考虑负载,即 CIP ➡ VIP 是固定的。

所以负载均衡器要做的事情,就是将 CIP 发送到 VIP 的数据包,经由 DIP 转发给 RIP,服务响应后再将响应的数据包返回给 CIP。

2.1 NAT 模式

红色表示发出的数据包,绿色表示返回的数据包,黄色表示负载均衡器修改的内容 ,虚线表示经过 N 个下一跳,即可以不在同一局域网内,实线表示只能 “跳跃一次”,即必须在同一局域网内。

  1. 当计算机发出一个请求的数据包到达负载均衡器后,负载均衡器将发送数据包的 { 目标 IP 地址、端口号、目标 MAC 地址 } 转换为 { 某台真实服务器的 IP 地址、真实服务的端口号、真实服务器的 MAC 地址 } ,其余信息不变。这种只转换数据包的目标设备信息,而不修改数据包的源设备信息,称之为 DNAT,即目标网络地址转换。
  2. 真实服务器收到请求的数据包,返回响应的数据包:{ 某台真实服务器的 IP 地址、真实服务的端口号、真实服务器的 MAC 地址 } ➡️ { 原始请求的 IP 地址、端口号、跳跃的 MAC 地址 } 。所以此时在服务器上查看 TCP 连接为:CIP ➡️ RIP。
  3. 真实服务器返回的数据包的 “下一个目的地” 必须是负载均衡器。如果返回数据包直接返回给客户端,客户端发现返回数据包的源设备信息和发出数据包的目标设备信息不一致,将会丢弃返回数据包。所以真实服务器的默认网关必须是 DIP,保证返回数据包的 “下一个目的地” 是负载均衡器。
  4. 当返回的数据包到达负载均衡器后,负载均衡器将返回数据包的 { 原始请求的 IP 地址、端口号、跳跃的 MAC 地址 } 转换为原始请求的 { 目标 IP 地址、端口号、目标 MAC 地址 } 。这种只转换数据包的源设备信息,而不修改数据包的目标设备信息,称之为 SNAT,即源网络地址转换。
  5. 负载均衡器返回数据包给客户端。

总结一下 NAT 模式的特点:

  1. 修改数据包的「源 IP 地址」或 「目标 IP 地址」,可以对端口进行转发
  2. 真实服务器的默认网关必须是负载均衡器,所以真实服务器和负载均衡器必须在同一个局域网内
  3. 所有的请求数据包、响应数据包都要经过负载均衡器

2.2 FULLNAT 模式

NAT 模式中,负载均衡器和真实服务器必须在同一局域网内,但在实际的开发过程中,真实服务器可能分布在不同的网段,甚至不同的城市。如何能将 NAT 模式应用在真实服务器分布在不同网段的场景下?

红色表示发出的数据包,绿色表示返回的数据包,黄色表示负载均衡器修改的内容 ,虚线表示经过 N 个下一跳,即可以不在同一局域网内,实线表示只能 “跳跃一次”,即必须在同一局域网。

  1. 当计算机发出一个请求的数据包到达负载均衡器后,负载均衡器会对请求数据包同时做 SNAT 和 DNAT,将请求数据包修改为:{ 均衡出口 IP 地址、端口号、负载均衡器的 MAC 地址 } ➡️ { 某台真实服务器的 IP 地址、真实服务的端口号、真实服务器的 MAC 地址 }。
  2. 这样负载均衡器就可以独立的和真实服务器进行数据包的传送。
  3. 真实服务器收到请求的数据包,返回响应的数据包:{ 某台真实服务器的 IP 地址、真实服务的端口号、真实服务器的 MAC 地址 } ➡️ { 负载均衡器的 IP 地址、端口号、负载均衡器的 MAC 地址 } 。此时在真实服务器上查看 TCP 连接为:DIP ➡️ RIP。
  4. 当返回的数据包到达负载均衡器后,负载均衡器将返回数据包再次同时做 DNAT 和 SNAT。
  5. 负载均衡器返回数据包给客户端。

总结一下FULL NAT 模式的特点:

  1. 同时修改数据包的「源 IP 地址」和「目标 IP 地址」,可以对端口进行转发
  2. 负载均衡器不需要以网关的形式存在,即负载均衡器可以和真实服务器在不同的网络中
  3. 真实服务器最终建立的连接是 DIP ➡️ RIP,无法获取真实客户端的 IP 地址
  4. 所有的请求数据包、响应数据包都要经过负载均衡器

LVS 本身不支持 FULLNAT 模式,需要额外对内核打补丁后才能使用。

可以看到在 NAT 和 FULLNAT 模式中,不管是请求数据包还是响应数据包,都要经过负载均衡器但是响应数据包一般要比请求数据包大很多,这可能会成为系统的瓶颈。如果能够将请求数据包转发到真实服务器之后,响应数据包由真实服务器直接返回,这样对负载均衡器的压力就小很多。这种模式又该如何实现?

2.3 DR 模式

如果真的能够由真实服务器直接响应客户端,而不经过负载均衡器。那么这个由负载均衡器直接响应回客户端的数据包需要满足什么条件,才能被客户端正常接收?

真实服务器发出的数据包,在客户端接收到的时候,一定要匹配得上从客户端发出的数据包。如果不匹配的话,客户端收到响应数据包后会直接将数据包丢弃。

客户端发出的请求数据包:CIP ➡️ VIP,则收到的响应数据包一定是 VIP ➡️ CIP。 做个小思考,为什么没有带上 MAC 地址?后文有解释~

但是 VIP 已经绑定在负载均衡器上,真实服务器也有多个,在连通的网络里,如何能让多个真实服务器和负载均衡器的 VIP 地址相同?并且真实服务器的 VIP 不能被其他设备访问的到。也就是说在每台真实服务器上的 VIP 地址,只能它们自己知道“我悄悄藏着 VIP”,别的设备压根不知道。

这里不得不提另一个非常神奇的 IP 地址 127.0.0.1/0.0.0.0。仔细想一下,127.0.0.1 不就是每台设备上都相同,“悄悄藏着”的 IP 地址吗,除了自己的其他设备都没办法访问。这个神奇的 IP 地址,叫做 Loopback 接口。它是一种纯软件性质的虚拟接口,当有请求数据包送达到 lo 接口,那么 lo 接口会将这个数据包直接 “掉头”,返回给这个设备本身,这就是“环回”接口的由来。所以,如果将 VIP 绑定在 lo 接口上,是不是就可以完成“只有自己知道这个 VIP,别的设备不知道”呢?

将 VIP 绑定在 lo 接口上,其实只完成了一半,只是做到了在多台真实服务器上绑定相同的 VIP 地址。还记得上篇文章中所讲的 ARP 协议吗,ARP 协议会采集在当前局域网中,除了自己之外的其他主机的 MAC 地址和 IP 地址的映射关系。而 VIP 是一个不能被别的设备采集到的地址,所以我们要对真实服务器的 ARP 协议做一些修改,让 VIP 不会被其他设备采集到。很显然,这不但要修改设备收到 ARP 请求之后的响应(arp_ignore 参数),也要修改设备向外通告 ARP 的请求 (arp_announce 参数)。

arp_ignore:定义接收 ARP 请求时的响应级别:

  • 0:响应任意网卡上接收到的对本机 IP 地址的 ARP 请求(包括环回网卡),不论目的 IP 地址是否在接收网卡上
  • 1:只响应目的 IP 地址为接收网卡地址的 ARP 请求 2:只响应目的 IP 地址为接收网卡地址的 ARP 请求,且 ARP 请求的源 IP 地址必须和接收网卡的地址在同网段

arp_announce:定义将自己地址向外通告时的通告级别:

  • 0:允许任意网卡上的任意地址向外通告
  • 1:尽量仅向目标网络通告与其网络匹配的地址
  • 2:仅向与本地接口上地址匹配的网络进行通告

可以看到,arp_ignore 为 1 并且 arp_announce 为 1 时,lo 接口上绑定的 VIP 可以被藏在本机上,只有自己知道。

(如图:红色表示发出的数据包;绿色表示返回的数据包;黄色表示负载均衡器修改的内容;虚线表示经过 N 个下一跳,即可以不在同一局域网内;实线表示只能 “跳跃一次”,即必须在同一局域网内)

1.当计算机发出一个请求的数据包到达负载均衡器后,负载均衡器修改请求数据包的 { 目标MAC 地址 } 为 真实服务器的 MAC 地址,其余信息不变。负载均衡器和真实服务器必须在同一局域网内,否则负载均衡器无法替换请求数据包的 { 目标MAC 地址 } 为 真实服务器的 MAC 地址

2.真实服务器收到请求的数据包,发现自己有一个 “隐藏“ 的 VIP,于是接收这个数据包,并交由对应的上层应用处理

3.处理完成后,将响应数据包直接返回给客户端。此时在真实服务器上查看 TCP 连接为:VIP ➡️ CIP

总结一下 DR 模式的特点

  1. 仅修改请求数据包的「目标 MAC 地址」,作用在数据链路层。因此负载均衡器必须和真实服务器在同一局域网内,且不能对端口进行转发
  2. 真实服务器中的 VIP,只能被自己 “看见”,其他设备不可知。因此 VIP 必须绑定在真实服务器的 lo 网卡上,并且不允许将此网卡信息经过 ARP 协议对外通告
  3. 请求的数据包经过负载均衡器后,直接由真实服务器返回给客户端,响应数据包不需要再经过负载均衡器

2.4 TUN 模式

除了直接修改请求数据包的目标 MAC 地址,做一次 MAC 地址欺骗之外,还有没有其他方式能够将响应数据包由真实服务器直接返回给客户端呢?看看 VPN 是怎么能够支持你远程办公的吧~

我们已经讨论过,如果真实服务器直接将响应数据包返回给客户端,那么真实服务器必须有一个 “隐藏” 的 VIP,即配置在 lo 网卡上并且不允许此 VIP 通过 ARP 协议对外通告。

(如图:红色表示发出的数据包;绿色表示返回的数据包;黄色表示负载均衡器修改的内容;虚线表示经过 N 个下一跳,即可以不在同一局域网内;实线表示只能 “跳跃一次”,即必须在同一局域网内)

1.当计算机发出一个请求的数据包到达负载均衡器后,负载均衡器不改变源数据包,而是在源数据包上新增一层 IP 首部 { 分发 IP、端口号、MAC 地址 } ➡️ { 真实服务器 IP、端口号、MAC 地址 }

2.真实服务器收到请求的数据包后,将最外层封装的 IP 首部去掉,发现还有一层 IP 首部,并且目标 IP 地址能够和 lo 上的地址匹配,于是收下请求数据包,并交由对应的上层应用处理

3.处理完成后,将响应数据包直接返回给客户端。此时在真实服务器上查看 TCP 连接为:VIP ➡️ CIP

总结一下 TUN 模式的特点

  1. 不改变请求数据包,而是在请求数据包上新增一层 IP 首部信息。因此负载均衡器不能对端口进行转发,但可以和真实服务器不在同一局域网内,且真实服务器需要支持能够解析两层 IP 首部信息,即需要支持“IP Tunneling”或“IP Encapsulation”协议
  2. 真实服务器中的 VIP,只能被自己 “看见”,其他设备不可知。因此 VIP 必须绑定在真实服务器的 lo 网卡上,并且不允许将此网卡信息经过 ARP 协议对外通告
  3. 请求的数据包经过负载均衡器后,直接由真实服务器返回给客户端,响应数据包不需要再经过负载均衡器

3. NAT、FULLNAT、DR、TUN模式总结

在 DR 和 TUN 模式中,负载均衡器只转发了请求数据包,响应数据包不经过负载均衡器,而是直接返回给客户端。解决了在通常情况下响应数据包比请求数据包大,如果请求和响应数据包都经过负载均衡器,在高并发下可能成为系统瓶颈的问题。

根据我们的推导过程,可以轻易地得出各种模式的特点和它们要解决的问题。

NAT 模式,通过修改数据包的「目标 IP 地址」和 「源 IP 地址」,将请求负载到多台真实服务器,是四层负载均衡模式中最基础的负载方式。因为它是对 IP 地址层面的修改,作用在网络层,所以可以对端口进行映射。真实服务器返回的响应数据包必须经过负载均衡器,所以要求真实服务器的默认网关是负载均衡器。

FULLNAT 模式,是对 NAT 模式的一种演进。通过同时修改「源 IP 地址」和「目标 IP 地址」,突破 NAT 模式中真实服务器的默认网关必须是负载均衡器的限制。但是由于同时修改了「源 IP 地址」和「目标 IP 地址」,真实服务器建立的真实连接和客户端毫无关系,所以会丢失客户端的信息。

DR 模式,是对 NAT 模式的另一种演进。由于真实请求中响应数据包比请求数据包大很多的特点,在高并发下会成为系统的瓶颈,于是将响应数据包直接由真实服务器返回给客户端。使用 MAC 地址欺骗来达到此目的,作用于数据链路层,所以不能对端口映射。并且在真实服务器上,必须有一个仅自己可见的 “隐藏” VIP。在网络中,真实的 VIP 绑定在负载均衡器上,用来接收客户端的真实请求数据包。而 “隐藏” 的 VIP 绑定在真实服务器的 lo 接口上,用来欺骗自己可以正常接收目标地址是 VIP 的数据包。所以真实服务器的默认网关也必须是负载均衡器。

TUN 模式,是对 DR 模式的一种演进。突破 DR 模式中真实服务器的默认网关必须是负载均衡器的限制。TUN 模式不会对源数据包进行修改,而是在源数据包上额外新增一条 IP 首部信息,所以不能对端口映射,且要求真实服务器必须能够卸载掉两层 IP 首部信息。

回顾之前的小思考题:为什么在说真实服务器能够正常接收负载均衡器转发的数据包的必要条件时,没有带上 MAC 地址?

在网络通信部分介绍 ARP 协议和下一跳机制时,我们提到数据包在网络中的转发和快递传送中的驿站类似,每一次数据包的发送,会不断地找到 “下一个目的地” 的 MAC 地址。所以,但凡涉及到物理端口的变迁,都涉及到源 MAC 地址的变化,这个变化是 IP 通信的特性,而并不是负载均衡的特点。

在对负载均衡的各个模式有一定的了解之后,下一篇我们来看看具体实践和配置 ~

参考资料:https://juejin.cn/post/7089982619856666661

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注