LVS基础介绍

        LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个开源的软件,可以基于软件的方法实现LINUX平台下的负载均衡,由章文嵩博士于1998年5月研发,是中国国内最早出现的自由软件项目之一。

        LVS集群采用IP负载均衡技术和基于内容请求分发技术。调度器具有很好的吞吐率,将请求均衡地转移到不同的服务器上执行,且调度器自动屏蔽掉服务器的故障,从而将一组服务器构成一个高性能的、高可用的虚拟服务器。整个服务器集群的结构对客户是透明的,而且无需修改客户端和服务器端的程序。为此,在设计时需要考虑系统的透明性、可伸缩性、高可用性和易管理性。

        LVS由两部分组成,分别是

ipvs:工作于内核空间的input或prerouting链

ipvsadm:在ipvs上写规则的工具,用于在ipvs上定义集群服务及该集群服务对应的后端可用主机;

二者结合使LVS可以根据指定的调度方法(算法)作出调度决策

        在正式介绍lvs前,我们要先对其使用的术语有一个基本的了解。

Host

Director:调度器

Real ServerRS,后端提供服务的主机

IP

ClientCIP

Director Virtual IPVIP

Director IPDIP

Real IPRIP


                session会话保持                   

         Session Sticky:会话绑定

    实现方法:会话绑定,假设后端有3台RS,某客户端第一次访问时被调度到RS1,则以        后所有该客户端的访问全都调度到RS1,由此保持了该客户端的会话;

    两种实现方法:基于IP绑定(粗糙),基于cookie绑定;

    缺陷:一旦RS1宕机,客户端将无法得到响应,或被重新调度到其他RS时,会话丢失;

         

         Session ReplicationCluster:会话复制集群

    实现方法:将后端的RS构建成多播集群,某客户端第一次访问时被调度到RS1,其保        存在RS1上的会话会通过多播的方式在集群中的所有RS上各复制一份,从而达到客户        端下次访问时无论被调度到哪个RS,其会话均被保持;

    缺陷:当集群中的RS数量过多时,每个RS均需保存大量的session,且整个服务器中        充斥着大量的会话复制广播,无意义的消耗资源,所以此种方式仅适用于集群中有较        小规模的RS;

         

         Session Server:会话服务器

    实现方法:会话不再存储于RS,而是在RS后端单独建立一个共享存储服务器专门用于        存储session;

    缺陷:共享存储服务器成为整个系统的瓶颈和SPOF(单点故障),所以需要构建分布        式和高可用

                   

           

        LVS有四种类型,分别是lvs-nat、lvs-dr、lvs-tun和lvs-fullnat,下面我们将对其一一进行介绍。

                lvs-nat 

类似iptablesDNAT,但支持多目标转发

通过将请求报文的目标地址修改为根据调度算法所挑选出的某RSRIP来转发

 

架构特性

(1)RS应该使用私有地址,即RIP应该为私有地址;各RS网关必须指向DIP

(2)请求和响应报文都经由Director转发,所以高负载场景中,Director容易成为系统瓶颈;

(3)支持端口映射;

(4)RS支持使用任意类型的OS

(5)RSRIP必须与DirectorDIP处于同一网段;


拓扑图

lvs基础介绍及实验演示_调度器

            

                lvs-dr

直接路由

Director在实现转发时不修改请求报文的IP首部,而是通过直接封装帧首部(MAC首部)完成转发(源MACDirectorMAC,目标MAC为算法选定的RSMAC);

 

架构特性

(1)RS要直接响应Client,因此各RS均需配置VIP;但仅允许Director上的VIP能够与本地末梢路由直接通信;

解决方案

静态绑定:在前端路由直接将VIP对应的目标MAC静态配置为DirectorMAC地址;

arptables:在各RS上,通过arptables规则拒绝响应对VIPARP广播请求;

内核参数:在RS上修改内核参数,并结合地址的配置方式实现拒绝响应;

 

(2)RSRIP可以使用私有地址和公网地址,使用公网地址时可通过互联网上的主机直接对此RS进行管理操作;

(3)请求报文必须经由Director调度,而响应报文必须不能经由Director

