最近在研究LVS,发现资料中介绍的是如果要用VS-DR模型,至少需要2个公网IP,有文章说用一个IP也可以但是需要给内核打forward_shared 补丁,那么有没有一种更简单的方式实现呢?答案是‘有’,本文就跟大家一起探讨这个话题。


1LVS简介

2LVS十种调度算法

3、一个公网IP实现LVS-DR模型案例


   LVS是基于TCP/UDP的端口来进行调度的,是基于内核的一个实现,比应用层负载均衡实现有更高的效能,但应用层可以识别高层的协议,针对更多的条件进行负载均衡,另外应用层负载均衡器(代理)可以对后端主机进行健康状况的检测等;可以说这两种方式各有千秋,下面浅谈一下LVS的实现方式以及调度算法:

三种常见的实现方式:

Virtual Server viaNAT(VS-NAT):

   用户通过虚拟IP地址(Virtual IPAddress)访问服务时,访问请求的报文会到达负载均衡器,由它进行负载均衡调度,从一组真实服务器选出一个,将报文的目标地址Virtual IPAddress改写成选定服务器的地址,报文的目标端口改写成选定服务器的相应端口,最后将报文发送给选定的服务器。真实服务器的回应报文经过负载均衡器时,将报文的源地址和源端口改为VirtualIP Address和相应的端口,再把报文发给用户。VS/NAT的优点是服务器可以运行任何支持TCP/IP的操作系统,它只需要一个IP地址配置在调度器上,服务器组可以用私有的IP地址。缺点是它的伸缩能力有限,当服务器结点数目升到10时,调度器本身有可能成为系统的新瓶颈,因为在VS/NAT中请求和响应报文都需要通过负载均衡器。


Virtual Server via IPTunneling(VS-TUN):

   在VS/TUN的集群系统中,负载均衡器只将请求调度到不同的后端服务器,后端服务器将应答的数据直接返回给用户。这样,负载均衡器就可以处理大量的请求,它甚至可以调度百台以上的服务器(同等规模的服务器),而它不会成为系统的瓶颈。

VS/TUN技术对服务器有要求,即所有的服务器必须支持“IPTunneling”协议。同时,使用隧道技术,将会增加系统开销,实际生产环境中用的案例不多。


Virtual Server viaDirect Routing(VS-DR):

   跟VS/TUN方法一样,VS/DR调度器只处理客户到服务器端的连接,响应数据可以直接从独立的网络路由返回给客户。极大的减轻了Director的负担,这可以极大地提高LVS集群系统的伸缩性。跟VS/TUN相比,这种方法没有IP隧道的开销,但是要求负载均衡器与实际服务器都有一块网卡连在同一物理网段上,服务器网络设备(或者设备别名)不作ARP响应。  


十种调度算法:

静态调度算法:


1.轮叫调度(Round Robin

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


2.加权轮叫(Weighted Round Robin

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


3.目标地址散列(Destination Hashing

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


4.源地址散列(Source Hashing

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


动态调度算法:


1.最少连接(Least Connections):lc

调度器通过最少连接调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用最小连接调度算法可以较好地均衡负载。Active*256+Inactive,取最小的作为下一个数据包转发的对象。刚开始工作时,安装配置列表中的服务器排列顺序进行安排。


2.加权最少链接(Weighted Least Connections):wlc

在集群系统中的服务器性能差异较大的情况下,调度器采用加权最少链接调度算法优化负载均衡性能,具有较高权值的服务器将承受较大比例的活动连接负载。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。计算方法:(Active*256 + Inactive/ weight  ,也是LVM的默认调度算法;



3.基于局部性的最少链接(Locality-Based Least Connectionslblc

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


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

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


5.最短期望延迟(Shortest Expect Delay):sed

sed是对wlc的改进,在此处,Inactive连接数不参加评估,计算公式(Active+1*256/weight,由此也引入了一个问题,就是RealServer中有一台设备的weight很小,那么这台服务器很多时间都是空闲状态。



6.永不排队(Never Queuenq

针对sed出现的问题进行优化,即便是最不济的服务器在刚开始工作的情况下也要分配任务。


三、案例分析


   当前公司业务处于初始阶段,为考虑以后的扩容问题,服务器集群可能会超过15个节点,受限于LVS-NAT模式集群节点的容量问题,计划采用LVS-DR模式,公司为节约IP地址,只租用了一个IP,为了安全起见,网络入口架设一台防火墙(用iptables实现防火墙功能,& iptables高效的NAT有目共睹)。拓扑设计如下:



思路:防火墙对请求做了DNAT之后,目的IP变成VIPTCP端口还是80,那么数据包返回时虽然是由服务器集群节点返回的,但此时响应包的源IP还是VIP,响应包的源TCP端口也没变,那么数据包回到防火墙时,应该也是可以转换回去的


IP地址分配:

防火墙外网口:202.106.1.1内网口:172.16.1.254

Directoreth0: 172.16.1.1     lo:0(Virtual IP,简称VIP ) : 172.16.1.100

服务器A: eth0:172.16.1.10      lo:0(VIP) :  172.16.1.100

服务器B: eth0:172.16.1.20      lo:0(VIP) 172.16.1.100

首先,客户端发起请求,防火墙对此请求做DNAT映射到DirectorDirector根据配置的服务器列表和算法,假设将此请求转发给服务器集群中B节点,同时Director修改源数据包的目的MAC地址为服务器BMAC地址,没有修改数据包的目的IP,此时仍为VIP,服务器B收到此包,发现目的MAC为自己,就解封装,发现目的IP也是自己lo:0上配置的IP,就对此数据包进行响应(用VIP来响应),有人也许会有疑问,为什么不用出接口的IP来响应呢?这是因为其他设备请求的是VIP,就必须用VIP来响应,不用多问为什么,因为这就是规定。看下图:

其实总的配置还是比较简单的:

防火墙配置:

# IP configuration

[root@NAT ~]# ifconfigeth0 202.106.1.1/30 up

[root@NAT ~]# ifconfigeth1 172.16.1.254/16 up


# DNAT configuration

[root@NAT ~]# iptables-t nat -A PREROUTING -d 202.106.1.1 -p tcp --dport 80 -j SNAT --to172.16.1.100:80


# 开启路由功能:

[root@NAT ~]# vi/etc/sysctl.conf

修改成如下内容

# Controls IP packetforwarding

net.ipv4.ip_forward= 1


Director 配置:


IP配置:

[root@LB ~]# ifconfigeth0 172.16.1.1/16 up

[root@LB ~]# ifconfiglo:0 172.16.1.100/32

安装ipvsadm

[root@LB ~]# yum -yinstall ipvsadm

配置服务类型

ipvsadm -A -t172.16.1.100:80 -s rr

添加服务器节点和设置工作模式

ipvsadm -a -t172.16.1.100:80 -r 172.16.1.20 -g

ipvsadm -a -t172.16.1.100:80 -r 172.16.1.10 -g


附ipvsadm常用命令介绍:

ipvsadm:

1、管理集群服务

          添加:-A -t|u|f service-address [-sscheduler]

                   -t:tcp协议的集群服务

                   -u:udp协议的集群

                   -f:FWM:防火墙标记

          修改:-E

          删除:-D

                    -D -t|u|fservice-address  

    例如:# ipvsadm -A -t 172.16.100.1:80 -s rr


 2、管理集群服务中的RS

       添加:-a -t|u|f service-address -rserver-address[-g|i|m] [-w weight]

                -t|u|fservice-address:事先定义好的某集群服务

                -rserver-address:某RS的地址,在NAT模型中,可以使用IP:PORT事先端口映射

                 [-g|i|m]:LVS类型

                    -g:DR

                    -I:TUN

                    -m:NAT

                 [-wweight]:定义服务器权重

      3、修改:-e

      4、删除:-d -t|u|f service-address -r server-address

      5、查看

              L|l[options]

                     -n:数字格式显示主机地址和端口号

                     --stats:统计信息

                     --rate:速率

                     --timeout:显示tcp、tcpfin和udp会话的超时时间值

                     --daemon

                     --sort:跟协议、地址、端口进行排序,默认为升序

                     -c:显示当前ipvs连接状况

      6、删除所有集群服务:

                  -C:清空ipvs规则

      7、保存规则

                  -S:(用输出重定向进行保存)

                  格式:#ipvsadm -s>/path/to/somefile

      8、载入此前的规则:

                  -R

                   格式:#ipvsadm -R </path/to/somefile



Real Server(服务器集群节点)配置


   在DR模型下,每个服务器节点都要配置VIP,那么当防火墙将包转发过来以后,到底谁来响应呢,那肯定是Director来响应,所以当防火墙请求VIPMAC地址时,请确保是Director来响应,简单的方法有两种:

1、在防火墙上添加静态的arp映射,如:

首先在/etc/hosts文件中定义IP和主机名的映射

172.16.1.100    vip.magedu.com   vip

然后添加静态映射

[root@NAT ~]# arp -svip 00:0C:29:1F:F8:3D

[root@NAT ~]# arp

Address                  HWtype  HWaddress           Flags Mask            Iface

vip.magedu.com           ether   00:0c:29:1f:f8:3d   CM                    eth1

192.168.10.1             ether   00:50:56:c0:00:01   C                     eth2


2、设置服务器节点的内核参数:


echo 1 >/proc/sys/net/ipv4/conf/eth0/arp_ignore

echo 2 >/proc/sys/net/ipv4/conf/eth0/arp_announce

参数介绍:

arp_announce

0  可以在任意接口向外发送所有IP的免费ARP

1  尽量避免发送所在接口之外IP的免费ARP

2  只向外发送所在接口的IP的免费ARP

arp_ignore

0  可以响应所有配置的IP的ARP报文

1  只响应从入接口IP的ARP报文

8        不响应任何ARP请求


3、配置http服务

使用yum install httpd 快速安装一个网站,设置测试页面,进行测试。


本文只是对LVS-DR模型一个简易实现,未过多涉及其他知识点,如有建议,欢迎讨论。