负载均衡集群
负载均衡集群指使用多台提供相同服务的服务器组成集群系统,提高服务的并发处理能力。负载均衡集群的前端使用一个调度器,将客户端请求平均分配到后端的服务器中,同时调度器可能还具有后端服务器状态检测的功能,将故障的服务器自动下线,使得集群具有一定的容错能力。
使用负载均衡集群能够有效的扩展服务的并发能力,负载均衡集群中的主机间应该尽量的「低耦合」,最好是「无状态」的,这样就能够方便的增加主机实现扩展。
常见的负载均衡器
根据工作在的协议层划分可划分为:
- 四层负载均衡:根据请求报文中的目标地址和端口进行调度
- 七层负载均衡:根据请求报文的内容进行调度,这种调度属于「代理」的方式
根据软硬件划分:
硬件负载均衡:
- F5 的 BIG-IP
- Citrix 的 NetScaler
- 这类硬件负载均衡器通常能同时提供四层和七层负载均衡,但同时也价格不菲
软件负载均衡: - TCP 层:LVS,Haproxy,Nginx
- 基于 HTTP 协议:Haproxy,Nginx,ATS(Apache Traffic Server),squid,varnish
- 基于 MySQL 协议:mysql-proxy
LVS
LVS 是一个工作在四层的负载均衡器,它的实现和 iptables/netfilter 类似,工作在内核空间的 TCP/IP 协议栈上,LVS 工作在 INPUT Hook Funtion 上,并在 INPUT 设置附加规则,一旦客户端请求的是集群服务,LVS 会强行修改请求报文,将报文发往 POSTROUTING,转发至后端的主机。
和 iptables/netfilter 类似,LVS 也是两段式的:
- ipvsadm:工作在用户空间,负责定义和管理集群服务的规则
- ipvs:工作在内核中,在 2.4.23 之前,必须向内核打补丁,并重新编译内核。在 2.4.23 和 2.6 之后的版本,ipvs 直接内置在内核中。
LVS 集群的设备地址命名
- VIP:Virtual IP,LVS 面向用户请求的 IP 地址
- RIP:Real server IP,后端服务器用于和 LVS 通信的 IP 地址
- DIP:Director IP,LVS 用户和后端服务器通信的 IP 地址
- CIP:Client IP,客户端 IP 地址
LVS 的工作模型
LVS-NAT
LVS-NAT 模型类似于 DNAT,工作机制与 DNAT 一样,当客户端请求的是集群服务时,LVS 修改请求报文的目标地址为 RIP,转发至后端的 RealServer,并修改后端响应报文的源地址为 VIP,响应至客户端。
在 LVS-NAT 模型下,Director 进出请求报文都经过 Director,因此 Director 的压力是比较大的。
LVS-NAT 的特性:
- 集群节点跟 Director 必须在同一个 IP 网络中
- RIP 通常是私有地址,仅用于各集群节点间的通信
- Director 位于 client 和 Realserver 之间,负责处理进出的所有报文
- Realserver 必须将网关指向 DIP
- 支持端口映射
- 较大规模应用场景中,Director 易成为系统瓶颈(bottleneck),扩展有限最多20台
LVS-DR
DR 值 Direct Routing,直接路由,DR 模型中,Director 和 Realserver 处在同一网络中,对于 Director,VIP 用于接受客户端请求,DIP 用于和 Realserver 通信。对于 Realserver,每个 Realserver 都配有和 Director 相同的 VIP(此 VIP 隐藏,关闭对 ARP 请求的响应),仅用户响应客户端的请求,RIP 用于和 Director 通信。
当客户端请求集群服务时,请求报文发送至 Director 的 VIP(Realserver的 VIP 不会响应 ARP 请求),Director 将客户端报文的源和目标 MAC 地址进行重新封装,将报文转发至 Realserver,Realserver 接收转发的报文。此时报文的源 IP 和目标 IP 都没有被修改,因此 Realserver 接受到的请求报文的目标 IP 地址为本机配置的 VIP,它将使用自己的 VIP 直接响应客户端。
LVS-DR 模型中,客户端的响应报文不会经过 Director,因此 Director 的并发能力有很大提升。
LVS-DR 模型的特性:
- 保证前端路由器将目标地址为 VIP 的报文通过 ARP 解析后送往 Director。
- 静态绑定:在前端路由将 VIP 对应的目标 MAC 地址静态配置为Director VIP 接口的 MAC 地址。
- arptables:在各 Realserver 上,通过 arptables 规则拒绝其响应对 VIP 的 ARP 广播请求
- 修改内核参数:在 Realserver 上修改内核参数,并结合地址的配置方式实现拒绝响应对 VIP 的 ARP 广播请求
- 各RIP 必须与 DIP 在同一个物理网络中
- RS 的 RIP 可以使用私有地址,也可以使用公网地址,以方便配置
- Director 仅负责处理入站请求,响应报文由 Realserver 直接发往客户端
- Realserver 不能将网关指向 DIP,而直接使用前端网关
- 不支持端口映射
由于数据返回不走director ,而是直接由 realserver返回给用户。所认其承载能力比较强,单台lvs dr模式下后端负载的realserver 数量可以达到100台。不过也因为其比较简单,只有四层处理能力,所以其无法对后端server 的健康状态做检查。
LVS-TUN
和 DR 模型类似,Realserver 都配有不可见的 VIP,Realserver 的 RIP 是公网地址,且可能和 DIP 不再同一网络中。当请求到达 Director 后,Director 不修改请求报文的源 IP 和目标 IP 地址,而是使用 IP 隧道技术,使用 DIP 作为源 IP,RIP 作为目标 IP 再次封装此请求报文,转发至 RIP 的 Realserver 上,Realserver 解析报文后仍然使用 VIP 作为源地址响应客户端。
LVS-TUN 的特性:
- 集群节点和可以跨越 Internet
- RIP,DIP,VIP 都是公网地址
- Director 仅负责处理入站请求,响应报文由 Realserver 直接发往客户端
- Realserver 使用自己的网关而不是 Director
- Realserver 只能使用支持隧道功能的操作系统
- 不支持端口映射
LVS-FULLNAT
FULLNAT 由淘宝研发,目前还没有加入至 CentOS 可用的内核中,使用时需要向内核打补丁。
类似于 DNAT,它修改请求报文的源地址为 DIP,目标地址为 RIP 来实现转发。对于响应报文,源地址修改为 VIP,目标地址修改为 CIP 来实现转发。
特点:
- RIP,DIP 可以使用私有地址
- RIP 和 DIP 可以不再同一网络中,且 RIP 的网关不需要指向 DIP
- 支持端口映射
- 请求和响应报文都经由 Director
LVS 的调度算法
当 LVS 接受到一个客户端对集群服务的请求后,它需要进行决策将请求调度至某一台后端主机进行响应。LVS 的调度算法共有 10 种,按类别可以分为动态和静态两种类型。
静态调度算法
静态调度算法调度时不会考虑后端服务器的状态
- rr:round robin,轮询,即简单在各主机间轮流调度
- wrr:weighted round robin,加权轮询,根据各主机的权重进行轮询
- sh:source hash,源地址哈希,对客户端地址进行哈希计算,保存在 Director 的哈希表中,在一段时间内,同一个客户端 IP 地址的请求会被调度至相同的 Realserver。sh 算法的目的是实现 session affinity(会话绑定),但是它也在一定程度上损害了负载均衡的效果。如果集群本身有 session sharing 机制或者没有 session 信息,那么不需要使用 sh 算法
- dh:destination hash,和 sh 类似,dh 将请求的目标地址进行哈希,将相同 IP 的请求发送至同一主机,dh 机制的目的是,当 Realserver 为透明代理缓存服务器时,提高缓存的命中率。
动态调度算法
动态调度算法在调度时,会根据后端 Realserver 的负载状态来决定调度选择,Realserver 的负载状态通常由活动链接(active),非活动链接(inactive)和权重来计算。
- lc:least connted,最少连接,LVS 根据 overhead = active*256 + inactive 计算服务器的负载状态,每次选择 overhead 最小的服务器
- wlc:weighted lc,加权最少连接,LVS 根据 overhead = (active*256+inactive)/weight 来计算服务器负载,每次选择 overhead 最小的服务器,它是 LVS 的默认调度算法
- sed:shortest expected delay,最短期望延迟,它不对 inactive 状态的连接进行计算,根据 overhead = (active+1)*256/weight 计算服务器负载,选择 overhead 最小的服务器进行调度
- nq:never queue,当有空闲服务器时,直接调度至空闲服务器,当没有空闲服务器时,使用 SED 算法进行调度
- LBLC:locality based least connection,基于本地的最少连接,相当于 dh + wlc,正常请求下使用 dh 算法进行调度,如果服务器超载,则使用 wlc 算法调度至其他服务器
- LBLCR:locality based least connection with replication,基于本地的带复制功能的最少连接,与 LBLC 不同的是 LVS 将请求 IP 映射至一个服务池中,使用 dh 算法调度请求至对应的服务池中,使用 lc 算法选择服务池中的节点,当服务池中的所有节点超载,使用 lc 算法从所有后端 Realserver 中
IPVSADM
ipvsadm 用于配置 LVS 的调度规则,管理集群服务和 Realserver
管理集群服务
1 | 添加:-A -t|u|f service-address [-s scheduler] |
管理集群服务中的 RS
1 | 添加:-a -t|u|f service-address -r server-address [-g|i|m] [-w weight] |
查看规则
1 | -L|-l |
删除所有集群服务
1 | -C:清空 ipvs 规则 |
保存规则
1 | -S |
载入保存的规则
1 | -R |
DR 模型的配置
DR 模型的 Realserver 禁止 ARP 响应
对于 Linux 来说,地址是属于主机的,Linux 主机在开机时会通告连接所有网络内的所有其他主机自己的所有 ip 地址和 mac 地址。
可以利用 Linux 的特性,将VIP配置在 Realserver 的本地回环接口上作为别名,并使用 arp_ignore 和 arp_annouce 内核参数。
禁止 ARP 响应的方式
arptables:红帽系类系统上提供的程序
修改内核参数:
arp_ignore:定义接收到 ARP 请i去时的响应级别
- 0:只要本地配置有响应地址,就给与响应
- 1:仅在请求的目标地址配置请i去到达的接口上的时候,才进行响应
arp_announce:定义主机将自己的地址想外通告时的通告级别
- 0:将本地任何接口上的任何地址向外通告
- 1:向目标网络通告与其网络匹配的地址
- 2:仅向本地接口上匹配的网络进行通告
添加特殊的路由条目 Linux 主机在使用某一接口发出报文时,默认会使用此接口的 IP 作为源 IP 地址。
当请求 Realserver 时,Realserver 的 VIP 是 lo 接口的别名,而 VIP 对外的通信实际需要使用的却是 eth0 接口,因此需要添加路由条目,让主机在使用 VIP 向外通信时,强制使用 lo 端口,因而它会使用 lo 端口的地址作为源 IP 进行响应,并最终由 lo 接口转发至 eth0 接口发出报文。1
/sbin/route add -host $VIP dev lo:0
持久连接
添加一个集群服务为192.168.10.10:80,使用的调度算法为wrr,持久连接的保持时间是3600秒。当超过3600秒都没有请求时,则清空LVS的持久连接模板。这里我们可以在上面的策略后面加其他服务,指向其他realserver服务器 。1
ipvsadm -A -t 192.168.10.10:80 -s wrr -p 3600
LVS_NAT配置
准备工作
时间同步
director服务器:VIP 192.168.10.10 DIP 192.168.10.100
RS1服务器:RIP 192.168.10.101 GATEWAY 192.168.10.100
RS2服务器:RIP 192.168.10.102 GATEWAY 192.168.10.100
客户端主机:CIP 192.168.10.251
director服务器操作
1 | yum install ipvsadm -y |
1 |
|
防火墙的一些操作1
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j MASQUERADE
注:
1、使用NAT模式必须要开启路由转发;
2、禁用发送ICMP ipv4重定向消息主要是出于安全考虑,并不影响ping检测;
3、ipvsadm 这里使用的是Round Robin轮询算法,-m 参数是指定使用的masquerading nat模式,-w 参数是指定权重,在 rr算法下,指定权重是没意义的,因为两台主机的的权重是一样的,每台主机都是公平平均轮询的。-p 3600 持久连接
RS1服务器操作
1 | yum install -y nginx |
注:需将在两台 RS 上设置网关的 IP 为 director 的内网 IP。
RS2服务器操作
1 | yum install -y nginx |
客户端操作
1 | [root@sunday ~]# curl http://192.168.10.10 |
1 | director操作 |
LVS_DR配置
director操作
1 | yum install ipvsadm -y |
1 | #!/bin/sh |
rs1 rs2操作
1 |
|
LVS_TUN
director主机
1 | #!/bin/sh |
RS1-3主机
1 |
|
健康检测
在LVS模型中,director不负责检查RS的健康状况,这就使得当有的RS出故障了,director还会将服务请求派发至此服务器 。为实现像F5这样专业的LB设备的功能,LVS可以与ldirectord工具结合,自动屏蔽后端异常的服务器。也可以通过简单的脚本来实现后端健康检查,当curl获取后端某服务器的状态发现不对时,自动通过ipvsadm命令将该服务器删除。正常时同样通过ipvsadm命令加入。由于本篇暂时还未跳出LVS工具本身,所以这里通过脚本实现后端健康检查。脚本内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
VIP=192.168.10.100
CPORT=80
BACKUP=127.0.0.1
STATUS=("1""1")
RS=("192.168.10.101" "192.168.10.101")
RW=("2" "1")
RPORT=80
TYPE=g
while:; do
letCOUNT=0
add() {
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2
[ $? -eq0 ] && return0 || return1
}
del() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT
[ $? -eq0 ] && return0 || return1
}
for I in${RS[*]}; do
if curl --connect-timeout 1 http://$I &> /dev/null; then
if[ ${STATUS[$COUNT]} -eq 0 ]; then
add $I ${RW[$COUNT]}
[ $? -eq 0 ] && STATUS[$COUNT]=1
fi
else
if[ ${STATUS[$COUNT]} -eq 1 ]; then
del $I
[ $? -eq0 ] && STATUS[COUNT]=0
fi
fi
letCOUNT++
done
sleep 5
done
http://www.361way.com/lvs-nat/5187.html
http://www.361way.com/lvs-dr/5192.html
http://www.361way.com/lvs-persistent-healthy-check/5204.html
http://liaoph.com/lvs/