(4)RIP必须与DIP在同一物理网络中;

(5)不支持端口映射;

(6)RS支持使用大多数的OS

(7)RS的网关一定不能指向Director


拓扑图

lvs基础介绍及实验演示_调度器_02

                        

(1)客户端的请求报文到达本地路由-->ARP地址解析(本地间通信基于MAC而非IP-->

此时出现问题:请求报文的目标IPVIP,而DirectorRS1RS2均配有VIP,当路由器做ARP地址广播请求拥有VIP地址的主机将其MAC发送过来时,三台主机均可响应,则无法保证报文是经由Director调度后发送至选定的RS,所以需要设置RS使其拒绝响应路由器的ARP广播或响应报文不予放行;

(2)此时请求报文只能由源MAC(路由器)发送至目标MACDirector);请求报文到达Director后,通过调度算法选定某RS,由Director再做ARP地址广播获得RSMAC,将请求报文的源MAC改为Director,目标MAC改为选定的RS,调度至此完成;

(3)请求报文到达RS后,通过解封,RS发现源IPCIP,目标IPVIP且本机具备,所以当RIP的网关指向本地路由器时,就可直接将响应报文发送给客户端而无需经过Director

(4)此时出现另一个问题:因为VIP配置在lo上,而lo无法与外部通信,所以响应报文只能经由物理网卡RIP流出,则响应报文的源IP变为了RIP,目标IPCIP;但是客户端请求的是VIP而非RIP,所以必须让第(2)步的请求报文到达RS后经由lo接口进入(由此保证了响应报文的源IPVIP),然后经由forward链转发至物理网卡响应给客户端;

                

                       上文提到的第三种解决方案需要修改内核参数,此参数是Linux2.4.262.6.4版本

                       入的,位于/proc/sys/net/ipv4/conf/INTERFACE

                       以下图为例加以说明

                        lvs基础介绍及实验演示_负载均衡_03       

                        

arp_announce

定义arp通告级别;有0~2三个级别,默认0级,当ARP广播到达后,会把自己拥有的3个IP地址都做响应;1级,尽量避免将与ARP广播来源不在同一网络的网卡上配置的IP地址作出响应;2级只允许和广播来源处于同一网络的IP作出响应;

以上图为例,0级1.1、2.1、3.1均会响应1.2的广播;1级尽量只让1.1响应1.2的广播,但是并不禁止2.1和3.1响应;而2级则只允许1.1响应1.2的广播;

 

arp_ignore

定义arp忽略arp请求或arp通告的级别;有0~8九个级别

以上图为例,当2.6请求与2.1通信的广播到达1.1时:默认0级,虽然1.1本身和2.6不在同一网络,但2.1和2.6却在同一网络,依据Linux特性,内核认为自己拥有2.1地址,所以会通过1.1接口对该广播作出响应;1级,只有广播请求流入的接口本身就是广播请求的地址时才予以响应,否则不予响应(即当2.6请求与2.1通信的广播从1.1网卡流入时,主机将不予响应;只有当广播从2.1接口流入时才会响应)

               

                lvs-tun

不修改请求报文的IP首部,而是通过IP隧道机制在原有IP报文之外再封装IP首部,经由互联网把请求报文转交给选定的RS

 

架构特性

(1)RIPDIPVIP都是公网地址;

(2)RS的网关无法指向DIP

(3)请求报文经由Director分发,但响应报文直接由RS响应给Client

(4)不支持端口映射;

(5)RSOS必须支持IP隧道;


                lvs-fullnat

通过修改请求报文的源地址为DIP,目标地址为RIP来实现转发;对于响应报文而言,修改源地址为VIP,目标地址为CIP来实现转发

 

架构特性

(1)RIPDIP可以使用私有地址;

(2)RIPDIP可以不在同一网络中,且RS的网关无须指向DIP

(3)支持端口映射;

(4)RSOS可以使用任意类型;

