[隐藏]

基于LVS的服务器集群主要由两部分组成,即负载调度器(Load Balancer,简称LB)和真正提供服务的服务器(Real Server,简称RS)。RS对外是不可见的,用户需要通过访问LB来获得服务,所以LB也称为虚拟服务器(Virtual Server),它对外公开的IP称为VIP(Virtual IP)。

LB接收到用户的请求后,会根据设置的转发模式和负载均衡调度算法将请求转发给RS,RS再将结果返回给LB或用户(返回给谁跟转发模式有关)。

LVS的转发模式主要有三种:网络地址转换(NAT,Network Address Translation)、IP隧道(TUN,IP Tunneling)和直接路由(DR,Direct Routing)。

NAT模式

网络地址转换技术应该都不陌生,就是将一个IP地址转换为另一个IP地址的技术。通常当一个内部网络中的主要要访问Internet或被Internet访问时,就需要采用NAT技术,将内部地址(10.0.0.0/255.0.0.0、172.16.0.0/255.240.0.0、192.168.0.0/255.255.0.0)转化为在Internet上可用的外部地址。

下面是LVS采用NAT模式的部署图:

lvs TUN模式

假设一个IP为200.200.200.2的用户来访问我们的虚拟服务器,VIP为200.200.200.1。集群使用的内部IP是10.10.10.0网段。那么请求和响应的过程可以用下图表示:

lvs NAT模式包流动

基本原理介绍过了,下面就开始做实验吧。

按照上面的部署图,我们需要四台机器,LB上需要安装ipvsadm,一般软件源上都有提供。RS上需要安装web服务器,我使用的是apache。软件装好后就可以开始配置了。

首先在客户机上配置IP:

然后配置LB的IP:

也就是LB的eth0网卡与Internet相连,eth1与内网相连。注意,我们需要LB在接收到外网用户的请求后将请求包转发给内网服务器,也就是将eth0接收的包通过eth1发出去,所以LB必须有数据包转发功能,所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的IP将包发往本机另一网卡,该网卡根据路由表继续发送数据包,这通常就是路由器所要实现的功能。默认情况下,Linux系统是禁止数据包转发的。所以我们需要打开这个功能,永久打开的方法是在/etc/sysctl.conf中添加:

net.ipv4.ip_forward=1

临时的方法是执行:

echo “1″ > /proc/sys/net/ipv4/ip_forward

配置RS1的IP:

注意将RS的默认网关设置成LB的IP,使得RS发出的包能够经过LB。

类似的将RS2的IP设置为10.10.10.3

分别在RS1和RS2上建立a.html:

还有一项任务是配置LVS服务。再次登录到LB,新建一个ipvsadm.sh脚本,写入以下内容:

–C    选项的意思是清除内核虚拟服务器表中的所有记录。

-A     在内核的虚拟服务器表中添加一条新的虚拟服务器记录。

-t      说明虚拟服务器提供的是tcp服务

-s      指定使用的调度算法,rr是轮询

-a     在内核虚拟服务器表的一条记录里添加一条新的真实服务器记录

-r      说明真实服务器

-m    指定工作模式为NAT模式

更多选项可以man ipvsadm查看。

赋予可执行权限并执行脚本即可开启服务。

这样整个配置就完成了,可以使用客户机查看效果了!

通过客户机浏览器访问200.200.200.1/a.html,多次刷新,可以看到页面内容也在不断改变:

DR模式

NAT模式中,请求和响应的数据包都需要通过LB,当RS的数目过多时,LB可能成为整个集群的新瓶颈。因为大多数Internet服务都有这样的特点:请求报文较短而响应报文往往包含大量的数据。如果能将请求和响应分开处理,即LB只负责调度请求而响应直接返回给客户,将极大地提高整个集群的吞吐量。

DR模式的部署图

DR模式有几点和NAT不同:

1. 不仅LB上配置了VIP,RS上也都配置了VIP

2. LB和RS都只需要一个真实网卡,LB的VIP配置在eth0:0上,RS的VIP配置在lo:0上

3. LB和RS上真实网卡的IP都需要是公网IP

4. LB不需要开启路由转发功能

5. 响应报文不经过LB

当用户通过VIP访问集群时,LB会收到这个请求,再按照设置的调度算法选择一个RS,并在一个hash表中存储这次连接。然后将请求报文的目的MAC地址改为所选择的RS的MAC并转发给它。RS收到请求后,发现报文的目的IP为VIP,而自己的lo:0上配置了这个IP,RS就处理这个请求并将响应报文直接发送给用户。当该用户再次发送请求时,LB就根据hash表找到对应的RS,并再次将请求转发给它。

下面介绍DR模式的配置,接下来我就只做临时配置而不写到配置文件里了。

分别为LB和RS配置VIP:

LB的VIP配置在eth0:0,RS的VIP配置在lo:0。

VIP的子网掩码都是是四个255。说明这一网段只有它自己,那么它就不会将ARP发送到真实的广播域了,这样就防止了与其它VIP冲突。

为了用户在访问VIP时能将请求发送给LB而不是RS,需要对RS的arp响应做限制:

