背景:近期准备对之前所接触及市面上常见的负载均衡(LB)及高可用(HA)软件及配置做一个简单的总结,首先就从LVS开始。

一、LVS简介

LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件之一。它的官方站点是www.linuxvirtualserver.org。现在LVS已经是 Linux标准内核的一部分,在Linux2.4内核以前,使用LVS时必须要重新编译内核以支持LVS功能模块,但是从Linux2.4内核以后,已经完全内置了LVS的各个功能模块,无需给内核打任何补丁,可以直接使用LVS提供的各种功能。

利用LVS技术实现高可伸缩的、高可用的网络服务,例如WWW服务、Cache服务、DNS服务、FTP服务、MAIL服务、视频/音频点播服务等等。LVS就是软件版的廉价的F5、A10 。

二、LVS体系架构

lvs
lvs

架构图比较容易理解,其中LVS软件就安装在Director server服务器上 ---现网应用中,一般LVS应用主机不会只有单台,因为有单点故障,一般会至少两台,再配合keepalive等软件实现高可用性。对于LVS来说,对应用层的real server的操作系统和软件类型没有要求。如果后面对应的两台real server,可以有一台是windows IIS,另一台是linux apache(httpd) 。

为了应用不同的场景,LVS有DR、NAT、TUN三种模式。在进行进一步的说明前,先理解几个服务及专有名词。

  • Director:负责调度集群的主机;也简称调度器、分发器
  • VIP:Virtual IP 向外提供服务的IP;通常此IP绑定域名
  • DIP:与内部主机RIP通信的IP,在Director主机上
  • RIP:RealServer IP;内部真正提供服务的主机
  • CIP:客户端IP

1、LVS-NAT工作模式

NAT模式需要注意的是,配置的时候realserver服务器的主机IP配置的网关必须为Director server 的IP地址。不然不能正常回包。

lvs-nat
lvs-nat

NAT模型其实就是通过网络地址转换来实现负载均衡的,它的工作方式几乎跟DNAT一模一样的,目前的DNAT只能转发到一个目标地址,早期的DNAT是可以将请求转发到多个目标的,在LVS出现之后就将此功能从DNAT种去掉了,下面来说说NAT模型的工作方式或者说NAT模型是怎么实现负载均衡的,根据上图,

  • 用户请求VIP(也可以说是CIP请求VIP);
  • Director Server 收到用户的请求后,发现源地址为CIP请求的目标地址为VIP,那么Director Server会认为用户请求的是一个集群服务,那么Director Server 会根据此前设定好的调度算法将用户请求负载给某台Real Server ;假如说此时Director Server 根据调度算法的结果会将请求分摊到RealServer1上去,那么Director Server 会将用户的请求报文中的目标地址,从原来的VIP改为RealServer1的IP,然后再转发给RealServer1;
  • 此时RealServer1收到一个源地址为CIP目标地址为自己的请求,那么RealServer1处理好请求后会将一个源地址为自己目标地址为CIP的数据包通过Director Server 发出去;
  • 当Driector Server收到一个源地址为RealServer1 的IP 目标地址为CIP的数据包,此时Driector Server 会将源地址修改为VIP,然后再将数据包发送给用户。

LVS-NAT的性能瓶颈:在LVS/NAT的集群系统中,请求和响应的数据报文都需要通过负载调度器(Director),当真实服务器(RealServer)的数目在10台和20台之间时,负载调度器(Director)将成为整个集群系统的新瓶颈。大多数Internet服务都有这样的特点:请求报文较短而响应报文往往包含大量的数据。如果能将请求和响应分开处理,即在负载调度器(Director)中只负责调度请求而响应直接(RealServer)返回给客户,将极大地提高整个集群系统的吞吐量。

2、LVS-DR工作模式

DR模式是最简单,最高效的一种架构,不过要求后端的realserver一定要和同一网段内 。假如director server主机配置有公网IP,则real server 也有有公网IP ;而NAT方式不需要,只需要director server主机上额外配置一个内网地址,外网客户请求公网地址时,可以通过NAT转换,将请求发送到内网去。

