lvs三种模式和调度算法
# 概述
负载均衡架构:在负载均衡架构中,Director(dispatcher)负责接收客户端请求,并将请求按照某种算法分发到后台真正提供服务的服务器上。既可以基于硬件(F5)来实现,也可以基于软件来实现。基于软件实现的又分为四层交换:基于 IP 地址和端口号组合起来对服务做重定向(LVS)。七层交换:通常指的是反向代理(proxy),例如 squid 等。而真正提供 Web 服务的服务器称为 Real Server,每个服务器称为一个节点。
# LVS (Linux Virtual Server)
LVS 类似于 iptables 的架构,在内核中有一段代码用于实时监听数据包来源的请求,当数据包到达端口时做一次重定向,这一系列的工作必须在内核中实现。在内核中实现数据包请求处理的代码叫做 ipvs。
ipvs 仅仅提供了功能框架,还需要自己手动定义是数据对哪个服务的请求,而这种定义需要通过写规则来实现,写规则的工具就称为ipvsadm。
LVS 的目标 :使用集群技术和 Linux 操作系统实现一个高性能、高可用的服务器,它具有很好的可伸缩性(Scalability)、可靠性(Reliability)和可管理性 (Manageability)。
LVS 负载均衡架构
关于几个 IP 地址的解释:
Virtual IP(VIP):Director 用来向客户端提供服务的 IP 地址;
Real IP (RIP):集群节点(后台真正提供服务的服务器)所使用的 IP 地址;
Director's IP (DIP):Director 用来和 D/RIP 进行通信的地址;
Client computer's IP (CIP):公网 IP,客户端使用的 IP 地址。
# LVS 三种模式
根据前端 Director 和后台 Real Server 的通信方式将 LVS 分为三类:
- Network Address Translation(LVS-NAT)
- Director routing (LVS-DR )
- IP tunneling(LVS-TUN )
# LVS-NAT
Virtual Server via Network Address Translation(LVS-NAT):通过网络地址转换,Director 重写请求报文的目标地址,根据预设的调度算法,将请求分派给后端的 Real Server;Real Server 的响应报文通过 Director 时,报文的源地址被重写,再返回给客户,完成整个负载调度过程。
目标地址转换,即所有客户端的请求都被 Director 根据访问请求和算法被定向到后台的 Real Server 上,后台的 Real Server 回应客户端的数据包也要经过 Director返回给客户端。如图所示,数据包地址转换过程:
S:CIP D:VIP---->Director---->S:CIP D:RIP---->Real Server
Real Server---->S:RIP D:CIP---->Director---->S:VIP D:CIP
LVS-NAT 特性:
- 1〉Director 和 Real Server 必须在同一个网段中;
- 2〉一般情况下,RIP 是私有地址,只用于集群内部节点间通信;
- 3〉Director 会响应所有的请求在客户端和 Real Server 之间,所承担的负载较大;
- 4〉所有的 Real IP 网关必须指向 DIP 以响应客户端请求;
- 5〉Director 可以重映射网络端口,即前端使用标准端口,后端使用非标准端口;
- 6〉后台的 Real Server 可以使用任何操作系统;
- 7〉Director 可能会成为系统瓶颈。
LVS-NAT 集群的设计及实现
LVS-NAT 网络架构如图所示,环境搭建如下:
Director :
- VIP 192.168.0.127 桥接;
- DIP 192.168.10.1 仅主机
Real Server 1:
RIP 192.168.10.2 仅主机 网关指向:192.168.10.1,提供 Web 服务,测试页内容为 Web1
Real Server 2:
RIP 192.168.10.3 仅主机 网关指向:192.168.10.1,提供 Web 服务,测试页内容为 Web2
Client:192.168.0.1 物理机
Real Server 1:
[root@station39 html]# ifconfig eth0 192.168.10.2 //为 eth0 设置 IP 地址;
[root@station39 html]# route add default gw 192.168.10.1 //添加网关;
2
Real Server 2:
[root@station26 html]# ifconfig eth0 192.168.10.3 //同上;
[root@station26 html]# route add default gw 192.168.10.1 //同上;
2
Director:
[root@server27 ~]# ifconfig eth1 192.168.10.1 //为 Director 设置 DIP;
[root@server27 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward //开启内核路由功能;
[root@server27 ~]# vim /etc/sysctl.conf //修改内核参数,确保永久有效;
net.ipv4.ip_forward = 1
[root@server27 ~]# sysctl -p //查看内核参数;
net.ipv4.ip_forward = 1
2
3
4
5
6
准备工作已经配置完毕,开始 LVS-NAT 的配置:
[root@server27 ~]# yum install ipvsadm -y //安装 ipvsadm 工具;
[root@server27 ~]# ipvsadm -A -t 192.168.0.127:80 -s rr //定义服务,设定算法
2
为服务添加 Real Server 并设置权重:
[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.10.2 -m -w 2
[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.10.3 -m -w 5
[root@server27 ~]# ipvsadm -Ln //查看服务状态;
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.127:80 rr
-> 192.168.10.3:80 Masq 5 0 16
-> 192.168.10.2:80 Masq 2 0 15
2
3
4
5
6
7
不同算法的测试效果
此时,我们使用物理机访问 http:192.168.0.127 就会发现页面出现交替变化的情况,这是由 RR 算法的特性决定的。我们改变为 WRR 算法试试:
[root@server27 ~]# ipvsadm -E -t 192.168.0.127:80 -s wrr //改为 WRR 调度算法;
[root@server27 ~]# ipvsadm -Ln
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.127:80 wrr
-> 192.168.10.3:80 Masq 5 0 86
-> 192.168.10.2:80 Masq 2 0 43
2
3
4
5
6
改变为 LBLC 算法:
[root@server27 ~]# ipvsadm -E -t 192.168.0.127:80 -s lblc
6
[root@server27 ~]# ipvsadm -Ln
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.127:80 lblc
-> 192.168.10.3:80 Masq 5 0 112
-> 192.168.10.2:80 Masq 2 0 41
2
3
4
5
6
7
此时会发现无论客户端怎么刷新,访问页面都不会改变,这是由 LBLC 调度算法所决定的。
# LVS-DR
Virtual Server via Direct Routing(LVS-DR):通过改写请求报文的 MAC 地址,将请求发送到 Real Server,而 Real Server 将响应直接返回给客户。同 LVS-TUN 技术一样,LVS-DR 技术可极大地提高集群系统的伸缩性。
这种方法没有 IP 隧道的开销,对集群中的真实服务器也没有必须支持 IP 隧道协议的要求,但是要求 Director 与 Real Server 都有一块网卡连 在同一物理网段上。
直接路由就是客户端请求经过 Director 分发给 Real Server 后,Real Server 直接回应客户端。如图所示,数据包地址转换过程:
S:CIP D:VIP---->Director---->S:CIP
D:RIP ----> Real Server----> S:VIP D:CIP
LVS-DR 特性:
- 1〉Real Server 上必须配置 VIP 切需要隐藏起来,只有在响应客户端请求时才使用VIP 作为源地址,除此之外并不使用此 VIP;
- 2〉集群节点和 Director 必须在同一个网络中;
- 3〉RIP 不要求为私有地址;
- 4〉Director 仅处理所有进来的请求;
- 5〉Real Server 不能以 DIP 作为网关,而是以公网上的某台路由器作为网关;
- 6〉Director 不能再使用端口重映射;
- 7〉大多数操作系统可以被用来作为 Real Server,windows 除外;
- 8〉LVS-DR 模式可以处理比 LVS-NAT 更多的请求。
LVS-DR 为实际生产环境中最常用的一种方式,因为 RIP 为公网地址,管理员可以远程连接 Real Server 来查看工作状态;一旦 Director 宕机,可以通过修改 DNS 记录将 A 记录指向 RIP 继续向外提供服务。
Director 分发到 Real Server 的过程中,数据包的源地址和目标地址都没有发生改变,Director 仅仅是将目标 mac 地址转换成某台 Real Server 的 mac 地址,源 mac 地址改为 Director 内网网卡的 mac 地址。
这里要解决的两个技术难题:
1> Real Server 要避免回应客户端发来的对 VIP 的 arp 地址解析请求; 解决方法:
(1) 修改内核的两个参数:arp_announce, arp_ignore;
① arp_announce :定义不同级别:当 ARP 请求通过某个端口进来是否利用这个接口来回应;
0 默认级别,利用本地的任何地址,不管配置在哪个接口上去响应 ARP 请求;
1 避免使用另外一个接口上的 mac 地址去响应 ARP 请求;
2 尽可能使用能够匹配到 ARP 请求的最佳地址。
② arp_ignore:当 ARP 请求发过来后发现自己正是请求的地址是否响应;
0 默认级别,利用本地的任何地址,不管配置在哪个接口上去响应 ARP 请求;
1 哪个接口上接受 ARP 请求,就从哪个端口上回应。
(2) Red Hat 系统提供了 arptables 工具,利用 arp 防火墙也可以实现。
2> 当 Real Server 内网网卡响应客户端请求时,要以 VIP 作为源地址,不能以 RIP作为源地址。解决方法:添加一条路由
route add -host 192.168.0.127 dev lo:0
1使客户端访问 VIP,就让 VIP 来响应客户端。这样避免了使用 RIP 作为源地址。
LVS-DR 集群架构的设计与实现
LVS-DR 网络架构如图所示:
环境搭建如下:
Director :
- eth0:0 VIP 192.168.0.127
- eth0 DIP 192.168.0.10 桥接
Real Server 1:
- eth0 RIP 192.168.0.12 桥接
- lo:0 VIP 192.168.0.127
- 提供 Web 服务,测试页内容为 Web1
Real Server 2:
- eth0 RIP 192.168.0.13 桥接
- lo:0 VIP 192.168.0.127
- 提供 Web 服务,测试页内容为 Web2
Client:192.168.0.1 物理机
Real Server 1:
[root@station39 ~]# vim /etc/sysctl.conf //修改内核参数,避免回应客户端发来的对 VIP 的 arp 地址解析请求;
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
[root@station39 ~]# sysctl -p //显示内核参数;
[root@station39 ~]# ifconfig eth0 192.168.0.12/24 //设置 IP 地址 RIP;
[root@station39 ~]# ifconfig lo:0 192.168.0.127 broadcast 192.168.0.127 netmask 255.255.255.255 // 设置 VIP;
[root@station39 ~]# route add -host 192.168.0.127 dev lo:0 //添加路由;
2
3
4
5
6
7
8
9
Real Server 2 网卡 eth0 的地址为 192.168.0.13,服务的设置方法同 Real Server 1 一致。
Director:
[root@server27 ~]# ifconfig eth0 192.168.0.10/24 //设置 DIP;
[root@server27 ~]# ifconfig eth0:0 192.168.0.127 broadcast 192.168.0.127 netmask 255.255.255.255 //设置 VIP;
[root@server27 ~]# route add -host 192.168.0.127 dev eth0:0 // 添加路由;
[root@server27 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward //开启内核路由功能;
[root@server27 ~]# ipvsadm -C //清空规则;
[root@server27 ~]# ipvsadm -A -t 192.168.0.127:80 -s wlc //添加服务,设定调
度算法;
2
3
4
5
6
7
添加 Real Server:
[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.0.12 -g -w 5
[root@server27 ~]# ipvsadm -a -t 192.168.0.127:80 -r 192.168.0.13 -g -w 8
2
测试结果
使用物理机浏览器访问 http://192.168.0.127,查看服务状态,就可以看到两台Real Server 的非活动连接数之比近似于 5:8,这是由分配的权重所决定的。
[root@server27 ~]# ipvsadm -Ln //查看服务状态;
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.127:80 wlc
-> 192.168.0.13:80 Route 8 0 18
-> 192.168.0.12:80 Route 5 0 11
2
3
4
5
# LVS-TUN
Virtual Server via IP Tunneling(LVS-TUN):采用 NAT 技术时,由于请求和响应报文都必须经过 Director 地址重写,当客户请求越来越多时,Director 的处理能力将成为瓶颈。为了解决这个问题,Director 把请求报文通过 IP 隧道转发至 Real Server,而 Real Server 将响应直接返回给客户,所以Director 只处理请求报文。由于一般网络服务应答比请求报文大许多,采用 LVS-TUN技术后,集群系统的最大吞吐量可以提高10倍。
LVS-TUN模式与LVS-DR的网络结构一样,但 Director 和 Real Server 可以在不同的网络当中,可以实现异地容灾的功能。数据包从 Director 到 Real Server 过程中是基于隧道来传输,在数据包外层额外封装了 S:DIP D:RIP 的地址。
LVS-TUN 特性:
- 1〉Director 和 Real Server 不需要在同一个物理网络中;
- 2〉RIP 一定不能是私有地址;
- 3〉Director 只负责处理进来的数据包;
- 4〉Real Server直接将数据包返回给客户端,所以Real Server默认网关不能是DIP,必须是公网上某个路由器的地址;
- 5〉Director 不能做端口重映射;
- 6〉只有支持隧道协议的操作系统才能作为 Real Server。
# LVS 调度算法
# 固定调度算法
- 按照某种既定的算法,不考虑实时的连接数予以分配: Round-robin(RR)轮询:将外部请求按顺序轮流分配到集群中的 Real Server,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载;
- Weighted round-robin(WRR)加权轮询:给每台 Real Server 分配一个权重/位列,权重越大,分到的请求数越多;
- Destination hashing (DH)目标散列:根据请求的目标 IP 地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。来自于同一个 IP 地址的请求都被重定向到同一台 Real Server 上,保证目标地址不变;
- Source hashing(SH)源地址散列:根据请求的源 IP 地址,作为散列键(HashKey)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。Director 必须确保响应的数据包必须通过请求数据包所经过的路由器或者防火墙,保证原地址不变。
# 动态调度算法
通过检查服务器上当前连接的活动状态来重新决定下一步调度方式该如何实现:
- Lease Connection (LC) 最少连接,哪一个Real Server上的连接数少就将下一个连接请求定向到那台Real Server上去。算法实现:连接数=活动连接数*256+非 活动连接数;
- Weight Least-Connection(WLC) 加权最少连接,在最少连接的基础上给每台Real Server分配一个权重。算法实现:连接数=(活动连接数*256+非活动连接数)÷权重,是一种比较理想的算法;
- Shortest Expected Delay (SED) 最短期望延迟,不再考虑非活动连接数,算法实现:连接数=(活动连接数+1) *256 ÷权重;
- Never Queue (NQ) 永不排队算法,对 SED 的改进,当新请求过来的时候不仅要取决于 SED 算法所得到的值,还要取决于 Real Server 上是否有活动连接;
- Locality-Based Least-Connection (LBLC) 基于本地状态的最少连接,在DH 算法的基础上还要考虑服务器上的活动连接数;
- Locality-Based Least-Connection with Replication Scheduling(LBLCR) 带复制的基于本地的最少连接,是 LBLC 算法的改进。
# LVS 持久性
尽管我们选择了 LVS 的分发方法,但是大多时候我们要保证返回给客户端的所有响应请求必须来自于同一台 Real Server,这里我们就要用到 LVS Persistence(持久性)。当使用 SSL 会话的时候,我们常常期望只交换一次密钥就可以建立永久连接,因此,LVS持久性在 SSL 会话中经常被用到。
使用 LVS 持久性的时候,Director 在内部使用一个连接根据记录称之为“持久连接模板”来确保所有来自同一个客户端的请求被分发到同一台 Real Server 上。
LVS 持久性类型分为:
- PCC
- PPC
- PNMP
- 混合类型
# PCC
PCC(Persistent client connections):来自同一客户端所有服务的请求都被重定向到同一台 Real Server 上,以 IP 地址为准。PCC 是一个虚拟服务没有端口号(或者端口号为 0),以"-p" 来标识服务。
缺点是定向所有服务,期望访问不同的 Real Server 无法实现。
假设一个用户在访问购物网站时同时使用 HTTP(80)和 HTTPS(443)两种协议,就需要这样定义:
ipvsadm -A -t 192.168.0.220:0 -s rr -p
ipvsadm -a -t 192.168.0.220:0 -r 192.168.10.11 -m
ipvsadm -a -t 192.168.0.220:0 -r 192.168.10.11 -m
2
3
# PPC
PPC(Persistent port connections):来自同一服务的请求都被重定向到同一台 Real Server 上,以端口号为准。例如:
- client---->LVS(80,22)---->RS1
- client---->LVS(23)---->RS2
缺陷:期望访问不同的端口到同一台 RS 上,无法实现。
# PNMP
PNMP(Persistent Netfilter Marked Packet persistence):根据 iptables 的规则,将对于某类服务/几个不同端口的访问定义为一类。具体过 程是先对某一特定类型的数据包打上标记,然后再将基于某一类标记的服务送到后台的Real Server 上去,后台的 Real Server 并不识别这些标记。
由于 LVS-DR 模型作了网卡别名,所以并不适合 PNMP,因此 PNMP 只能用在 LVS-NAT模式下。
[root@server27 ~]# iptables -t mangle -A PREROUTING -i eth0 -d 192.168.0.127
-p tcp --dport 80 -j MARK --set-mark 2
[root@server27 ~]# ipvsadm -A -f 2 -s wlc -p 3600
[root@server27 ~]# ipvsadm -a -f 2 -r 192.168.10.2 -m -w 2
[root@server27 ~]# ipvsadm -a -f 2 -r 192.168.10.3 -m -w 5
2
3
4
5