对RS2做相同的操作。

这么做的原因是,路由器一般是动态学习ARP的,当内网的机器要发送一个到外部的IP包,那么它就会请求路由器的MAC地址,发送一个arp请求,这个arp请求里面包括了自己的IP地址和MAC地址,而linux默认是使用IP的源IP地址作为arp里面 的源IP地址,而不是使用发送设备上面的 ,这样在lvs这样的架构下,所有发送包都是同一个VIP地址,那么arp请求就会包括VIP地址和设备MAC,而路由器收到这个arp请求就会更新自己的arp缓存,这样就会造成VIP被抢夺,所以就会有问题。

 

关于arp_ignore和arp_announce的解释(可以在Linux内核码Documentation/networking/ip-sysctl.txt中找到):

arp_ignore:定义对目标地址为本地IP的ARP询问不同的应答模式0

0 – (默认值):回应任何网络接口上对任何本地IP地址的arp查询请求

1 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求

2 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内

3 -不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应

4-7 -保留未使用

8 -不回应所有(本地地址)的arp查询

 

arp_announce:对网络接口上,本地IP地址的发出ARP回应,作出相应级别的限制:确定不同程度的限制,宣布对来自本地源IP地址发出Arp请求的接口

0 – (默认)在任意网络接口(eth0,eth1,lo)上的任何本地地址

1 -尽量避免不在该网络接口子网段的本地地址做出arp回应。当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用。此时会检查来访IP是否为所有接口上的子网段内ip之一。如果改来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理。

2 -对查询目标使用最适当的本地地址。在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信的本地地址.首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址。 如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送。

 

所以,上面设置的结果是,RS的VIP既不宣告也不回应arp,但宣告并回应真实IP的arp。这也是为什么RS的VIP设置在回环接口上而不是eth0:0上。

修改LB的ipvsadm.sh为:

-g表示使用DR模式。

配置完成。

 

TUN模式

 

IP隧道技术是将一个IP数据报封装成另一个IP数据报的技术,使得被封装的数据报可以被转发到另一个IP地址。

TUN模式与DR模式基本相同。不同的是:

1. TUN模式中,LB和RS必须支持“IP Tunneling”或者“IP Encapsulation”协议

2. LB和RS的VIP配置在tunl0虚拟网卡上

3. LB将请求报文封装成一个新的IP报文,新的IP包的目的IP是某一RS的IP,然后转发给RS,RS收到报文后解封装,取出用户的请求报文,发现目的IP是VIP,而自己的tunl0网卡上配置了这个IP,从而处理请求并将结果直接发送给客户。DR模式中LB修改的是目的MAC

4. LB与真实服务器不必在同一网段,只要路由可达即可。如果不再同一网段,不会存在arp问题

TUN模式的配置方法和DR模式也很类似。感兴趣的看官自己摸索一下吧!

调度策略

我们在上面的实验中使用调度策略的都是rr,即轮叫。现在LVS已实现了10种调度策略(man ipvsadm可以查看)。

1.轮叫调度(Round Robin,rr)

调度器通过“轮叫”调度算法将外部请求按顺序轮流分配到集群中的真实服务器上,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。

2.加权轮叫(Weighted Round Robin,wrr)

调度器通过“加权轮叫”调度算法根据真实服务器的不同处理能力来调度访问请求。这样可以保证处理能力强的服务器能处理更多的访问流量。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。

3.最少链接(Least Connections,lc)

调度器通过“最少连接”调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用“最小连接”调度算法可以较好地均衡负载。

4.加权最少链接(Weighted Least Connections,wlc)

在集群系统中的服务器性能差异较大的情况下,调度器采用“加权最少链接”调度算法优化负载均衡性能,具有较高权值的服务器将承受较大比例的活动连接负载。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。

5.基于局部性的最少链接(Locality-Based Least Connections,lblc)

“基于局部性的最少链接”调度算法是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。该算法根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用“最少链接” 的原则选出一个可用的服务器,将请求发送到该服务器。

6.带复制的基于局部性最少链接(Locality-Based Least Connections with Replication,lblcr)

“带复制的基于局部性最少链接”调度算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。它与LBLC算法的不同之处是它要维护从一个目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。该算法根据请求的目标IP地址找出该目标IP地址对应的服务器组,按“最小连接”原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按“最小连接”原则从这个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。

7.目标地址散列(Destination Hashing,dh)

“目标地址散列”调度算法根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

8.源地址散列(Source Hashing,sh)

“源地址散列”调度算法根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

9.最短的期望的延迟(Shortest Expected Delay Scheduling SED,sed)

基于wlc算法。这个必须举例来说了

ABC三台机器分别权重123,连接数也分别是123。那么如果使用WLC算法的话一个新请求进入时它可能会分给ABC中的任意一个。使用sed算法后会进行这样一个运算

A(1+1)/1

B(1+2)/2

C(1+3)/3

根据运算结果,把连接交给C。

10.最少队列调度(Never Queue Scheduling,nq)

如果有台realserver的连接数=0就直接分配过去,不需要在进行sed运算