(5)请求报文和响应报文都必须经由Director


        LVS的调度算法分为静态方法和动态方法,共有10种,详细介绍如下:

                

    静态调度

    仅根据算法实现调度

    RR:

    round-robin,轮询、轮调、轮流、轮叫;

    WRR:

    weighted round-robin,加权轮询;算法公式:Overhead=conn/weight;

      DH                                                                                             

    Destination ip Hashing,目标地址哈希;把访问同一目标地址的访问定向至此前选定的RS;

    lvs基础介绍及实验演示_lvs_04

    应用场景:当某网络的出口网关有多个时,例如本公司有两个出口网关,而公司内有众多客户端,(1)当第一次访问某网站时,请求报文从FW1出去,返回时有可能从FW2返回,而FW2上的iptables设置了状态链接追踪规则,只允许ESTABLISHED状态的响应报文放行,此时会导致客户端无法得到响应;(2)客户端A通过FW1访问了某网站,有了缓存,而客户端B却通过FW2访问了同一网站,此时A访问是产生的缓存未生效;此时DH算法可将所有访问该网站的请求全都调度到FW1上以提升缓存命中率;但是当公司的所有客户都访问该网站时,所有的请求都被调度到FW1,而FW2却无需响应请求,反均衡;此时LBLC算法可解决此问题,但是却降低了缓存命中率,此时LBLCR可进一步解决此问题。

    SH:

    Source ip Hashing,源地址哈希;把来自同一地址的请求定向至此前选定的RS;

    基于IP的哈希是反均衡的(例如通过SNAT的IP,一个IP可能有来自众多私网IP的请求,而SH却把众多的请求视作一个IP请求直接调度给了同一个RS),可通过应用层基于cookie的哈希解决此问题,但是lvs无法工作于应用层

     

    动态调度

    根据算法及后端RS当前负载状况实现调度

    LC

    least connection,最小连接

    算法公式:Overhead=Active*256+Inactive

    WLC

    weighted least connection,加权最小连接;lvs默认调度方法

    算法公式:Overhead=(Active*256+Inactive)/weight

    lvs的默认调度算法

    SED

    Shorted Expectation Delay,最短期望延迟

    算法公式:Overhead=(Active+1)*256/weight

    NQ

    Never Queue,永不排队

    按照SED算法按顺序先保证每个RS至少处理一个请求,然后再按照SED算法进行调度

    LBLC

    Local-Based Least Connection,基于本地的最少连接,动态方式的DH算法

    LBLCR

    Replicated LBLC,可复制的LBLC

     

    名词解释

    overhead:

    衡量当前RS负载情况的指标,值越小,越被优先调度


        在对LVS有了基本的了解后,现在我们来介绍下ipvsadm构建集群服务的具体使用方法。

                (1)管理集群服务

        创建或修改

        ipvsadm-A|E -t|u|f service-address [-s scheduler]

        -A:创建

        -E:修改

         

        -t:

        承载的应用层协议基于tcp协议,其service-address的格式为“VIP:PORT”,如“172.16.14.1:80”;

        -u:

        承载的应用层协议基于udp协议,其service-address的格式为“VIP:PORT”,如“172.16.14.1:53”;

        -f:

        承载的应用层协议基于TCP或UDP协议,但此类报文会经由iptables/netfilter打标记即防火墙标记,0~99之间的整数);其service-address的格式为“FWM,例如“10

        作用是将基于不同端口的服务归为同一类集群服务

        -s scheduler:

        指明调度方法,省略时默认使用WLC

         

        删除

        ipvsadm-D -t|u|f service-address


                (2)管理集群上的RS

        添加或修改

        ipvsadm-a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight]

        -r server-address:

        指明RSserver-address格式一般为IP[:PORT];注意,只有支持端口映射的lvs类型中才应该显式定义此处端口

        [-g|i|m]:指明lvs类型

        -g:gateway,意为dr类型;

        -i:ipip,意为tun类型;

        -m:masquerade,意为nat类型;

        省略时默认为dr类型

        [-w weight]:

        指明当前RS的权重,只对支持加权调度的scheduler才有意义;

         

        删除

        ipvsadm-d -t|u|f service-address -r server-address

            

                (3)查看规则

            pvsadm -L|l [options]

            -c: 列出当前所有connection;

            --stats: 列出统计数据

            --rate: 列出速率

            -n, --numeric: 数字格式显示IP及端口;

            --exact: 精确值;

        

                (4)保存及回复规则 

        ipvsadm -S > /etc/sysconfig/ipvsadm

        ipvsadm-save > /etc/sysconfig/ipvsadm

        service ipvsadm save

     

        ipvsadm -R < /etc/sysconfig/ipvsadm

        ipvsadm-restore < /etc/sysconfig/ipvsadm

        service ipvsadm restart


 LVS的实验演示

        有了以上的基础,下面我们以lvs-nat和lvs-dr两种类型为演示,进一步加深对LVS的理解

                lvs-nat类型的web服务器集群构建演示

                

