LVS(Linux Virtual Server)即Linux虚拟服务器,由章文嵩博士主导的开源负载均衡项目,目前LVS已经被集成到Linux内核模块中。该项目在Linux内核中实现了基于IP的数据请求负载均衡调度方案,客户端请求某服务时,请求会先发送给LVS调度器,调度器根据自己预设的算法决定将该请求发送给后端的某台服务器。
VS
:
Virtual Server
,
Director Server(DS), Dispatcher(
调度器
),
Load Balancer
RS
:
Real Server(调度器为lvs时), upstream server(调度器为nginx时), backend server(调度器为haproxy时)
CIP:
Client IP(客户端ip)
VIP
:
Virtual serve IP,VS
外网的
IP
DIP
:
Director IP,VS
内网的
IP
RIP
:
Real server IP
二、工作模式
1、NAT模式
通过将请求报文中的目标地址和目标端口修改为LVS通过调度算法得出的
RS
的
RIP
和PORT实现转发,请求报文和响应报文的传输路径一致,下图为示例:
在上图中:
(
1
)
RIP
和
DIP
应该在同一个
IP
网络(可以不在),且应使用私网地址,
RS
的网关要指向
DIP。
(
2
)请求报文和响应报文都必须经由
Director(即VS)
转发,
Director
易于成为系统瓶颈。
(
3
)支持端口映射(即后端服务端口可以不用保持为默认端口)可修改请求报文的目标
PORT。
(
4
)
VS
必须是
Linux
系统,
RS
可以是任意
OS
系统。
过程中LVS服务器的内部操作:
如上图所示:
一开始,用户通过CIP发往VIP,LVS服务器接收到后,由于VIP确实为LVS的IP,因此,请求报文将会进入INPUT链(linux防火墙),因为LVS为虚拟服务器,本身没有为用户提供服务的能力,因此,请求报文将会被截获,改为CIP发往RIP,及上图中的第三步。
2、DR模式(重点)
Direct Routing,直接路由,
LVS
默认模式
,
应用最广泛
,
通过为请求报文重新封装一个
MAC
首部进行转发
,每个RS上都配备有一个VIP,如下图所示:
如上图所示,请求报文要经过LVS,而响应报文则不用,提高了效率。
LVS与RS之间的必须是交换机,不能是路由器,即不能跨网段,因为LVS要想获得RS的MAC地址,必须通过ARP广播获得,所以之间不能是路由器。
因为LVS和RS中都配备了VIP,如何确保路由器会将请求报文发向LVS。而不是RS,第一种是在路由器上做个VIP和LVS的MAC地址的绑定,但不建议。第二种,当路由器发送ARP广播获取VIP的MAC地址时,RS不做回应,开启ignore;还有当RS启动VIP这个网卡时,会对外广播MAC地址,也要将这个Announce功能关闭,这样路由器就只会得到LVS的MAC地址。
将RS中的VIP绑定到lo网卡上,然后对arp_ignore和arp_announce两个内核参数进行修改。
DR模式下不支持端口映射,即服务应保持默认端口,例:apache服务,保持80端口。
3、TUN模式
工作原理:
不修改请求报文的IP
首部(源
IP
为
CIP
,目标
IP
为
VIP
),而在原
IP
报文之外再封装一个
IP
首部 (源IP
是
DIP,
目标
IP
是
RIP
),将报文发往挑选出的目标
RS,
RS
直接响应给客户端(源
IP
是
VIP
,目标
IP是CIP
)
其中的switch可以是路由,LVS和RS之间可以是跨网段的,如下图:
4、三种主要模式对比
三、LVS调度算法
根据其调度时是否考虑各
RS
当前的负载状态分为两种:静态方法和动态方法。
静态方法:
1
、
RR
:
roundrobin
,轮询
,
较常用。
2
、
WRR
:
Weighted RR
,加权(根据各台RS之间的性能,性能好,比重高)轮询
,
较常用。
3
、
SH
:
Source Hashing
,实现
session sticky
,源
IP
地址
hash
;将来自于同一个
IP
地址的请求始终发往第一次挑中的RS
,从而实现会话绑定,有时会造成某台RS服务器负载过大。
4
、
DH
:
Destination Hashing
;目标地址哈希,第一次轮询调度至
RS,后续将发往同一个目标地址的请求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡(每个RS有对应的缓存服务器),如:
Web
缓存。
动态方法:
主要根据每
RS
当前的负载状态及调度算法进行调度,
Overhead=value
较小的
RS
将被调度
1
、
LC
:
least connections
适用于长连接应用
Overhead=activeconns*256+inactiveconns (其中activeconns为活动连接,inactiveconns为非活动连接)
2
、
WLC
:
Weighted LC
,带权重,默认调度方法
,
较常用
Overhead=(activeconns*256+inactiveconns)/weight
3
、
SED
:
Shortest Expection Delay
,指初始连接时,高权重优先,
只检查活动连接
,
而不考虑非活动连接
Overhead=(activeconns+1)*256/weight
4
、
NQ
:
Never Queue
,第一轮均匀分配,后续
SED
5
、
LBLC
:
Locality-Based LC
,动态的
DH
算法,使用场景:根据负载状态实现正向代理
,
实现
Web Cache等
6
、
LBLCR
:
LBLC with Replication
,带复制功能的
LBLC
,解决
LBLC
负载不均衡问题,从负载重的复制到负载轻的RS,
实现
Web Cache
等
内核版本 4.15 版本后新增调度算法:FO和OVF
1、FO
(
Weighted Fail Over
)调度算法
,
在此
FO
算法中,遍历虚拟服务所关联的真实服务器链表,找到还未过载(未设置IP_VS_DEST_F_OVERLOAD
标志)的且权重最高的真实服务器,进行调度
,
属于静态算法
2、OVF
(
Overflow-connection
)调度算法,基于真实服务器的活动连接数量和权重值实现。将新连接调度到权重值最高的真实服务器,直到其活动连接数量超过权重值,之后调度到下一个权重值最高的真实服务器,
在此
OVF
算法中,遍历虚拟服务相关联的真实服务器链表,找到权重值最高的可用真实服务器,
属于动态算法
一个可用的真实服务器需要同时满足以下条件:
未过载(未设置IP_VS_DEST_F_OVERLOAD
标志)
真实服务器当前的活动连接数量小于其权重值
其权重值不为零
四、实验演示
LVS相关软件
程序包:ipvsadm
1、LVS-NAT模式
实验图如下:
1、配好上述主机的网卡,在各台主机上开启apache服务,做测试用。
2、配置LVS主机
yum -y install ipvsadm
ipvsadm -A -t 192.168.142.134:80 -s rr #创建集群,rr表示LVS调度使用轮询算法
ipvsadm -a -t 192.168.142.134:80 -r 192.168.204.132 -m #往集群里添加RS,-m表示NAT模式
ipvsadm -a -t 192.168.142.134:80 -r 192.168.204.133 -m
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf #启用转发功能
sysctl -p
3、在客户端使用curl命令访问vip测试即可
curl 192.168.142.134
4、在LVS上用ipvsadm -Ln可查看定义的集群规则。
2、LVS-DR模式
实验示例图如下:
1、先按照上图配置IP,网关等信息,记得路由要配转发功能。
2、配置RS(重点)
每个RS上的lo网卡上绑定VIP,并且修改两个内核参数。
回环网卡lo绑定vip:ifconfig lo:1 192.168.204.100/32,子网掩码必须为32位。
修改内核参数:
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
在每台RS上执行上述两步操作
3、配置LVS
回环网卡lo绑定vip:ifconfig lo:1 192.168.204.100/32,
子网掩码必须为32,否则访问vip时报文无法转发出去,
而VIP绑定到其他物理网卡上则不是必须32位。
其中的VIP可以为与物理网卡同一网段的IP,但不要IP冲突。
LVS的网关在本次实验中,其实可以随便配,但不可以不配,因为VIP和client并不在同一网段,当LVS收到从client的报文时,如果不配网关,LVS会丢弃此报文,而不调度给RS。
ifconfig lo:1 192.168.204.100/32
yum -y install ipvsadm
ipvsadm -A -t 192.168.204.100:80 -s rr #创建集群,rr表示LVS调度使用轮询算法
ipvsadm -a -t 192.168.204.100:80 -r 192.168.204.132 -g #往集群里添加RS,-g表示DR模式
ipvsadm -a -t 192.168.204.100:80 -r 192.168.204.137 -g
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf #启用转发功能
sysctl -p
4、在客户端用curl命令测试访问VIP即可
LVS-DR多网段实验图示例(过程和单网段差不多):
3、LVS-TUN模式
不支持端口映射,允许跨网段,即LVS与RS可以在不同网段中,但也可以在同一网段。
实验示例图如下:
1、按照上图先配好各台主机的ip,以及网关,记得路由开启转发功能等。
2、配置LVS
创建tunl0虚拟网卡,并绑定VIP,其中的VIP可以为与物理网卡同一网段的IP,但不要IP冲突。
ifconfig tunl0 192.168.204.100 netmask 255.255.255.255 up
yum -y install ipvsadm
ipvsadm -A -t 192.168.204.100:80 -s rr #创建集群,rr表示LVS调度使用轮询算法
ipvsadm -a -t 192.168.204.100:80 -r 192.168.204.132 -i #往集群里添加RS,-i表示TUN模式
ipvsadm -a -t 192.168.204.100:80 -r 192.168.204.137 -i
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf #启用转发功能
sysctl -p
3、配置RS
修改内核参数(如果是跨网段则不用执行)
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
创建tunl0虚拟网卡,并绑定VIP
ifconfig tunl0 192.168.204.100 netmask 255.255.255.255 up
修改内核参数:
echo 0 > /proc/sys/net/ipv4/conf/tunl0/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
上述两行中的参数用来控制系统是否开启对数据包源地址的校验。
0标示不开启地址校验。
1表开启严格的反向路径校验。对每一个进行的数据包,校验其反向路径是否是最佳路径。如果反向路径不是最佳路径,则直接丢弃该数据包。
2标示开启松散的反向路径校验,对每个进行的数据包,校验其源地址是否可以到达,即反向路径是否可以ping通,如反向路径不通,则直接丢弃该数据包。
在每台RS上执行上述三步操作
4、在客户端用curl命令测试即可
五、防火墙标记
有时,当有多个集群时,对共享同一组RS的多个集群服务,LVS会将不同的请求服务同时调度在一台机器上,如下图所示:
可以通过使用防火墙标签的方法来解决此问题,即将443和80端口统一用某端口来表示,下面举例用10端口。拿上述LVS-DR模型的IP来举例,在LVS上配置。
iptables -t mangle -A PREROUTING -d 192.168.204.100 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 10
ipvsadm -C #清除原有规则
ipvsadm -A -f 10 -s rr
ipvsadm -a -f 10 -r 192.168.204.132 -g
ipvsadm -a -f 10 -r 192.168.204.137 -g
六、LVS持久连接
即实现无论使用任何调度算法,在一段时间内(timeout默认360s ),
能够实现将来自同一个地址的请求始终发往同一个RS。
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] #命令格式
ipvsadm -A -t 192.168.204.100:80 -s rr -p 600 #举例设为600s