lvs-dr
lvs-dr

  • 首先用户用CIP请求VIP;
  • 根据上图可以看到,不管是Director Server还是Real Server上都需要配置VIP,那么当用户请求到达我们的集群网络的前端路由器的时候,请求数据包的源地址为CIP目标地址为VIP,此时路由器会发广播问谁是VIP,那么我们集群中所有的节点都配置有VIP,此时谁先响应路由器那么路由器就会将用户请求发给谁,这样一来我们的集群系统是不是没有意义了,那我们可以在网关路由器上配置静态路由指定VIP就是Director Server,或者使用一种机制不让Real Server 接收来自网络中的ARP地址解析请求,这样一来用户的请求数据包都会经过Director Servre;
  • 当Director Server收到用户的请求后根据此前设定好的调度算法结果来确定将请求负载到某台Real Server上去,假如说此时根据调度算法的结果,会将请求负载到Real Server 1上面去,此时Director Server 会将数据帧中的目标MAC地址修改为Real Server1的MAC地址,然后再将数据帧发送出去;
  • 当Real Server1 收到一个源地址为CIP目标地址为VIP的数据包时,Real Server1发现目标地址为VIP,而VIP是自己,于是接受数据包并给予处理,当Real Server1处理完请求后,会将一个源地址为VIP目标地址为CIP的数据包发出去,此时的响应请求就不会再经过Director Server了,而是直接响应给用户。

DR 配置处理有三种方式:

第一种方式: 在路由器上明显说明vip对应的地址一定是Director上的MAC,只要绑定,以后再跟vip通信也不用再请求了,这个绑定是静态的,所以它也不会失效,也不会再次发起请求,但是有个前提,我们的路由设备必须有操作权限能够绑定MAC地址,万一这个路由器是运行商操作的,我们没法操作怎么办?第一种方式固然很简便,但未必可行。

第二种方式: 在给别主机上(例如:红帽)它们引进的有一种程序arptables,它有点类似于iptables,它肯定是基于arp或基于MAC做访问控制的,很显然我们只需要在每一个real server上定义arptables规则,如果用户arp广播请求的目标地址是本机的vip则不予相应,或者说相应的报文不让出去,很显然网关(gateway)是接受不到的,也就是director相应的报文才能到达gateway,这个也行。第二种方式我们可以基于arptables。

第三种方式: 在相对较新的版本中新增了两个内核参数(kernelparameter),第一个是arp_ignore定义接受到ARP请求时的相应级别;第二个是arp_announce定义将自己地址向外通告是的通告级别。【提示:很显然我们现在的系统一般在内核中都是支持这些参数的,我们用参数的方式进行调整更具有朴实性,它还不依赖于额外的条件,像arptables,也不依赖外在路由配置的设置,反而通常我们使用的是第三种配置】

arp_ignore:定义接受到ARP请求时的相应级别

0:只要本地配置的有相应地址,就给予响应。
1:仅在请求的目标地址配置请求到达的接口上的时候,才给予响应
2:只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内
3:不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应
4-7:保留未使用
8:不回应所有(本地地址)的arp查询

arp_ignore:设置为1,当别人的arp请求过来的时候,如果接收的设备上面没有这个ip,就不响应,默认是0,只要这台机器上面任何一个设备上面有这个ip,就响应arp请求,并发送MAC地址应答。

arp_announce:定义将自己地址向外通告是的通告级别

0: 将本地任何接口上的任何地址向外通告
1:试图仅想目标网络通告与其网络匹配的地址
2:仅向与本地借口上地址匹配的网络进行通告

3、LVS-TUN工作模式

lvs tun
lvs tun

TUN的工作机制跟DR一样,只不过在转发的时候,它需要重新包装IP报文。这里的real server离得都比较远。用户请求以后,到director上的VIP上,它跟DR模型一样,每个realserver上既有RIP又有VIP,Director就挑选一个real server进行响应,但是director和real server并不在同一个网络上,这时候就用到隧道了,director进行转发的时候,一定要记得CIP和VIP不能动。我们转发是这样的,让它的CIP和VIP不动,在它上面再加一个IP首部,再加的IP首部源地址是DIP,目标地址的RIP的IP地址。收到报文的RIP,拆掉报文以后发现了里面还有一个封装,它就知道了,这就是隧道。