1、安装ipvsadm,并查看ipvs在当前系统是否启用

# yum install -y ipvsadm

# grep -i -A 5"ipvs" /boot/config-2.6.32-504.el6.x86_64

显示下列结果可知,当前系统已启用了ipvs

lvs基础介绍及实验演示_调度器_05

 

2、构建实验拓扑机构

lvs基础介绍及实验演示_lvs_06

 

将两台RS的默认网关指向DIP

# route add default gw 192.168.14.3

编辑两台RS的测试页

# vim /var/www/html/index.html

测试RIPVIPDIP的连通性

# ping 192.168.14.3

# ping 172.16.14.2

DIP上测试两台RS

# curl http://192.168.14.1

# curl http://192.168.14.2

 

3、使用ipvsadm构建集群服务

 

# ipvsadm -A -t 172.16.14.2:80 -s rr

# ipvsadm -a -t 172.16.14.2:80 -r 192.168.14.1 -m -w1

# ipvsadm -a -t 172.16.14.2:80 -r 192.168.14.2 -m -w5

# ipvsadm -ln

lvs基础介绍及实验演示_调度器_07

 

4、确保Director的网络间转发功能处于开启状态

# cat /proc/sys/net/ipv4/ip_forward

若结果为0,则

# echo 1 > /proc/sys/net/ipv4/ip_forward

或者

# vim /etc/sysctl.conf

lvs基础介绍及实验演示_负载均衡_08

# sysctl -p

 

5、在浏览器上访问172.16.14.2后查看结果

# ipvsadm -ln --stats

lvs基础介绍及实验演示_调度器_09

因为采用的schedulerrr,所以权重无意义,因此调度结果是11

 

6、修改调度方法后再做测试

# ipvsadm -E -t 172.16.14.2:80 -s wrr

# ab -n 10000 -c 100 http://172.16.14.2/index.html

# ipvsadm -ln --stats

lvs基础介绍及实验演示_调度器_10

此时调度结果接近15

 

7、再次修改调度方法做测试

# ipvsadm -E -t 172.16.14.2:80 -s sh

计数清零

# ipvsadm -Z

lvs基础介绍及实验演示_lvs_11

# ab -n 10000 -c 100 http://172.16.14.2/index.html

# ipvsadm -ln --stats

lvs基础介绍及实验演示_调度器_12

此时所有请求全都被调度到RS2

 

8、抓包分析

