一、LVS的简介

    LVS(Linux Virtual Server)即Linux虚拟服务器,是由章文嵩博士主导的开源负载均衡项目,目前LVS已经被集成到Linux内核模块中。该项目在Linux内核中实现了基于IP的数据请求负载均衡调度方案,其体系结构如图1所示,终端互联网用户从外部访问公司的外部负载均衡服务器,终端用户的Web请求会发送给LVS调度器,调度器根据自己预设的算法决定将该请求发送给后端的某台Web服务器,比如,轮询算法可以将外部的请求平均分发给后端的所有服务器,终端用户访问LVS调度器虽然会被转发到后端真实的服务器,但如果真实服务器连接的是相同的存储,提供的服务也是相同的服务,最终用户不管是访问哪台真实服务器,得到的服务内容都是一样的,整个集群对用户而言都是透明的。最后根据LVS工作模式的不同,真实服务器会选择不同的方式将用户需要的数据发送到终端用户,LVS工作模式分为NAT模式、TUN模式、以及DR模式。

LVS 官网: http://www.linuxvirtualserver.org/

二、三种工作模式

1、基于NAT的LVS模式负载均衡

    NAT(Network Address Translation)即网络地址转换,其作用是通过数据报头的修改,使得位于企业内部的私有IP地址可以访问外网,以及外部用用户可以访问位于公司内部的私有IP主机。

LVS-NAT:

本质是多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和 PORT实现转发

RIP和DIP应在同一个IP网络,且应使用私网地址;RS的网关要指向DIP

请求报文和响应报文都必须经由Director转发,Director易于成为系统瓶颈

支持端口映射,可修改请求报文的目标PORT

VS必须是Linux系统,RS可以是任意OS系统

下面通过实验来给大家演示基于NAT的LVS负载均衡

实验一

实验拓扑图

本实验均使用VMware 红帽9的操作系统(需要四台主机,一台客户端,一台LVS,两台服务器) 

注:LVS为双网卡,一个网卡连接客户端,一个网卡连接后面的服务器

配置命令

Webserver1的配置:

# 使用脚本
vmset.sh eth0 192.168.0.10 webserver1.org
# 修改网关
vim /etc/NetworkManager/system-connections/eth0.nmconnection
address1=192168.0.10/24,192.268.0.100
# 更新网卡
nmcli connection reload
nmcli connection up eth0
# 下载httpd服务,用于测试
yum install httpd -y
echo webserver1 - 192.168.0.10 > /var/www/html/index.html
systemctl enable  --now httpd

Webserver2的配置:

与Webserver1类似(把主机IP改为192.168.0.20),参考Webserver1的配置

 LVS的配置:

# 使用脚本
 vmset.sh eth0 172.25.254.100 lvs.org
 vmset.sh eth1 192.168.0.100  lvs.org
# 修改网关
 vim /etc/NetworkManager/system-connections/eth1.nmconnection
 将eth1网关删掉
# 更新网卡
 nmcli connection reload
 nmcli connection up eth1
# 启用内核路由功能
vim /etc/sysctl.conf
添加 net.ipv4.ip_forward = 1
# 安装ipvsadm
 yum install ipvsadm -y
# 添加调度策略
ipvsadm -A -t 172.25.254.100:80 -s rr
ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.10:80 -m
ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.20:80 -m
# 查看策略
  ipvsadm -Ln
TCP 172.25.254.100:80 rr

   -> 192.168.0.10:80   Masq   1   0   0

   -> 192.168.0.20:80

客户端测试:

[root@Client ]# for i in {1..5}; do curl 172.25.254.100; done
webserver2 - 192.168.0.20

webserver - 192.168.0.10

webserver2 - 192.168.0.20

webserver - 192.168.0.10

webserver2 - 192.168.0.20

注:在企业中两个Web服务器用该访问到相同的东西,本实验仅供测试,方便看出效果

2、基于DR的LVS负载均衡 

