20 张图让你彻底掌握负载均衡的秘密!
时间:2021-09-10 16:31:49
手机看文章
扫描二维码
随时随地手机看文章
[导读]前言今天我们来深度解密一下负载均衡器LVS的秘密,相信大家看了你管这破玩意儿叫负载均衡?这篇文章后,还是有不少疑问,比如LVS看起来只有类似路由器的转发功能,为啥说它是四层(传输层)负载均衡器呢,今天我们就来逐渐揭开LVS的迷雾,本文将会用图解的方式浅入深地探讨LVS的工作机制最...
前言
今天我们来深度解密一下负载均衡器 LVS 的秘密,相信大家看了你管这破玩意儿叫负载均衡?这篇文章后,还是有不少疑问,比如 LVS 看起来只有类似路由器的转发功能,为啥说它是四层(传输层)负载均衡器呢,今天我们就来逐渐揭开 LVS 的迷雾,本文将会用图解的方式浅入深地探讨 LVS 的工作机制最好大家对网络是如何连接的,数据包的收发机制有所了解,这样会很容易理解本文的知识点,如果对此没概念,建议大家看看这篇文章,把网络是如何连接的给你安排得明明白白没看过也没关系,本文会对一些必要的知识点做些铺垫,争取让大家都能看懂负载均衡器的诞生
在很长一段时间内小章公司的 DAU(日活)不超过 10,所以他只部署了一台机器,毕竟多一台机器要加钱,而且就算挂了也影响不了几个用户- 占用过多公网 IP,要知道现在租一个公网 IP 可是要好几千
- DNS 缓存可能会引起致命故障
根 DNS 服务器 ->顶级DNS服务器->权威DNS服务器这三步查找才能解析到域名对应的 ip,可想可知这个解析是有多么耗时,所以一般会有 DNS 缓存,DNS 缓存主要有「浏览器缓存」,「操作系统缓存」,「路由器缓存」,「ISP 缓存」四种- 对外用公网 ip(以下我们简称 VIP) 承接所有流量,对内则与真实的服务器(即 Real Server,以下简称 RS)通信,与 RS 在同一个内网里
- LB 只负载转发请求的工作,实际的处理逻辑交由其背后的 RS,RS 处理完后将响应包发给 LB,然后 LB 再返回给 client
NAT
接下来的重点就是 LB 是如何工作的了,首先要明白,当我们说收到一个请求时,实际上收到的是一个数据包,那么这个数据包长啥样呢源IP,目的IP,源端口,目的端口,简称 TCP 四元组,四元组唯一确定一条链接,在传输过程中四元组是不会变的,现在 LB 收到这个数据包之后,想将其转发给其背后的服务器,就要把目的 IP 改成服务器的 IP(假设为第二台机器,其 IP 地址为 192.168.0.3),那么修改后的数据包如下DR
经过这样的设计,由于 LVS 负载均衡的作用,轻松解决了单机瓶颈,小章的公司顺利度过了 C10K(并发连接 1 万),C20K,。。。。的问题,度过了瓶颈期,但随着并发数越来越高,小章发现了一个大问题,LVS 逐渐扛不住了,因为所有数据包的进出都要经过它,这让它成为了很大的瓶颈,随着 RS 水平扩展数量越来越多, LVS 迟早要挂掉。能否让 LVS 只负责转发请求包,但响应的数据包直接经由 RS 返回给客户端呢,类似下面这样- 首先 LVS 还是要承载所有的请求流量(接收所有数据包),然后再根据负载均衡算法转发给 RS
- RS 处理完后是不经过 LVS,直接将数据包转发给路由器再发给客户端的,意味着 RS 必须要有与 LVS 同样的 VIP(四元组不能变),另外由以上拓扑图可知,它们也必须在同一个子网里(严格地说,应该是同一个 vlan,因为是通过交换机通信的),这就意味着 LVS 和 RS 都必须要有两个 IP,一个 VIP,一个子网 IP
物理网卡:可以插网线的网卡,如果有多个网卡,我们一般将其命名为 eth0,eth1。。。,如果一个网卡对应多个 IP,以 eth0 为例,一般将其命名为 eth0,eth0:0,eth0:1。。。eth0:x,比如一台机器只有一个网卡,但其对应两个 IP 192.168.1.2, 192.168.1.3,那么其绑定的网卡名称分别为 eth0,eth0:0虚拟网卡:虚拟网卡通常被称为 loopback,一般命名为 lo,是一个特殊的网络接口,主要用于本机中各个应用之间的网络交互(哪怕网线拔了,本机各个应用之间通过 lo 也是能通信的),需要注意的是虚拟网卡和物理网卡一样,也可以绑定任意 IP 地址,如果在虚拟网卡配置了任何的 IP 地址,只要有物理网卡,就能到收到并处理目的 IP 为虚拟网卡上 IP 的数据包,lo 默认绑定了 127.0.0.1 这个本地 IP ,如果要绑定其他的 IP,对应的网卡命名一般为 lo:0,lo:1。。。
1. arp_ignore=1
首先我们知道 LVS 和 RS 都位于同一个子网,我们需要了解一下子网的工作机制:子网一般称为以太网,主要用 mac 地址来通信,位于 ISO 模型的二层,一开始内网的机器互相不知道彼此的 mac 地址,需要通过 arp 机制来根据 IP 获取其对应的 mac,获取之后首先会在本地的 arp 表记录此 IP 对应的 mac(下次就直接在本地缓存查找 mac),然后会在包头上附上 IP 对应的 mac,再将包传输出去,交换机就会找到对应的机器了所以当客户端请求 VIP 后,请求到达了上图中的路由器,路由器要转发给此 IP 对应的机器,于是它首先发起了一个 arp 请求希望拿到 VIP 对应的 mac 地址。那么现在问题来了,由于三台机器的 IP 都为相同的 VIP,如果都响应了 arp 请求,就相当于一个 IP 对应了三个 mac,路由器该用谁的 mac 地址呢?解决方案很简单:由于请求都要经过 LVS,所以只让 LVS 响应 arp,抑制住另外两台 RS 对 VIP 的 arp 响应即可,不过请求到达 LVS 后,LVS 还要将包转发给 RS(假设为 RS2 吧),此时也要用到 arp 来获取 RS 的 mac 地址,但是注意从 LVS 发起的 arp 请求目的 IP 变成了 RS2 的内网 IP:115.205.4.217(绑定在物理网卡 eth0 上)。综上所述, RS 不能响应目的 IP 为虚拟网卡绑定的 VIP 的 arp 请求,但能响应目的 IP 为物理网卡绑定的 IP 的 arp 请求,这就是为什么 RS 需要把 VIP 绑定在虚拟网卡上,而把内网 IP 绑定在物理网卡上的真实原因,就是为了 arp 响应的需要当然一般服务器默认都会响应所有 IP 的 arp 响应,所以需要对 RS 做额外配置,即net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.lo.arp_ignore=1
设置的 arp_ignore=1 表示的含义如下1 - reply only if the target IP address is local address
configured on the incoming interface
即我们上述所说的,只响应目的 IP 为接收网卡(即物理网卡)上的 IP 的 arp 请求(会忽略目的 IP 为虚拟网卡 上 VIP 的 arp 请求)作了以上的设置后由于针对 VIP 的 arp 请求只有 LVS 会响应(路由器收到 LVS 的 arp 响应后会在 arp 缓存表里记录 VIP 的 mac 地址为 LVS 的mac),所以可以保证所有请求都会打到 LVS 上,然后 LVS 也顺利地将数据包发给了 RS2,RS2 处理好后就准备把数据包从网卡发出了,但这里需要注意,RS2 可不能直接把数据包通过物理网卡 eth0 传出去的,这样会导致数据包的源 IP 被修改为 eth0 的 IP(即 115.205.4.217),会导致四元组发生变化(别问为什么,问就是协议栈的关系),所以我们需要额外配置一下,让数据包使用 lo 接口发送,如下route add -host 115.205.4.214 dev lo:0
# 添加一条路由,目标 IP 为 VIP 的数据包使用 lo 接口发送,这样响应报文的源 IP 就会为 VIP
然后再通过 eth0 发出去,这样可保证四元组不会发生变化。2. arp_announce=2
接下来还有一个问题,RS2 怎么将数据包传给它的网关(即路由器)呢,由于它们还是在同一个子网,所以也是通过 arp 的方式先获取到网关的 mac,然后在以太网包头上装上网关的 mac 传给网关的。但这里有一个点需要注意,通过 arp 获取网关的 mac 时,网卡会发送一个包含「源IP」,「目标 IP」,「源 mac」的 arp 广播包 net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.lo.arp_announce=2
arp_announce=2 表示的是忽略 IP 数据包的源 IP 地址,选择该发送网卡上最合适的本地地址作为 arp 请求的源 IP 地址上面这段有点绕,大家可以多读几遍好好体会一下,其实主要目的就是为了避免路由器的 ARP 缓存表误更新 VIP 的 mac 为 RS 的 mac从上面的介绍可以看出 DR 模式是比较复杂的,需要在 RS 上做额外的配置,所以线上一般使用 NAT 模式