其实数据转发原理和DR是一样的,只不达DR多用于同一局域网环境中,而TUN多用于跨机房、跨网络环境中。

优点:负载均衡器只负责将请求包分发给物理服务器,而物理服务器将应答包直接发给用户。所以,负载均衡器能处理很巨大的请求量,这种方式,一台负载均衡能为超过100台的物理服务器服务,负载均衡器不再是系统的瓶颈。使用VS-TUN方式,如果你的负载均衡器拥有100M的全双工网卡的话,就能使得整个Virtual Server能达到1G的吞吐量。

不足:但是,这种方式需要所有的服务器支持”IP Tunneling”(IP Encapsulation)协议。

4、三种架构之间的对比

LVS三种模式的特点:

模式 VS/NAT VS/TUN VS/DR
服务器操作系统 任意 支持隧道 多数(支持Non-arp)
服务器网络 私有网络 局域网/广域网 局域网
服务器数目(100M网络) 10-20 100 多(100)
服务器网关 负载均衡器 自己的路由 自己的路由
效率 一般 最高

三、LVS调度算法

lvs有10种调度算法,主要分为两在类:静态调度、动态调度

1.Fixed Scheduling Method 静态调度方法

(1).RR (Round Robin) 轮询
(2).WRR(Weighted Round Robin) 加权轮询
(3).DH (Destination Hashing) 目标地址hash
(4).SH (Source Hashing) 源地址hash

2.Dynamic Scheduling Method 动态调度方法

(1).LC (Least Connections) 最少连接
(2).WLC (Weighted Least Connections) 加权最少连接
(3).SED (Shortest Expected Delay) 最少期望延迟
(4).NQ (Never Queue) 从不排队调度方法
(5).LBLC (Locality-Based Least Connections) 基于本地的最少连接
(6).LBLCR (Locality-Based Least Connections with Replication) 带复制的基于本地的最少连接

具体详细的实现方法,可以查看http://kb.linuxvirtualserver.org/wiki/IPVS

四、其他

当前版本的LINUX系统内核默认都支持LVS,可以通过以下命令进行验证:

 1[root@361way ~]# grep -i 'ip_vs'  /boot/config-`uname -r`
 2CONFIG_IP_VS=m
 3CONFIG_IP_VS_IPV6=y
 4# CONFIG_IP_VS_DEBUG is not set CONFIG_IP_VS_TAB_BITS=12
 5CONFIG_IP_VS_PROTO_TCP=y
 6CONFIG_IP_VS_PROTO_UDP=y
 7CONFIG_IP_VS_PROTO_AH_ESP=y
 8CONFIG_IP_VS_PROTO_ESP=y
 9CONFIG_IP_VS_PROTO_AH=y
10CONFIG_IP_VS_PROTO_SCTP=y
11CONFIG_IP_VS_RR=m
12CONFIG_IP_VS_WRR=m
13CONFIG_IP_VS_LC=m
14CONFIG_IP_VS_WLC=m
15CONFIG_IP_VS_LBLC=m
16CONFIG_IP_VS_LBLCR=m
17CONFIG_IP_VS_DH=m
18CONFIG_IP_VS_SH=m
19CONFIG_IP_VS_SED=m
20CONFIG_IP_VS_NQ=m
21CONFIG_IP_VS_FTP=m
22CONFIG_IP_VS_PE_SIP=m

LVS 本身来说只能实现四层的负载均衡,不过通过官方提供的KTCPVS也可以实现简单的七层负载均衡,具体可以参看官方页面:http://www.linuxvirtualserver.org/software/ktcpvs/ktcpvs.htmlhttp://kb.linuxvirtualserver.org/wiki/KTCPVS_HTTP。LVS本身虽然廉价、稳定、高效,但于商业的硬件负载均衡器相比有一些缺点,比如线性扩展不方便、缺少synflood、DDOS等防御模块和策略。这里也可以参看下taobao内部使用的一个ppt