之前我们花了两篇文章的篇幅,具体解说了Nginx的原理、安装和特性组件。请參看《负载均衡层设计方案(2)——Nginx安装》(http://blog.csdn.net/yinwenjie/article/details/46620711)和《架构设计:负载均衡层设计方案(3)——Nginx进阶》(http://blog.csdn.net/yinwenjie/article/details/46742661)两篇文章。尽管不包含Nginx的所有知识(也不可能所有包含)。可是足够读者将Nginx应用到实际的生产中,并进行重要特性的优化,后面有时间我们还会又一次回到Nginx的解说上。从本篇文章開始,我们将開始介绍LVS技术,包含基本概念、简单使用和进阶使用。
1、LVS介绍
请自行Google或者百度。
2、网络协议基础知识
依据官方文档LVS支持三种负载工作方式:NAT方式、TUN方式和DR方式。
为了说明这三种方式的工作原理。我们首先须要了解一下基础的IP/TCP报文(注意,IP报文和TCP报文是两种不同的报文格式)。以及链路层对IP数据的封装方式。
然后我们採用看图说话的方式,以图文结合的方式为您介绍这三种工作方式中对报文或重写或封装的过程。
为了说清楚我们将要解说的基础知识,就要提到OSI7层网络模型。
章文嵩博士及其团队是我的偶像,LVS体系之所以高效是由于其直接对链路层报文、IP报文、TCP报文进行了改动或封装。所以要真正理解LVS的三种工作方式。就不能像网络上的抄袭贴一样转几句不知所以的文字就完了。必须对链路层报文、网络层报文、传输层报文有所了解。
以下我们就进行概述。
为了保证这个系列的博文不发生偏差,我们仅仅解说当中须要用到的属性和含义。假设读者对网络的核心原理有兴趣,能够读读《TCP/IP具体解释,卷1:协议》这本书。
2.1、链路层报文
链路层的数据格式有一个共同特点,都包含目标MAC地址和源MAC地址。以下这个图主要说明了我们最经常使用的Ethernet帧(以太帧)的报文格式:
- 目标MAC地址/源MAC地址:00:00:00:00:00:00——FF:FF:FF:FF:FF:FF这个范围是全球MAC地址的可用范围。
一张物理网卡肯定有一个唯一的MAC地址。
实际上网络层经常使用的IP协议,就是基于MAC地址的。
一个子网范围内某个IP相应的MAC地址是通过ARP查询协议从NAT设备(可能是路由器、交换机或者网络代理设备)上查询得到的。
-
上层协议类型:链路层的报文是为了承载网络层的协议而存在的,所以链路层的数据格式中须要有一个属性说明这个链路层所承载的上层协议是什么类型。
-
IPv4: 0x0800
- ARP:0x0806
- PPPoE:0x8864
- IPV6: 0x86DD
-
封装的上层数据:最多能够有1500个字节。
请记住这个链路层的数据格式,由于讲到LVS-DR方式的时候,主要就是对链路层的数据格式进行改动,而不会对IP数据报文和TCP数据报文进行改动。
2.2、网络层IP报文
-
TCP协议和IP协议是两种不同的协议。相应的。也就是两种不同的描写叙述格式。
-
IP协议是网络层协议,顾名思义,就是用来描写叙述整个网络构成情况的;TCP协议是通讯层协议,是用来表示两个或多个网络上的点怎样进行通信和当前通信状态的。
-
这两种协议有非常多共同特点,比如这两种协议都分为“头部”和“数据部”。针对IP协议来说,TCP协议的描写叙述就存放在其“数据部”。
我们首先来看看IP协议是怎么描写叙述的:
好吧。图我是直接从百度百科直接粘过来的,由于要我来画,结构也是这样^_^。当中有几个重要的我们后面要使用的属性,要给大家说一下:
- header.version:IP协议的版本号号。你猜对了就是IPV4还是IPV6。4表示IPV4版本号,6表示IPV6。
你要问我什么是IPV4,还是IPV6:192.168.220.141,这就是IPV4的格式;FE80:0000:0000:0000:AAAA:0000:00C2:0002,这就是IPV6的格式。
-
header.Total Length:总长度。这个总长度是IP头和IP数据两个区域的总长度。主要还是用于生成头验证码和为了操作系统处理方便。
-
header.IP Flags:这个位置有3位000,但实际仅仅有后两位才有值010,这个就是“D”位=1,这个时候表示由于要传输的整个数据不大,所以这个IP数据报的数据部分已经描写叙述了整个数据描写叙述,不须要进行IP数据报的分片;”D”为=0,表示要传输的整个数据比較大。所以IP数据报进行了拆分。这个时候就要用到最后一位了:最后一位“M”中“1”表示还有兴许分片;0表示这个数据报就是IP分片的最后一个数据片了。
-
header.Protocol:IP协议是网络层协议。在网络层以上是传输层协议。TCP、UDP、ICMP和IGMP是传输层协议。这个位置的8位说明IP协议数据部分携带的是哪种上层协议。
-
header.Source Address:这个当然就是IP数据报的来源地址咯。
-
header. Destination Address:这个当然就是IP数据报的目标地址咯。
-
header.checksum:首部校验值。
这个值校验IP数据报首部的传输完整性(注意校验不包含IP数据报的数据部分)。
这就意味着NAT设备重写这个数据报的来源或者目标IP后。校验值要又一次进行计算。
Source Address、Destination Address、Checksum是各种NAT设备基本的改写属性。而且非常多时候NAT设备仅仅改写这三个值就能够实现IP数据报的转发(当然TCP报文中的port也会被改写,以便在port映射的情况下进行port转换)。
2.3、传输层TCP报文
上文已经说过。TCP的报文信息是装在到IP报文的数据部分的,当成网络上进行传输的数据从Srouce Address传到Destination Address中。以下是TCP报文的信息:
-
头.源port号:TCP信息来源的port号。
-
头.目的port号:TCP信息数据的目标port。
-
头.状态位(URG/ACK/PSH/RST/SYN/FIN):假设您已经看到我之前写的《标准Web系统的架构分层》(http://blog.csdn.net/yinwenjie/article/details/46480485)这边文章的第3.2小节,那么您对ACK、SYN、FIN这三个标记肯定不陌生,由于TCP的三次握手和连接中断就要用到这三个标记。须要注意SYN SEQ和ACK SEQ就是TCP数据报的确认号;另外解释一下PSH和RST两个状态标记。
应用层的TCP数据报有一个缓存区。也就是说多个正确的TCP数据报会首先放到这个缓存区,达到一定条件后,再推送给上层的应用层协议。比如http。PSH为1的时候。表示不须要再等到兴许的TCP数据报文了。直接将眼下接收方缓存中的tcp数据报进行数据段组合后推送给上层协议,而且清空缓存区;RST表示复位,您能够理解成放弃当前缓存区的所有未发送给上层协议的TCP数据报文。一般这样的情况都是TCP报文传输出现了问题。
- 头.TCP校验和:TCP报文的校验和比起IP头校验要略微复杂点。TCP校验的输入包含三部分:TCP伪首部、TCP首部长度和TCP数据部长度。
TCP伪首部是一个虚拟概念。它包含承载TCP数据报文的IP报文的一部分,和TCP首部的一部分数据(源IP、目标IP、IP报文中的protocoly、以及TCP报文的报文头长度和TCP报文的数据长度)。
从上面的描写叙述能够看出。一旦IP报文中的源IP和目标IP发生改变了,TCP报文校验信息就会改变。
3、LVS的三种工作方式
3.1、LVS-NAT工作方式
NAT方式是一种由LVS Master服务节点收到数据报,然后转给下层的Real Server节点,当Real Server处理完毕后回发给LVS Master节点然后又由LVS Master节点转发出去的工作方式。LVS的管理程序IPVSADMIN负责绑定转发规则,并完毕IP数据报文和TCP数据报文中属性的重写。
请用几分钟时间细致看看下图(为了简单。图里面仅仅画了一个Real Server。假设看不清楚。可点击右键“查看原图”):
- 1、在正式的机房环境中,一般有两种方式为一个机器分配外网地址:在核心交换机上直接绑定外网地址到主机网卡的,这样使用ifconfig命令看到的IP地址为外网地址;在核心交换机上使用映射规则。将一个外网地址映射到内网地址。这样使用ifconfig命令看到的IP地址为内网地址。上图中我们採用的是后一种映射规则。
假设使用前一种外网IP的分配规则。也不会影响LVS NAT的工作方式。由于这个IP被限制在LVS NAT工作以外。仅仅只是eth1的IP从192.168.100.10换成100.64.92.199而已。
- 2、我们用中文描写叙述一下转换规则:凡是发送到“192.168.100.10:80”的数据报,目标地址所有改写为“192.168.220.121:8080”,所以来自于100.64.92.199:80的报文被改写了。被改写的属性包含:IP.header.destinationIP、IP.header.checksum、TCP.header.sourcePort、TCP.header.targetPort、TCP.header.checksum。
注意IP报文的Source IP不会发生变化。还是“互联网某个IP”。
-
3、这个包终于被送到了192.168.220.121的8080port进行处理。并由下层的Real Server生成了返回的数据报(至于这个Real Server是不是“真正的Real Server”,LVS不会关心)。你要问它是怎么被发送过去的。请參考ARP查询协议。
-
4、注意:由于LVSserver和Real Server(可能有多个),组成了一个封闭的局域网。除了LVS节点以外。这个子网的不论什么节点都是无法訪问外网的。
所以要求192.168.220.121这个Real Server直接把数据报给“互联网某个IP”这个外网地址,显然是不行的,由于在局域网中根本就找不到这个IP。Real Server仅仅能将数据报返给网关,再由网关去寻找这个外网地址。整个server中仅仅有LVS节点能够找到这个外网地址,这就是为什么在LVS-NAT工作模式下,所有的Real Server节点必须设置自己的Gateway为LVS节点的原因。
- 5、收到来源于“192.168.220.121:8080”的数据报文后,IPVS又要进行数据报文的重写了。
重写规则是:凡是来源于“192.168.220.121:8080”的数据报。源地址所有改写为“192.168.100.10:80”。
于是数据报文的Source IP、Source Port被改写成“192.168.100.10:80”。在外层的核心交换机(或者是机房以外的请求方)看来,LVS接受了数据报,并进行了处理,返回了结果。它并不知道LVS节点的下层还有什么。
LVS-NAT的长处在于:
- 配置管理简单。
LVS-NAT的工作方式是LVS三种工作模式中最easy理解、最easy配置、最easy管理的工作模式。
- 节省外网IP资源。一般机房分配给使用者的IP数量是有限的。特别是您购买的机架的数量不多时。
LVS-NAT工作方式将您的系统架构封装在局域网中。仅仅须要LVS有一个外网地址或外网地址映射就能够实现訪问了。
-
系统架构相对封闭。在内网环境下我们对防火墙的设置要求不会非常高,也相对easy进行物理server的运维。您能够设置来源于外网的请求须要进行防火墙过滤,而对内网请求开放訪问。
-
另外改写后转给Real Server的数据报文,Real Server并不会关心它的真实性,仅仅要TCP校验和IP校验都能通过,Real Server就能够进行处理。所以LVS-NAT工作模式下Real Server能够是不论什么操作系统,仅仅要它支持TCP/IP协议就可以。
-
当然作为Linux系统忠实拥护者。我并不建议使用Windowserver。但假设您的Real Server是.Net系统,又有业务场景须要用到LVS,那么LVS-NAT可能是一个不错的选择。
LVS-NAT的缺点是由于这样的转发模式本身所造成的:
-
转发点就是瓶颈点。您能够想象100台Real Server将处理结果所有转到一个LVS进行发送是一个怎么样的场景。其实,LVS-NAT的极限负载是达不到100台Real Server的。
3.2、LVS-DR工作方式
LVS的DR工作模式,是眼下生产环境中最经常使用的一种工作模式。网上的资料也是最多的。有的文章对DR工作模式的解说还是比較透彻的。这里我们通过图文的方式再向您介绍一下DR的工作模式(相同,假设看不清楚,请右键“查看原图”):
上图反映了DR模式的整个工作过程,相同为了简单起见,这里的Real Server也仅仅画了一个。假设是多个Real Server的话。LVS会通过调度算法来决定发往哪台Real Server。
LVS-DR工作模式的几个关键点在于:
-
被Real Server处理后形成的响应报文,不再回发到LVS节点。而是直接路由给中心交换机然后发送出去。省去了LVS-NAT方式中的LVS回发过程。
-
LVS节点仅仅会改写链路层的报文封装,对网络层和传输层报文是不进行改写的。
-
有网帖说DR工作模式。不能跨子网,也就是说LVS节点和各个Real Server节点必须处于同一个网段中。这是为什么呢?事实又真的是这样吗?非常多网络帖子没有回答这个问题,这篇文章立即回答一下(实际上章文嵩先生已经回答过这个问题)。
-
使用DR模式时。须要Real Server设置LVS上的VIP为自己的一个回环IP。不然包会被丢弃。这又是为什么呢?非常多网贴相同没有回答这个问题。好吧,我们立即回答一下。
先来说一说上图的工作原理:
- 1、相同的。我们为了演示整个生产环境中,从机房中心交换机收到一个数据报文后開始解说。中心交换机相同採取的IP映射方式。
可是与LVS-NAT方式不一样,Real Server在机房的中心交换机上也须要绑定一个外网映射。这样保证Real Server回发的响应报文能够被发送到外网。
- 2、LVS节点接收到请求报文后,会改写报文的数据链路层格式。
将Target Mac改写成Real Server的Mac,可是网络层和传输层报文不会改写,然后又一次回发给交换机。
这里就涉及一个问题。如今target Mac和Destination IP的相应关系的错误的。这个数据报文到了交换机后。由于这样的错位的关系。是不能进行三层交换的,仅仅能进行二层交换(一旦进行IP交换,数据报文的验证就会出错,被丢弃)。所以LVS-DR方式要求Real Server和LVS节点必须在同一个局域网内,或者这样说更确切:LVS节点须要找到一个二层链路,将改写了Mac地址的报文发送给Real Server,而不能进行三层交换的校验。这样来看。实际上LVS节点和Real Server界面不一定要在同一个子网,您用一个独立网卡独立组网,传送报文也是可行的。
- 3、通过二层交换,数据被发送到Real Server节点。
那么Real Server节点怎么来推断这个包的正确性呢?首先当然是传输层TCP/IP报文校验没有问题。LVS-NAT没有改写TCP/IP,当然校验就没有问题(除非报文本身就存在问题)。然后是链路层的MAC地址能够被识别。这时就是回环IP的功劳了。
对于Real Server节点来说,192.168.100.10这个VIP就是自己的回环IP,绑定的MAC也就是被LVS替换后的target mac。那么Real Server会觉得这个包是在本机执行的某一个应用程序通过回环IP发给自己的,所以这个包不能被丢弃,必须处理。
- 4、被处理后的生成的响应报文,被直接发送给网管。这个就没有太多的解释的了,仅仅要保证Real server的默认路由设置成到核心交换机的192.168.100.1就OK了。另外,须要说明的是。由于LVS-DR模式并没有更改原有的IP报文和TCP报文,所以LVS-DR模式本身是不支持port映射的。实际上在日常使用实践中,我们一般使用Nginx做port映射,由于: 灵.活.。
LVS-DR工作模式的长处在于:
-
攻克了LVS-NAT工作模式中的转发瓶颈问题。能够支撑规模更大的负载均衡场景。
-
比較耗费网外IP资源。机房的外网IP资源都是有限的,假设在正式生产环境中确实存在这个问题,能够採用LVS-NAT和LVS-DR混合使用的方式来缓解。
LVS-DR当然也有缺点:
-
配置工作较LVS-NAT方式略微麻烦一点,您至少须要了解LVS-DR模式的基本工作方式才干更好的指导自己进行LVS-DR模式的配置和执行过程中问题的解决。
-
由于LVS-DR模式的报文改写规则,导致LVS节点和Real Server节点必须在一个网段。由于二层交换是没法跨子网的。
可是这个问题针对大多数系统架构方案来说,实际上并没有本质限制。
3.3、LVS-TUN工作方式
非常多网络上的文章都为读者介绍DR和TUN的工作方式相似。要么就是直接解说DR模式和TUN模式的安装配置方式,然后总结两种模式相似。
那为什么有了DR模式后还须要TUN模式呢?为什么ipvsadmin针对两种模式的配置參数不一样呢?
实际上LVS-DR模式和LVS-TUN模式的工作原理全然不一样。工作场景全然不一样。
DR基于数据报文重写,TUN模式基于IP隧道,后者是对数据报文的又一次封装。以下我们就来解说一下LVS-TUN模式的工作原理。
首先要介绍一个概念IPIP隧道。
将一个完整的IP报文封装成还有一个新的IP报文的数据部分,并通过路由器传送到指定的地点。
在这个过程中路由器并不在意被封装的原始协议的内容。到达目的地点后,由目的地方依靠自己的计算能力和对IPIP隧道协议的支持,打开封装协议,取得原始协议。例如以下图:
能够说隧道协议就是为了解决跨子网传输准备的,在生产环境中由于业务须要、技术须要或者安全须要。可能使用交换机进行VLAN隔离(即形成若干个虚拟的独立的局域网)。我们可能须要LVS节点在局域网A。而须要进行负载的多台Mysql读server可能在局域网B中。这个时候,我们就要配置LVS的隧道方式。
LVS-TUN模式例如以下图所看到的(注意,目标节点要能够解开隧道协议。好消息是Linux支持IPIP隧道协议):
上图中的线长处多,您仅仅须要关注关心“有箭头”的虚线就能够了。
-
1、一旦LVS节点发现来目标为192.168.100.10VIP的请求。就会使用IPIP隧道协议对这个请求报文进行封装。而不是像LVS-DR模式重写数据报文的MAC信息。假设配置了多个Real Server,那么LVS会使用设置的调度算法确定一个Real Server(这里为了简单,就仅仅画了一个Real Server节点)。
-
2、又一次封装后的IPIP隧道协议报文会又一次被回发到路由器,路由器(或三层交换机)会依据设置的LVAN映射情况,找到目标server,并将这个IPIP隧道报文发送过去。
-
3、Real Server收到这个IPIP隧道报文后。会将这个报文进行解包。这里注意一下,普通情况下IPIP隧道报文会进行分片,就如同IP报文分片一样。仅仅是为了解说方便,我们假定这个报文不须要分片。解压后得到的数据报文就是原来发送给VIP的请求报文。
-
4、Real Server设置的回环IP。让Real Server觉得原始的请求报文是从自己本地的某个应用程序发出的。完毕原始报文的校验后,它会对这个报文进行处理。剩下的过程就和LVS-DR相同了,这里就不再进行复述了。
能够说LVS-TUN方式基本上具有LVS-DR的长处。在此基础上又支持跨子网间穿透。
这样的敷在方案能够给我们架构师足够的系统设计场景。
4、LVS调度方式
在本文第3节中。为了集中介绍LVS的三种工作模式,我们在三幅图中都为LVS画了一个Real Server。
但实际应用中,一般都是多个Real Server。LVS使用多种调度算法来决定“当前的数据报文”由哪个Real Server进行处理。在我的上篇文章《架构设计:负载均衡层设计方案(2)——Nginx安装》(http://blog.csdn.net/yinwenjie/article/details/46620711)中,已经花了较多的篇幅介绍了Nginx中的调度方式,并明白说明了这些调度方式是**万变不离其宗的**。
文章中包含了Hash算法,而且说明了不论什么属性都能够做Hash,包含IP、username等。还介绍了轮询和加权轮询。加权轮询也能够依据各种属性作为权值,比如节点的CPU使用情况、内存使用情况、或者管理员自己设置的一个固定权值。
LVS的调度也是这样的。
-
利用一致性Hash算法完毕调度
-
目标地址Hash(DH):调度算法依据请求的目标IP地址。作为散列键(Hash Key)从静态分配的散列表找出相应的server,若该server是可用的且未超载。将请求发送到该server,否则返回空。
- 原地址Hash(SH):依据请求的源IP地址。作为散列键(Hash Key)从静态分配的散列表找出相应的server。若该server是可用的且未超载,将请求发送到该server。否则返回空。
-
轮询调度
-
最简轮询(RR):调度算法将外部请求按顺序轮流分配到集群中的真实server上,它均等地对待每一台server,而无论server上实际的连接数和系统负载。
-
最少连接轮询(LC):请注意“最少连接轮询”和“最少连接加权轮询”两种调度算法的差别。调度器通过“最少连接”调度算法动态地将网络请求调度到已建立的链接数最少的server上。注意请求肯定会被分配到这台眼下连接数最少的Real Server上面。不会考虑几率问题
-
-
加权轮询调度:
-
性能加权轮询(WRR):调度算法依据真实server的不同处理能力来调度訪问请求。这样能够保证处理能力强的server能处理很多其它的訪问流量。调度器能够自己主动问询真实server的负载情况,并动态地调整其权值。
- 最少连接数的加权轮询(WLC):具有较高权值的server将承受较大比例的活动连接负载。
调度器能够自己主动问询真实server的负载情况,并动态地调整其权值。注意,是依照一个比例,有较高的分配几率。而不是LC一样“肯定分配”。
在LVS官方中文资料中。提到了更为完整的调度算法。能够进行參考(http://zh.linuxvirtualserver.org/node/2903)。**但一定记住各种调度算法肯定是逃不开哈希一致性、轮询、加权轮询这大思路的**。
5、后文介绍
这篇文章我们的重点是说明LVS的工作原理,并具体介绍了LVS三种工作模式的工作过程、优缺点、应用场景。仅仅要您理解了原理。那么下一篇介绍的LVS的安装和配置就是小菜一碟。我们在下一篇文章中,将介绍LVS三种工作模式的安装和配置方式。之后我们介绍LVS + Keepalived的安装和配置方式。
有了这个知识基础。我们将回到Nginx,介绍LVS + Keepalived + Nginx的安装和配置方式。