LVS四层负载均衡器原理和DR模式的搭建
什么是LVS(what)?
LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的*软件项目之一。后来被Linux内核收录,将LVS代码直接整合到Linux的内核中,使LVS成为内核程序而不是用户程序,这样LVS的逻辑以及数据均在内核态进行处理,不需要通过事件中断的方式copy到用户态,这样使LVS的性能更优。
为什么需要LVS(why)?
LVS是4层(IP:PORT)负载均衡器,主要解决高并发衍生服务器过载的问题。为了帮助理解,我们思考下面的场景:假设我们开发的某个电商项目部署在一个Tomcat容器里面运行(例如早期的淘宝),随着不断的推广和运营,日活用户量越来越大,假设达到每秒1W的并发,普通服务器上部署的单个Tomcat容器一般并发在800-1000左右,所以此时这个千级别并发的服务因为承受不了上W的并发会挂掉,如下图:
一般解决这个问题最快速、最直接的办法就是加机器,加完后如下图:
这种方式可行吗?答案是:不完全可行,原因是客户端一般是通过一个域名去访问应用服务的,一个域名只能解析一个IP,通常为了域名更方便记忆,直接使用80端口的方式,现在后端服务部署了10个tomcat,但是这10个tomcat是运行在不同的服务器上,他们的ip肯定不相同,现在面临的问题就是如何实现客户端访问一个IP负载到不同的IP上?
有两种办法解决上述问题:
1、基于DNS的负载均衡:使用域名系统通过将域名解析为服务器的不同IP地址来将请求分发到不同的服务器,但是DNS在负载均衡的算法实现上不太灵活。
2、基于任务分派器的负载均衡:目前有两种方式实现,一种是基于7层协议(URL级别的)的任务分派器(例如nginx),另一种是基于4层协议(IP:PORT级别的)的任务分派器(例如LVS),由于基于4层协议的任务分配器它并不需要承受所有客户端的TCP的3次握手和4次挥手的连接压力,而是直接转给后端负载服务,相反,7层协议需要承受TCP握手和挥手的连接压力,所以4层协议比7层协议性能更高,根据LVS官方给出经验:7层负载均衡器可以较轻松代理负载5台节点,当超过5个时,负载均衡本身就会成为新的瓶颈,而4层负载均衡器LVS可以代理负载25-100个(不同模式决定)应用服务器。
总结:LVS可以基于4层协议高效解决客户端访问一个IP负载到多个不同的IP的问题。加入LVS后的架构如下:
理解LVS 的waht和why之后,下面开始讲解LVS是如何实现一个IP负载到不同的IP上的。在讲解LVS之前这里先介绍后面频繁提到的几个关键字:
1、负载均衡器:表示LVS实现的负载均衡器。
2、客户端:表示任意请求客户端,例如浏览器、curl等。
3、Real Server:又被称为RS ,真实业务服务器,例如上面的业务Tomcat容器。
4、虚拟IP:又被称为VIP,LVS负载均衡器IP,在生产环境一般是域名映射的公网IP地址,给客户端访问的地址,例如www.taobao.com。
5、虚拟服务器:又称为代理服务器,又简称为DS。
6、ipvsadm: LVS内核态对应的用户态客户端程序,用来操作LVS配置,类似linux操作系统内核对应的systemctl管理命令。
LVS三大模式
NAT模式
TUN模式
DR模式
其中DR模式是较常用的模式,后面只会给出DR模式的完整搭建过程,其它模式只讲解原理。
NAT模式
NAT模式的出现是为了解决全球IP地址数量短缺的问题,NAT(Network Address Translation)翻译为:网络地址转换,NAT代理(例如公网路由器)的原理是通过占用一个连接到公网的IP,来代理某个局域网的多个内网IP(例如内网路由器或电脑主机),NAT代理层级可以是多个层级,但是至少要有一个层级是连到公网的且其它NAT代理的网关都配置到连接公网的路由器才能上网。
当某个电脑内网IP想要访问公网数据时(比如访问www.taobao.com),首先通过本机的内网IP二进制&子网掩码二进制(一般为255.255.255.0)得到下一跳的地址一般是WAN对应的LAN路由器(上一级的NAT代理)的地址,NAT代理会一层一层去修改请求TCP数据包的源IP地址直到修改为那个公网IP地址作为数据包的源IP后再发送搞公网的下一跳,当请求响应到NAT代理时,NAT会再次一层一层修改响应的TCP数据包的目标IP地址为源头那个电脑内网IP,使用NAT模式时需要保证你的每个路由器网关配置正确,使它最终能够走到公网那个路由器。
可见NAT需要接受请求并重新发起请求并接受响应,对于高并发的场景来说会影响性能。所以LVS虽然支持NAT模式,但是不建议作为优先使用的模式。
NAT模式架构图:
架构图流程说明:
1、客户端请求虚拟服务器的IP地址(Virtual IP Address),该请求首先到达LVS-NAT模式的负载均衡器上。
2、负载均衡器检查数据包的目标地址和端口号,如果匹配虚拟IP和端口,然后从虚拟服务器规则表找到对应的Real Server列表,通过调度算法从列表中选择一个Real Server,并将该连接和对应的Real Serve关系记录到哈希表中(最小连接数调度算法的依据,以及同一个TCP连接3次握手和4次挥手以及业务的数据包必须要发送到同一个Real Server的依据),然后,将数据包的目标地址和端口重写为所选Real Serve服务器的地址和端口,最后负载均衡器将数据包转发到Real Serve服务器。
3、Real Server处理完成后将响应TCP数据回复给负载均衡器。
4、负载均衡器收到Real Server回复后再次重写回复的TCP数据包。
5、最后负载均衡器将重写后的TCP数据包回复给客户端。
6、连接终止或超时后,连接记录将从哈希表中删除。
NAT模式拓扑:
下表为上图对应的搭建拓扑说明:
节点 |
服务器公网虚拟IP:PORT |
服务器内网IP:PORT |
角色 |
node1 |
10.68.212.101:80 |
10.68.212.1:80(下一跳网关地址) |
NAT模式负载均衡器 |
node2 |
无 |
10.68.212.102:80 |
Real Server 1 |
node3 |
无 |
10.68.212.103:80 |
Real Server 2 |
1、当某个客户端假设IP:PORT为:10.68.212.63:3456请求负载均衡器虚拟IP地址时,TCP数据包中的源IP:PORT和目标IP:PORT伪信息如下:
SOURCE: 10.68.212.63:3456 DEST:10.68.212.101:3456
2、负载均衡器根据调度算法(加权轮询、最小连接数、加权最小连接数)选择一个Real Server,假设选择到node3,那么此时负载均衡器将修改TCP的IP:PORT数据为:
SOURCE: 10.68.212.63:3456 DEST:10.68.212.103:3456
3、Real Server处理完成后通过找到下一跳(10.68.212.103二进制&255.255.255.0二进制,可以通过在线工具http://ip.soshoulu.com/ip_jisuan.aspx计算得到)为负载均衡器内网地址(10.68.212.1),回复的数据包流转到负载均衡器的TCP数据包IP相关信息如下:
SOURCE: 10.68.212.103:3456 DEST:10.68.212.63:3456
4、很明显上面回复如果直接给到客户端,客户端时不会接收的,因为IP信息和发出时的匹配不上(10.68.212.103不匹配10.68.212.101),所以此时负载均衡器需要再次修改回复的TCP数据包的IP信息如下:
SOURCE: 10.68.212.101:3456 DEST:10.68.212.63:3456
注意点:
1、一般我们局域网的NAT代理路由器只支持代理内网IP发出请求,不支持接受外部请求内网IP,因为不同局域网的内网IP是允许重复的,但是LVS的NAT模式是需要支持接受外部请求的,所以LVS是在NAT原理基础上进行改造的(重写TCP数据包),也就是LVS的NAT模式跟我们局域网的路由器NAT是有区别的。
2、NAT模式要求集群中涉及的服务均在同一个局域网(WAN)内,不能跨LAN。
NAT模式特性:
1、可以运行在任何支持TCP/IP的操作系统。
2、Real Server必须将网关指向负载均衡器。
3、扩展能力有限,官方保守估计当Real Server大于20个节点时,负载均衡器本身会成为瓶颈,因为NAT模式下负载均衡器需要处理请求和响应的TCP数据包。
4、集群可以在私有网络下运行。
以上为LVS NAT模式的核心原理,这里不给出搭建过程,如有兴趣可以查阅下面的官方文档链接完成搭建。
http://www.linux-vs.org/VS-NAT.html
TUN模式
TUN模式又称为IP隧道模式。
TUN模式架构图:
架构图流程说明:
1、客户端请求虚拟服务器的IP地址(Virtual IP Address)。
2、负载均衡器检查数据包的目标地址和端口号,如果匹配虚拟IP和端口,则从虚拟服务器规则表找到对应的Real Server列表,通过调度算法从列表中选择一个Real Server,并将该连接和对应的Real Serve关系记录到哈希表中(最小连接数调度算法的依据,以及同一个TCP连接3次握手和4次挥手以及业务的数据包必须要发送到同一个Real Server的依据),然后,负载均衡器将数据包再封装一层,将目标IP修改为所选的Real Server的IP(IP隧道模式核心就是IP嵌套IP),并将其转发到所选的Real Server服务器。下面会单独讲解IP嵌套IP的概念。
3、Real Server服务器收到数据包时对数据包进行解封(Real Server必须同时配置好IP隧道),将响应结果直接返回给客户端。
4、连接终止或超时后,连接记录将从哈希表中删除。
注意点:
1、IP隧道核心概念就是IP嵌套IP,假定虚拟服务的IP地址为:10.68.212.101,而Real Server分别为:10.68.212.102,10.68.212.103,当客户端请求目标地址为虚拟IP:10.68.212.101时,虚拟服务会将TCP数据包再封装一层,包装后的目标IP改为对应的Real Server,然后转发给Real Server。然后Real Server将其解封后发现里面目标IP是发往配置的虚拟IP地址,此时Real Server会接受并处理该数据包(而不是继续转发),最后将处理结果直接返回给客户端。
2、IP隧道模式允许跨局域网LAN。
3、IP隧道模式要求Real Server服务器使用的端口和虚拟服务的端口一致。
4、IP隧道模式需要有单独3个角色的IP:虚拟IP、负载均衡IP、Real Server IP。
5、IP隧道模式和NAT模式的区别在于IP隧道模式负载均衡器通过IP隧道转发,NAT模式负载均衡器通过NAT转发。
TUN模式特性:
1、由于负载均衡器不实际处理TCP请求和响应数据包,而是简单封装数据包进行转发,扩展性好,单个负载均衡器能够带动100个节点。
2、不能将网关指向负载均衡器,指向自有网关即可。
3、集群网络允许跨不同的LAN/WAN。
4、限制服务器必须“IP Tunneling”或者“IP Encapsulation”协议。
以上为IP 隧道模式的核心原理,这里不给出搭建过程,如有兴趣可以查阅下面的官方文档链接完成搭建。
http://www.linux-vs.org/VS-IPTunneling.html
DR模式
DR模式又称为直接路由模式,也是本章重点。这种模式特殊之处在于负载均衡器和Real Server共享虚拟IP地址,也就是Real Server和LVS负载均衡器服务器节点都要配置虚拟IP(VIP),但是我们知道IP地址是不能重复的,LVS怎么解决这个问题呢?
假设VIP地址为:10.68.212.100, 那么负载均衡器可以在对外公开的网卡接口上配置一个子接口IP来创建对外公开的VIP:10.68.212.100,而Real Server 则通过在回环路由(localhost所在的网卡)的网卡上配置一个子接口IP来创建不对外公开的VIP:10.68.212.100。这样负载均衡器和Real Server都拥有VIP:10.68.212.100。
注意,负载均衡器必须和Real Server直连在同一个LAN的WAN下,因为负载均衡器需要通过将数据帧的MAC地址更改为所选Real Server服务器的MAC地址,然后在LAN上重新传输的方式来找到对应的Real Server。
DR模式架构图:
架构图流程说明:
1、当客户端访问虚拟服务IP地址时,数据包首先到达对外公开的VIP所在的负载均衡器上。
2、负载均衡器检查数据包的目标地址和端口号,如果匹配VIP和端口,则从虚拟服务器规则表找到对应的Real Server列表,通过调度算法从列表中选择一个Real Server,并将该连接和对应的Real Serve关系记录到哈希表中(最小连接数调度算法的依据,以及同一个TCP连接3次握手和4次挥手以及业务的数据包必须要发送到同一个Real Server的依据),然后,负载均衡器根据配置的虚拟服务器规则表中的Real Server IP地址发起一个ARP协议广播到LAN,由LAN交换机找到返回该Real Server的MAC地址,最后负载均衡器将数据帧的MAC地址更改为所选Real Server服务器的MAC地址,在LAN上重新传输。
3、Real Server服务器收到数据包时会发现该数据包目标地址VIP为本地回环IP地址,此时将使用类似localhost的本地套接字处理方式进行处理,最后将处理结果直接返回给客户端。
4、连接终止或超时后,连接记录将从哈希表中删除。
DR模式特性:
1、由于负载均衡器不实际处理TCP请求和响应数据包,而是直接转发,扩展性好,单个负载均衡器能够带动100个节点。
2、不能将RS网关指向负载均衡器,指向自有网关即可。
3、跟TUN模式相比,这种方法没有IP隧道的开销。
4、要求负载调度器与实际服务器都有一块网卡连在同一物理网段上。
5、服务器网络设备(或者设备别名)不作ARP响应,或者能将报文重定向(Redirect)到本地的Socket端口上。
LVS负载均衡算法
在内核中的连接调度算法上,IPVS已实现了以下十种调度算法:
轮循调度(rr)
加权轮循调度(wrr)
最小连接调度(lc)
加权最小连接调度(wlc)
基于局部性的最少链接(lblc)
带复制的基于局部性最少链接(lblcr)
目标地址散列调度(dh)
源地址散列调度(sh)
最短预期延时调度(sed)
不排队调度(nq)
右边括号对应ipvsadm 命令 -s选项参数值。
DR模式搭建
1、准备3个测试节点服务器,笔者这里规划清单如下:
节点 |
角色 |
虚拟IP |
对外网卡IP |
node1 |
LVS负载均衡器 |
10.68.212.100 |
10.68.212.101 |
node2 |
Real Server1 |
10.68.212.100 |
10.68.212.102 |
node3 |
Real Server2 |
10.68.212.100 |
10.68.212.103 |
2、node2执行以下命令,通过安装httpd服务模拟web业务应用服务:
yum install -y httpd
# 写入点内容区分后面负载均衡测试效果
echo "this is node2 real server" > /var/www/html/index.html
# 启动httpd服务
systemctl start httpd.service
# 关闭防火墙
systemctl stop firewalld
3、node3执行以下命令,通过安装httpd服务模拟web业务应用服务:
yum install -y httpd
# 写入点内容区分后面负载均衡测试效果
echo "this is node3 real server" > /var/www/html/index.html
# 启动httpd服务
systemctl start httpd.service
# 关闭防火墙
systemctl stop firewalld
4、浏览器分别访问测试httpd启动情况,分别出现如下图表示正常:
5、所有节点检查安装ifconfig命令:
yum install -y net-tools.x86_64
6、调整Real Server的arp_ignore和arp_announce参数,它们都和ARP协议相关,主要用于控制系统返回arp响应和发送arp请求时的动作。这两个参数很重要,特别是在LVS的DR场景下,它们的配置直接影响到DR转发是否正常。(node2、node3都配):
echo 1 > /proc/sys/net/ipv4/conf/enp0s3/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/enp0s3/arp_announce
配置说明如下:
-
arp_ignore参数的作用是控制系统在收到外部的arp请求时,是否要返回arp响应,常用配置值为0,1,下面对其说明:
0:响应任意网卡上接收到的对本机IP地址的arp请求(包括环回网卡上的地址),而不管该目的IP是否在接收网卡上(默认)。
1:只响应目的IP地址为接收网卡上的本地地址的arp请求。
-
arp_announce的作用是控制系统在对外发送arp请求时,如何选择arp请求数据包的源IP地址,常用配置值0,1,2,下面对其说明:
0:允许使用任意网卡上的IP地址作为arp请求的源IP,通常就是使用数据包a的源IP(默认)。
1:尽量避免使用不属于该发送网卡子网的本地地址作为发送arp请求的源IP地址。
2:忽略IP数据包的源IP地址,选择该发送网卡上最合适的本地地址作为arp请求的源IP地址。
7、配置Real Server的VIP(node1、node2均需要配置),配置在环回网卡lo接口的子接口上,注意子网掩码为255.255.255.255:
ifconfig lo:1 10.68.212.100 netmask 255.255.255.255
8、node1节点创建VIP,先通过ifconfig命令查看网卡信息:
ifconfig
9、通过ifconfig命令在enp0s3网卡子接口上创建VIP,命令如下:
ifconfig enp0s3:0 10.68.212.100/24
10、将node1配置为路由器能力,使之接收到目标地址为VIP时做转发而不是直接自己处理数据:
echo 1 > /proc/sys/net/ipv4/ip_forward
11、node1安装ipvsadm客户端程序:
yum install -y ipvsadm
12、node1节点创建VIP规则:
# -A表示添加一个虚拟服务 -s表示调度schdule rr表示轮询
ipvsadm -A -t 10.68.212.100:80 -s rr
# -a表示添加一个Real Server -t表示使用TCP协议的服务 -g表示DR模式
# 更多关于 ipvsadm命令选项可以通过man ipvsadm查阅
ipvsadm -a -t 10.68.212.100:80 -r 10.68.212.102 -g
ipvsadm -a -t 10.68.212.100:80 -r 10.68.212.103 -g
# 查看LVS虚拟服务列表
ipvsadm -ln
至此DR模式搭建完毕,现在可以通过curl命令在其它服务器来刷新试下,效果如下图:
for i in {1..10}; do curl 10.68.212.100 ;done
注意,如果直接用浏览器访问的话,LVS会发生轮询不生效的问题,这个原因是:
1、浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,格式类似这样:Last-Modified: Fri, 12 May 2006 18:53:33 GMT
2、客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头,询问该时间之后文件是否有被修改过:If-Modified-Since: Fri, 12 May 2006 18:53:33 GMT
3、如果服务器端的资源没有变化,则自动返回 HTTP 304 (Not Changed.)状态码,内容为空,这样就节省了传输数据量。
至此,LVS DR模式4层负载均衡器搭建完毕,下面有几个思考问题:
1、LVS解决了Real Server的过载的问题,但是LVS本身存在单点问题,如果LVS挂了,那么整个服务将不可用。
2、目前搭建的LVS无法识别后端Real Server是否存活,如果某个Real Server服务挂掉,那么任何请求到这个Real Server的请求将连接失败,下面是我们停掉node2 httpd服务测试截图:
systemctl stop httpd
可以通过引入keepalived来解决上面的问题,后面有空会继续编写keepalived + LVS实现4层负载均衡的文章。
最后总结:
1、LVS是基于TCP第4层协议也就是IP:PORT级别上实现负载均衡。
2、LVS的搭建有3大模式,NAT模式性能属最差,常用的模式是DR模式。
3、LVS比较适合在不同的数据中心架构上做负载均衡,同一个数据中心内部使用Nginx这种Http URL级别的7层负载均衡器来负载Real Server(Tomcat),LVS负责负载Nginx(Real Server),大致架构图如下:
地理分布LVS集群系统可以带来以下好处:
使得用户访问离他们最近的系统,对用户来说体验到更快的响应速度,对服务提供商来说节约网络带宽,降低成本。
避免灾难导致系统中止服务。当一个地点发生地震、火灾等使得系统或者网络连接瘫痪时,所有的用户访问可以很快由其他地点的LVS集群来提供。除了已建立的连接中断以外,这一切对用户来说都是透明的。
---------------------- 正文结束 ------------------------
长按扫码关注微信公众号
Java软件编程之家
上一篇: 四层负载均衡LVS DR模式配置
下一篇: Nginx 中 HTTP模块初始化
推荐阅读
-
LVS四层负载均衡器原理和DR模式的搭建
-
keepalived的原理、LVS负载均衡之DR模式+KeepAlived双机热备架构【原理和配置】
-
lvs+keepalive实现双主模式(采用DR),同时实现TCP和UDP检测实现非web端的负载均衡,同时实现跨网段的通讯
-
负载均衡集群 之 LVS (2) DR模式搭建 和 keepalived+lvs
-
LVS+keepalived实现高可用的DR模式负载均衡的搭建过程
-
lvs+keepalive实现双主模式(采用DR),同时实现TCP和UDP检测实现非web端的负载均衡,同时实现跨网段的通讯
-
LVS+keepalived实现高可用的DR模式负载均衡的搭建过程