tcpdump -i eth0 -nn host 172.16.250.65(本机物理IP

lvs基础介绍及实验演示_负载均衡_13


                lvs-dr类型的web服务器集群构建演示

                

1.设计实验拓扑结构

lvs基础介绍及实验演示_lvs_14

 

2、配置Director:

(1)VIP配置在物理接口的别名上

ifconfigINTERFACE:ALIAS $vip broadcast $vip netmask 255.255.255.255

# ifconfig eth0:0 172.16.14.2 broadcast172.16.14.2 netmask 255.255.255.255

 

(2) 配置路由信息 

routeadd -host $vip dev INTEFACE:ALIAS

# route add -host 172.16.14.2 dev eth0:0

 

3、配置RS:

(1)先修改内核参数

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

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

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

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

lvs基础介绍及实验演示_负载均衡_15

lvs基础介绍及实验演示_调度器_16


 

(2) VIP配置在lo的别名上

ifconfiglo:0 $vip broadcast $vip netmask 255.255.255.255 up

 

(3)配置路由信息

routeadd -host $vip dev lo:0

# route add -host 172.16.14.2 dev lo:0

此步配置确保响应报文必须从lo:0流出,从而保证了RS直接响应给客户端的报文源IP是VIP

 

4、使用ipvsadm构建集群服务

#ipvsadm -A -t 172.16.14.2:80 -s rr

# ipvsadm -a -t 172.16.14.2:80 -r 192.168.0.1 -g -w1

# ipvsadm -a -t 172.16.14.2:80 -r 192.168.0.2 -g -w5

lvs基础介绍及实验演示_负载均衡_17

 

5、补充说明:

(1)因为lvs-dr模型的VIP仅用于目标地址标记而不用于通信,所以VIP掩码一般设置为32位(形如“netmask255.255.255.255”);虽然这是子网掩码但是在这里已经不是用来分子网用的,而是用来作为受限广播地址的(表示广播时全匹配,这时候的子网掩码和ip地址完全相同,只能匹配到自己)。

四个特殊地址:

直接广播地址:X.X.X.255(ip最后一位为255)

受限广播地址:255.255.255.255(全四位为255)

这个网络上的特定主机:0.0.0.X(X表示在1—254之间随意取)

回送地址:127.0.0.0(属于A类ip地址)

 

(2)为确保VIP不会主动对外做广播,可设置“broadcast $vip”,表示广播域仅是自己本身;

 

(3)辅助命令

查看内核参数

#sysctl -a

lvs基础介绍及实验演示_调度器_18

显示ping命令发起主机和响应主机的对应网卡MAC地址

# arp-a

lvs基础介绍及实验演示_lvs_19


lvs定义集群服务的“-f”方式

 

定义格式

-f FWM,防火墙打标

在ipvs生效之前的netfilter的某hook function上定义iptables规则,实现给报文打上防火墙标记;

 

定义方法

(1) 打标:在Director上mangle表的PREROUTING链上实现

# iptables -t mangle -A PREROUTING -d $vip -p $protocol --dport$port -j MARK --set-mark FWM([1-99])

 

(2) 基于FWM定义集群服务

#ipvsadm -A -f FWM -s SCHEDULER

#ipvsadm -a -f FWM -r server-address -g|-i|-m -w #

 

lvspersistencelvs持久连接

无论使用哪一种调度方法,持久连接功能都能保证在指定时间和范围之内,来自于同一个IP的请求将始终被定向至同一个RS;

 

persistencetemplate:持久连接模板

 

PPC:

每端口持久,持久连接的生效范围仅为单个集群服务;如果有多个集群服务,每服务被单独持久调度;

PCC:

每客户端持久,持久连接的生效范围为所有集群服务;定义集群服务时,其tcp或udp协议的目标端口要使用0

PFWM:

每防火墙标记持久,持久连接的生效范围为定义为同一个FWM下的所有服务;

 

ipvsadm-A -t|-u|-f service-address -s SCHEDULER [-p [#]]

无-p选项:不启用持久连接

-p #:指定持久时长,省略时长,默认为300seconds

 

RS宕机问题解决方案

lvs本身不支持对RS的健康状态作检测

(1)自写程序

(2)keepalived程序(可解决单点故障和健康状态检测);

 

健康状态检测应该是一种周期性检查机制,并在状态发生变化时作出相应处理

当状态up-->down,建议至少检查3次再做相应处理;

当状态down-->up,建议至少检查1次再做相应处理;

 

下线处理机制:

(1)设置权重为0;

(2)将相应的RS 从ipvs的可用RS列表中移除;

 

上线处理机制:

(1)设置为正常权重;

(2)将相应的RS添加到ipvs的可用RS列表中;

 

健康状态检测方法

(1)IP层:ping等主机在线状态探查工具;

(2)传输层:端口扫描工具探查服务在线状态;

(3)应用层:请求专用于健康状态检查的资源或者某正常资源;

 

备用服务器

当后端所有RS都宕机时,启用此服务器

sorry server,backupserver

可以在Director上直接实现,即配置Director称为web服务器,仅提供有限资源,在所有RS都出现故障时才启用此server