LVS基础介绍
LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个开源的软件,可以基于软件的方法实现LINUX平台下的负载均衡,由章文嵩博士于1998年5月研发,是中国国内最早出现的自由软件项目之一。
LVS集群采用IP负载均衡技术和基于内容请求分发技术。调度器具有很好的吞吐率,将请求均衡地转移到不同的服务器上执行,且调度器自动屏蔽掉服务器的故障,从而将一组服务器构成一个高性能的、高可用的虚拟服务器。整个服务器集群的结构对客户是透明的,而且无需修改客户端和服务器端的程序。为此,在设计时需要考虑系统的透明性、可伸缩性、高可用性和易管理性。
LVS由两部分组成,分别是
ipvs:工作于内核空间的input或prerouting链
ipvsadm:在ipvs上写规则的工具,用于在ipvs上定义集群服务及该集群服务对应的后端可用主机;
二者结合使LVS可以根据指定的调度方法(算法)作出调度决策
在正式介绍lvs前,我们要先对其使用的术语有一个基本的了解。
Host
Director:调度器
Real Server:RS,后端提供服务的主机
IP
Client:CIP
Director Virtual IP:VIP
Director IP:DIP
Real IP:RIP
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
类似iptables的DNAT,但支持多目标转发
通过将请求报文的目标地址修改为根据调度算法所挑选出的某RS的RIP来转发
架构特性
(1)RS应该使用私有地址,即RIP应该为私有地址;各RS网关必须指向DIP;
(2)请求和响应报文都经由Director转发,所以高负载场景中,Director容易成为系统瓶颈;
(3)支持端口映射;
(4)RS支持使用任意类型的OS;
(5)RS的RIP必须与Director的DIP处于同一网段;
拓扑图
lvs-dr
直接路由
Director在实现转发时不修改请求报文的IP首部,而是通过直接封装帧首部(MAC首部)完成转发(源MAC为Director的MAC,目标MAC为算法选定的RS的MAC);
架构特性
(1)各RS要直接响应Client,因此各RS均需配置VIP;但仅允许Director上的VIP能够与本地末梢路由直接通信;
解决方案
静态绑定:在前端路由直接将VIP对应的目标MAC静态配置为Director的MAC地址;
arptables:在各RS上,通过arptables规则拒绝响应对VIP的ARP广播请求;
内核参数:在RS上修改内核参数,并结合地址的配置方式实现拒绝响应;
(2)RS的RIP可以使用私有地址和公网地址,使用公网地址时可通过互联网上的主机直接对此RS进行管理操作;
(3)请求报文必须经由Director调度,而响应报文必须不能经由Director;
(4)各RIP必须与DIP在同一物理网络中;
(5)不支持端口映射;
(6)RS支持使用大多数的OS;
(7)RS的网关一定不能指向Director;
拓扑图
(1)客户端的请求报文到达本地路由-->ARP地址解析(本地间通信基于MAC而非IP)-->?
此时出现问题:请求报文的目标IP是VIP,而Director和RS1、RS2均配有VIP,当路由器做ARP地址广播请求拥有VIP地址的主机将其MAC发送过来时,三台主机均可响应,则无法保证报文是经由Director调度后发送至选定的RS,所以需要设置RS使其拒绝响应路由器的ARP广播或响应报文不予放行;
(2)此时请求报文只能由源MAC(路由器)发送至目标MAC(Director);请求报文到达Director后,通过调度算法选定某RS,由Director再做ARP地址广播获得RS的MAC,将请求报文的源MAC改为Director,目标MAC改为选定的RS,调度至此完成;
(3)请求报文到达RS后,通过解封,RS发现源IP是CIP,目标IP是VIP且本机具备,所以当RIP的网关指向本地路由器时,就可直接将响应报文发送给客户端而无需经过Director;
(4)此时出现另一个问题:因为VIP配置在lo上,而lo无法与外部通信,所以响应报文只能经由物理网卡RIP流出,则响应报文的源IP变为了RIP,目标IP为CIP;但是客户端请求的是VIP而非RIP,所以必须让第(2)步的请求报文到达RS后经由lo接口进入(由此保证了响应报文的源IP是VIP),然后经由forward链转发至物理网卡响应给客户端;
上文提到的第三种解决方案需要修改内核参数,此参数是Linux2.4.26和2.6.4版本后
入的,位于/proc/sys/net/ipv4/conf/INTERFACE
以下图为例加以说明
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)RIP,DIP,VIP都是公网地址;
(2)RS的网关无法指向DIP;
(3)请求报文经由Director分发,但响应报文直接由RS响应给Client;
(4)不支持端口映射;
(5)RS的OS必须支持IP隧道;
lvs-fullnat
通过修改请求报文的源地址为DIP,目标地址为RIP来实现转发;对于响应报文而言,修改源地址为VIP,目标地址为CIP来实现转发
架构特性
(1)RIP,DIP可以使用私有地址;
(2)RIP和DIP可以不在同一网络中,且RS的网关无须指向DIP;
(3)支持端口映射;
(4)RS的OS可以使用任意类型;
(5)请求报文和响应报文都必须经由Director;
LVS的调度算法分为静态方法和动态方法,共有10种,详细介绍如下:
静态调度
仅根据算法实现调度
RR:
round-robin,轮询、轮调、轮流、轮叫;
WRR:
weighted round-robin,加权轮询;算法公式:Overhead=conn/weight;
DH:
Destination ip Hashing,目标地址哈希;把访问同一目标地址的访问定向至此前选定的RS;
应用场景:当某网络的出口网关有多个时,例如本公司有两个出口网关,而公司内有众多客户端,(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:
指明RS,server-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
2、构建实验拓扑机构
将两台RS的默认网关指向DIP
# route add default gw 192.168.14.3
编辑两台RS的测试页
# vim /var/www/html/index.html
测试RIP与VIP及DIP的连通性
# 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
4、确保Director的网络间转发功能处于开启状态
# cat /proc/sys/net/ipv4/ip_forward
若结果为0,则
# echo 1 > /proc/sys/net/ipv4/ip_forward
或者
# vim /etc/sysctl.conf
# sysctl -p
5、在浏览器上访问172.16.14.2后查看结果
# ipvsadm -ln --stats
因为采用的scheduler是rr,所以权重无意义,因此调度结果是1:1的
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
此时调度结果接近1:5
7、再次修改调度方法做测试
# ipvsadm -E -t 172.16.14.2:80 -s sh
计数清零
# ipvsadm -Z
# ab -n 10000 -c 100 http://172.16.14.2/index.html
# ipvsadm -ln --stats
此时所有请求全都被调度到RS2上
8、抓包分析
tcpdump -i eth0 -nn host 172.16.250.65(本机物理IP)
lvs-dr类型的web服务器集群构建演示
1.设计实验拓扑结构
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
(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
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
显示ping命令发起主机和响应主机的对应网卡MAC地址
# arp-a
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 #
lvs的persistence:lvs持久连接
无论使用哪一种调度方法,持久连接功能都能保证在指定时间和范围之内,来自于同一个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