当第一次接触LVS,得知是国内的大佬弄出来的东东,还被加入了内核,简直佩服的不要不要的。不过,由于其功能比较简单,配置复杂,其实正真被使用的到不是很多。也许一提到软件的负载均衡,肯定先想到的是Nginx或者haproxy。当然,对于理解LVS的一些概念,各种类型,已经调度方式,对于以后学习应用层的负载均衡技术是有很大帮助的。今天,我们就先来说说LVS的一些概念性的东西。
正文:
首先,我们先以宏观的角度来说说LVS集群的各个类型,多目标DNAT的LVS-nat,直接路由的LVS-dr,此为默认类型,还有基于隧道的LVS-tun。其实基本的类型就以上三种,不过还有一个后面出来的东东LVS-fullnat。我们一个一个的来说~在讲具体LVS类型之前,我们先提几个术语,方便后面的描述,能用到的我会尽量在图中标记出来。整个服务器集群,由一堆提供服务的服务器和调度器组成,服务器是来提供服务器的,调度器使用来决定,当一个客户请求尽量,选择哪个服务器响应的东东。我们把这个调度器称为Virtual Server(VS),Director(调度器),Dispatcher(分发器),Balancer(负载均衡器),把后面的服务器称为Real Server(RS),客户端向调度器发送请求时,客户端的IP即Client IP简称为CIP,接收客户端请求的IP为Virtual Server IP(VIP),连接后端服务器的为Director IP(DIP),服务器端为Real Server IP(RIP)
LVS-nat
咳咳,图有点丑,将就着看把~nat做为网络中很基本的协议,估计是没人不懂把。不懂的道友求请自行学习下~不难!LVS-nat是多目标的DNAT,通过将请求报文中的目标地址和目标端口修改为挑选出来的RS的RIP和PORT实现转发。简单来说就是,用户客户端发送的请求都由VIP接收,然后VS根据调度策略选择某一个RIP。从客户端到调度器的数据包的源IP是CIP,目的IP是VIP,然后DNAT把其目的地址从VIP转换为RIP,所有数据包从DIP发送到RIP是,其源IP为CIP,目的IP为RIP。这样客户端的请求就到达了调度器选择的某一个RS上,然后此RS根据请求,向CIP发送一个响应,如果RIP直接响应CIP,不经过调度器,客户端收到一个源IP不是VIP的数据包,肯定莫名奇妙呀,明明我请求的是VIP,怎么会返回RIP的数据包呢?所以,RS响应客户端请求时,得重新把源地址为RIP的数据转换成VIP。然后客户端就收到响应啦~~~
OK,我们重新来总体描述下。假如现在同时有5个客户端请求发给调度器,然后调度器根据调度策略,把这5个请求送到后面几个服务器上,送的方式就是修改目的IP地址为选择的RIP。然后,各服务器的响应在经过调度器的转换发送给各个客户端。这样就实现了最基本的负载均衡啦~有木有很简单~
在此模式下 ,我们只用把VIP设置为公网IP,把其他的DIP,RIP设置为私有地址,就可以提供服务器并满足负载均衡的需求了。而且,此模式还支持端口映射~因为调度器只是发送一个请求到后端服务器,所以VS必须是linux,比较LVS是linux上的东东,还加到内核了,RS就可以是任何系统了,能提供服务就好。
nat模式有不少优势,但是劣势却是相当明显的,所有的请求,响应都必须经过调度器,可想调度器的负载有多大,当集群越来越大时,调度器就有可能称为整个集群的瓶颈。所以,我们就想,我们能不能只把请求发送给调度器选定的服务器,然后后端服务器直接响应客户端。因为,其实请求的消耗的资源,比起响应消耗的资源简直不要小太多,这样调度器即实现了调度的功能,有减少了负载,妙哉!其实,这种实现方式就是我们下面要讲到的基于直接路由的LVS-dr啦~让我们来一起看看这个有趣又复杂的东东把~
LVS-dr
虽然叫Direct Routing,但是跟我们熟悉的路由不太一样耶~来看看整个结构图把!图丑,见谅~(为了显示方便,我就不打水印了,引用要注明出处哈~我想是没人想看这丑图的!)
普通意义上来讲,用户从客户端到我们的调度器时,已经经过了无数个网络设备了,图上的路由器标识我们局域网的出接口所在的路由器,交换机表示VS和RS所在的局域网,专业点说就是同一个广播域。我们来开始描述下LVS-dr这个东东的结构哈~当客户端的请求经过无数个路由器,交换机到达我们的调度器时,此过程中源IP是客户端的CIP,目的IP是调度器的VIP,到达调度器的内网时,请求报文的源MAC地址为网关的MAC地址,目的MAC地址就是VIP所在的MAC地址。(这个东东必须明晰!不然后面理解有点困难,此处默认大家有基本的网络知识!)此结构中我们的VIP和DIP其实是同一个,然后我们把请求的数据包转发给处在同一网络中的VS选择的一个RS。此时的请求数据包的源IP依然是CIP,目的IP依然是VIP不变,但是目的MAC地址变为RIP所在接口的MAC地址。(必须知道,IP地址是逻辑上的地址,MAC地址才是真正的通信地址,所以我们才可以通过修改MAC地址发送到指定的RS)。RS接收到数据后,假如她能根据请求进行响应,直接发给客户端。这样就响应报文就不用经过调度器。不过,前面我们提到的问题还没解决呀,我们从RIP发出去的数据包,肯定源IP是RIP,客户端依然会觉得莫名奇妙呀!也许你会想,那我们可以给RIP所在的接口加一个VIP地址呀,让它出去的时候源IP是VIP不就行了,嗯。。想法很好,不过还是有问题,RS和VS在同一个网络,同一个网络可是不能有相同地址的。不然,当某个接口发送arp广播,问这个网络中VIP的MAC地址是谁呀,如果有两个接口响应,不是就乱套了吗?当然,这个问题可以有两个解决办法,第一我们可以在出接口的路由器上绑定arp,就把VIP绑定到VS的VIP所在的接口,然后把RIP也设置为VIP。这样问题就解决了~当然,一般来说我们的出接口路由器都在 运营商的机房里我们很难有权利去修改,所以也有第二种方法,我们可以通过arptables禁止RS的VIP去响应和通告arp。这样RS可以不告诉别人我有VIP地址了~完美!