DR:Direct Routing 直接路由模式(DR模式)要求调度器与后端服务器必须在同一个局域网内,VIP地址需要在调度器与后端所有的服务器间共享,因为最终的真实服务器给客户端回应数据包时需要设置源IP为VIP地址,目标IP为客户端IP,这样客户端访问的是调度器的VIP地址,回应的源地址也依然是该VIP地址(真实服务器上的VIP),客户端是感觉不到后端服务器存在的。由于多台计算机都设置了同样一个VIP地址,所以在直接路由模式中要求调度器的VIP地址是对外可见的,客户端需要将请求数据包发送到调度器主机,而所有的真实服务器的VIP地址必须配置在Non-ARP的网络设备上,也就是该网络设备并不会向外广播自己的MAC及对应的IP地址,真实服务器的VIP对外界是不可见的,但真实服务器却可以接受目标地址VIP的网络请求,并在回应数据包时将源地址设置为该VIP地址。调度器根据算法在选出真实服务器后,在不修改数据报文的情况下,将数据帧的MAC地址修改为选出的真实服务器的MAC地址,通过交换机将该数据帧发给真实服务器。整个过程中,真实服务器的VIP不需要对外界可见。 

实验二

实验拓扑图

本实验均使用VMware 红帽9的操作系统(需要五台主机,一台客户端,一台路由器,一台LVS,两台服务器) 

配置命令 

Webserver的配置:

# Webserver1,2的基础配置与实验一相同
# RS(real server)主机中使vip不对外响应
[root@webserver1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@webserver1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@webserver1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce  
[root@webserver1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore

[root@webserver2 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore 
[root@webserver2 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@webserver2 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce 
[root@webserver2 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
# 在server设定vip
[root@webserver1 ~]#  ip a a 192.168.0.200/32 dev lo
[root@webserver2 ~]# ip a a 192.168.0.200/32 dev lo

 Client 的配置:

# 使用脚本
 vmset.sh eth0 172.25.254.200 Client.org
# 修改网关
 vim /etc/NetworkManager/system-connections/eth0.nmconnection
 address1=172.25.254.200/24.172.25.254.100
# 更新网卡
 nmcli connection reload
 nmcli connection up eth0

router的配置:

# 使用脚本
[root@router ~]# vmset.sh eth0 172.25.254.100 router.org

[root@router ~]# vmset.sh eth1 192.168.0.100 router.org

[root@router ~]# vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=172.25.254.100/24,172.25.254.2
method=manual
dns=114.114.114.114;

[root@router ~]# cat /etc/NetworkManager/system-connections/eth1.nmconnec         
[connection]
id=eth1
type=ethernet
interface-name=eth1

[ipv4]
address1=192.168.0.100/24
method=manual
# 更新网卡
[root@router ~]# nmcli connection reload
[root@router ~]# nmcli  connection  up eth1
[root@router ~]# nmcli  connection  up eth0
# 启用内核路由功能
[root@router ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@router ~]# sysctl -p
net.ipv4.ip_forward = 1

LVS的配置

# 使用脚本
[root@lvs ~]# vmset.sh eth1 192.168.0.50 lvs.org
# 修改网关为192.168.0.100
[root@lvs ~]#vim /etc/NetworkManager/system-connections/eth1.nmconnection
address1=192.168.0.50/24,192/168/0/100
# 更新网卡
[root@lvs ~]# nmcli connection reload
[root@lvs ~]#nmcli  connection  up eth1
# 在回环接口配置VIP
[root@lvs ~] ip a a 192.168.0.200/32 dev lo
# 下载ipvsadm
[root@lvs ~] yum install ipvsadm -y
# 配置策略
[root@lvs ~]# ipvsadm -A -t 192.168.0.200:80 -s wrr
[root@lvs ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10:80 -g -w 1
[root@lvs ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20:80 -g -w 2
# 查看策略
[root@lvs ~]# ipvsadm -Ln
TCP  192.168.0.200:80 wrr
  -> 192.168.0.10:80              Route   1      0          0
  -> 192.168.0.20:80              Route   2      0          0

 测试:

[root@client ~]# for i in {1..5}
> do
> curl 192.168.0.200
> done
webserver2 - 192.168.0.20
webserver1 - 192.168.0.10
webserver2 - 192.168.0.20
webserver2 - 192.168.0.20
webserver1 - 192.168.0.10

3、基于TUN的LVS负载均衡 (了解即可)

 在LVS(NAT)模式的集群环境中,由于所有的数据请求及响应的数据包都需要经过LVS调度器转发,如果后端服务器的数量大于10台,则调度器就会成为整个集群环境的瓶颈。我们知道,数据请求包往往远小于响应数据包的大小。因为响应数据包中包含有客户需要的具体数据,所以LVS(TUN)的思路就是将请求与响应数据分离,让调度器仅处理数据请求,而让真实服务器响应数据包直接返回给客户端。

特点:

1.DIP, VIP, RIP都应该是公网地址

2.RS的网关一般不能指向DIP

3.请求报文要经由Director,但响应不能经由Director

4.不支持端口映射

5.RS的OS须支持隧道功能

ipvsadm参数详解

选项作用
-A添加一个虚拟服务,使用IP地址、端口号、协议来唯一定义一个虚拟服务
-E编辑一个虚拟服务
-D删除一个虚拟服务
-C清空虚拟服务表
-R从标准输入中还原虚拟服务规则
-S保存虚拟服务规则值标准输出,输出的规则可以使用-R导入还原
-a在虚拟服务中添加一台真实服务器
-e在虚拟服务中编辑一台真实服务器
-d在虚拟服务中减少一台真实服务器
-L显示虚拟服务列表
-t

使用TCP服务,该参数后需要跟主机与端口信息

-u使用UDP服务,该参数会需要跟主机与端口信息
-s 

指定LVS所采用的的调度算法

-r设置真实服务器IP地址与端口信息
-g设置LVS工作模式为DR直连路由模式
-i设置LVS工作模式为TUN隧道模式
-m设置LVS工作模式为NAT地址转换模式
-w设置指定服务器的权重
-c连接状态,需要配合-L使用
-n数字格式输出

三、LVS负载均衡调度算法

1.轮询调度

轮询调度(Round Robin 简称’RR’)算法就是按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点就是实现简单。轮询算法假设所有的服务器处理请求的能力都一样的,调度器会将所有的请求平均分配给每个真实服务器。

2.加权轮询调度

加权轮询(Weight Round Robin 简称’WRR’)算法主要是对轮询算法的一种优化与补充,LVS会考虑每台服务器的性能,并给每台服务器添加一个权值,如果服务器A的权值为1,服务器B的权值为2,则调度器调度到服务器B的请求会是服务器A的两倍。权值越高的服务器,处理的请求越多。

3.最小连接调度

最小连接调度(Least Connections 简称’LC’)算法是把新的连接请求分配到当前连接数最小的服务器。最小连接调度是一种动态的调度算法,它通过服务器当前活跃的连接数来估计服务器的情况。调度器需要记录各个服务器已建立连接的数目,当一个请求被调度到某台服务器,其连接数加1;当连接中断或者超时,其连接数减1。

(集群系统的真实服务器具有相近的系统性能,采用最小连接调度算法可以比较好地均衡负载。)

4.加权最小连接调度

加权最少连接(Weight Least Connections 简称’WLC’)算法是最小连接调度的超集,各个服务器相应的权值表示其处理性能。服务器的缺省权值为1,系统管理员可以动态地设置服务器的权值。加权最小连接调度在调度新连接时尽可能使服务器的已建立连接数和其权值成比例。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。

5.基于局部的最少连接

基于局部的最少连接调度(Locality-Based Least Connections 简称’LBLC’)算法是针对请求报文的目标IP地址的 负载均衡调度,目前主要用于Cache集群系统,因为在Cache集群客户请求报文的目标IP地址是变化的。这里假设任何后端服务器都可以处理任一请求,算法的设计目标是在服务器的负载基本平衡情况下,将相同目标IP地址的请求调度到同一台服务器,来提高各台服务器的访问局部性和Cache命中率,从而提升整个集群系统的处理能力。LBLC调度算法先根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则使用’最少连接’的原则选出一个可用的服务器,将请求发送到服务器。

6.带复制的基于局部性的最少连接

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

7.目标地址散列调度

目标地址散列调度(Destination Hashing 简称’DH’)算法先根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且并未超载,将请求发送到该服务器,否则返回空。

8.源地址散列调度U

源地址散列调度(Source Hashing 简称’SH’)算法先根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且并未超载,将请求发送到该服务器,否则返回空。它采用的散列函数与目标地址散列调度算法的相同,它的算法流程与目标地址散列调度算法的基本相似。

9.最短的期望的延迟

最短的期望的延迟调度(Shortest Expected Delay 简称’SED’)算法基于WLC算法。举个例子吧,ABC三台服务器的权重分别为1、2、3 。那么如果使用WLC算法的话一个新请求进入时它可能会分给ABC中的任意一个。使用SED算法后会进行一个运算

A:(1+1)/1=2 B:(1+2)/2=3/2 C:(1+3)/3=4/3 就把请求交给得出运算结果最小的服务器。

10.最少队列调度

最少队列调度(Never Queue 简称’NQ’)算法,无需队列。如果有realserver的连接数等于0就直接分配过去,不需要在进行SED运算。

         

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