一、Linux Virtual Server简介
LVS介绍
- LVS:Linux Virtual Server,负载调度器,内核集成,章文嵩(花名 正明), 阿里的四层SLB(Server Load Balance)是基于LVS+keepalived实现。
- LVS 官网:https://www.linuxvirtualserver.org/
- LVS 相关术语
- VS: Virtual Server,负责调度
- RS: Real Server,负责真正提供服务
LVS工作原理
VS根据请求报文的目标IP和目标协议及端口将其调度转发至某RS,根据调度算法来挑选RS。LVS是内核级功能,工作在INPUT链的位置,将发往INPUT的流量进行“处理”
查看内核支持LVS
[root@localhost ~]# grep -i -C 10 ipvs /boot/config-3.10.0-957.el7.x86_64
LVS集群体系架构
LVS 功能及组织架构
下面摘自于阿里云:https://help.aliyun.com/document_detail/27543.html?spm=5176.21213303.J_6028563670.7.505a3edaQq9WLJ&scm=20140722.S_help%40%40%E6%96%87%E6%A1%A3%40%4027543.S_0.ID_27543-OR_s%2Bhelpproduct-V_1-P0_0
负载均衡的应用场景为高访问量的业务,提高应用程序的可用性和可靠性。
应用于高访问量的业务
如果您的应用访问量很高,可以通过配置监听规则将流量分发到不同的云服务器 EC(ElasticCompute Service 弹性计算服务)实例上。此外,可以使用会话保持功能将同一客户端的请求转发到同一台后端ECS
扩展应用程序
可以根据业务发展的需要,随时添加和移除ECS实例来扩展应用系统的服务能力,适用于各种Web服务器和App服务器。
消除单点故障
可以在负载均衡实例下添加多台ECS实例。当其中一部分ECS实例发生故障后,负载均衡会自动屏蔽故障的ECS实例,将请求分发给正常运行的ECS实例,保证应用系统仍能正常工作,LVS自身做不到,需要配合keepalive软件。
同城容灾(多可用区容灾)
为了提供更加稳定可靠的负载均衡服务,阿里云负载均衡已在各地域部署了多可用区以实现同地域容灾。当主可用区出现机房故障或不可用时,负载均衡仍然有能力在非常短的时间内(如:大约30s中断)切换到另外一个备可用区恢复服务能力;当主可用区恢复时,负载均衡同样会自动切换到主可用区提供服务。
使用负载均衡时,您可以将负载均衡实例部署在支持多可用区的地域以实现同城容灾。此外,建议您结合自身的应用需要,综合考虑后端服务器的部署。如果您的每个可用区均至少添加了一台ECS实例,那么此种部署模式下的负载均衡服务的效率是最高的。
如下图所示,在负载均衡实例下绑定不同可用区的ECS实例。正常情况下,用户访问流量将同时转至发主、备可用区内的ECS实例;当可用区A发生故障时,用户访问流量将只转发至备可用区内的ECS实例。此种部署既可以避免因为单个可用区的故障而导致对外服务的不可用,也可以通过不同产品间可用区的选择来降低延迟。
如果您采取如下图所示的部署方案,即在负载均衡实例的主可用区下绑定多台ECS实例,而在备可用区没有任何ECS实例。当主可用区发生故障时会造成业务中断,因为备可用区没有ECS实例来接收请求。这样的部署方式很明显是以牺牲高可用性为代价来获取低延时。
跨地域容灾
您可以在不同地域下部署负载均衡实例,并分别挂载相应地域内不同可用区的ECS。上层利用云解析做智能DNS,将域名解析到不同地域的负载均衡实例服务地址下,可实现全局负载均衡。当某个地域出现不可用时,暂停对应解析即可实现所有用户访问不受影响
LVS应用场景
音视频/游戏等大并发流量场景
音视频/游戏等行业经常面临突发访问,海量流量,后端服务压力大。如短视频/长视频/直播/在校教育/游戏等业务中,由于服务端与用户端之间需要实时大量的互动,因此,用户流量非常大,而音视频业务的波峰波谷效应明显,这对整个系统的性能、弹性、稳定性和可用性带来了巨大的挑战,需要使用负载均衡进行流量分发
零售/金融/企业等弹性高可靠场景
新零售新金融业务变化快,新业务上线、老业务调整时常发生,大促大型活动常态化;因此,对即开即用网络,快速交付能力,弹性伸缩能力,安全可靠、灵活计费等需求显著,需要使用负载均衡搭建高可靠架构。
云原生网络应用场景
云:指的是远在天边,不是说是虚拟的,是有真实服务器存在的
传统mysql
单机部署(多实例),存储和计算能力都是一体
有单机性能瓶颈 500G 16c
云原生
都使用云的技术 云存储 云服务器
tdsql -c 块存储 计算节点(通过网络的形式连接到存储)
随着云原生逐步成熟,互联网/金融/企业等诸多行业新建业务时选择云原生部署,或对现有业务进行云原生化改造。无论是使用阿里云ACK/ASK/SAE还是开源K8S,云原生网络均可用到负载均衡服务来实现流量调度。
跨地域网络应用场景
跨地域跨可用区的容灾方案。互联网/金融/企业等业务逐步遍及全球,需要将不同地域用户智能调度访问到相应的业务系统,为了降本增效,线下IDC业务需要与云上业务互通,需要使用负载均衡构建跨地域或混合云容灾架构。
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
访问流程:CIP <–> VIP == DIP <–> RIP
二、LVS 工作模式和相关命令
LVS极强的工作模式
lvs-nat:修改请求报文的目标IP,多目标IP的DNAT
lvs-dr:操纵封装新的MAC地址。MAC头的修改
lvs-tun:在原请求IP报文之外新加一个IP首部。
lvs-fullnat:修改请求报文的源和目标IP
LVS 的NAT模式
lvs-nat:本质是多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和PORT实现转发
- RIP和DIP应在同一个IP网络,且应使用私网地址;RS的网关要指向DIP
- 请求报文和响应报文都必须经由Director转发,Director易于成为系统瓶颈
- 支持端口映射,可修改请求报文的目标PORT
- VS必须是Linux系统,RS可以是任意OS系统
LVS的DR模式
LVS-DR:Direct Routing,直接路由,LVS默认模式,应用最广泛,通过为请求报文重新封装一个MAC首部进行转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源IP/PORT,以及目标IP/PORT均保持不变
会存在一个问题,客户端的sip:cip,dip:vip,服务器给客户端回复的时候使用的sip:rip,dip:cip,客户端发现不是自己请求的ip给自己的回复
DR模式的特点
- Director和各RS都配置有VIP
这又会存在一个问题:都有vip,那访问的时候是真实的服务器响应还是负载均衡器响应
- 确保前端路由器将目标IP为VIP的请求报文发往Director三种方法
1.在前端网关做静态绑定VIP和Director的MAC地址(这样防止路由器将请求转发给rs主机)
此方法一般不使用,过于固定,如果负载均衡有高可用,则无法使用
2.在RS上使用arptables工具
arptables -A IN -d $VIP -j DROP
arptables -A OUT -s $VIP -j mangle --mangle-ip-s $RIP #不响应数据包
3.在RS上修改内核参数以限制arp通告及应答级别
/proc/sys/net/ipv4/conf/all/arp_ignore
/proc/sys/net/ipv4/conf/all/arp_announce
-
RS的RIP可以使用私网地址,也可以是公网地址;RIP与DIP在同一IP网络;RIP的网关不能指向DIP,以确保响应报文不会经由Director
-
RS和Director要在同一个物理网络(物理连接)
- physical network由电缆线路、调制解调器或其他硬件连接起来的设备所构成的网络,一个物理网络能包含一个或几个逻辑网络。
-
请求报文要经由Director,但响应报文不经由Director,而由RS直接发往Client
-
不支持端口映射(端口不能修改)
-
RS可使用大多数OS系统
LVS的TUN模式
解决上一个模式必须要在同一个物理网络的缺点
转发方式:不修改请求报文的IP首部(源IP为CIP,目标IP为VIP),而在原IP报文之外再封装一个IP首部(源IP是DIP,目标IP是RIP),将报文发往挑选出的目标RS;RS直接响应给客户端(源IP是VIP,目标IP是CIP)
TUN模式特点
- DIP, VIP, RIP可以是公网地址
- RS的网关一般不能指向DIP
- 请求报文要经由Director,但响应不经由Director
- 不支持端口映射
- RS的OS须支持隧道功能
LVS-Tun工作原理
场景非常少,主要用来解决DR和RS必须要在同一个物理网络中的问题;主要使用tun技术去封装IP报头
在VS/NAT的集群系统中,请求和响应的数据报文都需要通过负载调度器,当真实服务器的数目在10台和20台之间时,负载调度器将成为整个集群系统的新瓶颈。大多数Internet服务都有这样的特点:请求报文较短而响应报文往往包含大量的数据。如果能将请求和响应分开处理,即在负载调度器中只负责调度请求而响应直接返回给客户,将极大地提高整个集群系统的吞吐量。
IP隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,这可以使得目标为一个IP地址的数据报文能被封装和转发到另一个IP地址。IP隧道技术亦称为IP封装技术(IP encapsulation)。IP隧道主要用于移动主机和虚拟私有网络(Virtual Private Network),在其中隧道都是静态建立的,隧道一端有一个IP地址,另一端也有唯一的IP地址。
我们利用IP隧道技术将请求报文封装转发给后端服务器,响应报文能从后端服务器直接返回给客户。但在这里,后端服务器有一组而非一个,所以我们不可能静态地建立一一对应的隧道,而是动态地选择一台服务器,将请求报文封装和转发给选出的服务器。这样,我们可以利用IP隧道的原理将一组服务器上的网络服务组成在一个IP地址上的虚拟网络服务。
LVS的FULLNAT模式
- 通过同时修改请求报文的源IP地址和目标IP地址进行转发
- CIP --> DIP
- VIP --> RIP
- fullnat模式特点:
- VIP是公网地址,RIP和DIP是私网地址,且通常不在同一IP网络;因此,RIP的网关一般不会指向DIP
- RS收到的请求报文源地址是DIP,因此,只需响应给DIP;但Director还要将其发往Client
- 请求和响应报文都经由Director
- 支持端口映射
- 注意:此类型kernel默认不支持
LVS工作模式总结和比较
NAT | TUN | DR | |
---|---|---|---|
Real server | any | Tunneling | Non-arp device |
Real server network | private | LAN/WAN | LAN |
Real Server number | low(10-20) | High(100) | High(100) |
Real server gateway | load balancer | own router | own router |
优点 | 端口转换 | WAN | 性能最好 |
缺点 | 性能瓶颈 | 支持隧道 | 不支持跨网段 |
-
lvs-nat与lvs-fullnat:
- 请求和响应报文都经由Director
- lvs-nat:RIP的网关要指向DIP
- lvs-fullnat:RIP和DIP未必在同一IP网络,但要能通信
-
lvs-dr与lvs-tun:
- 请求报文要经由Director,但响应报文由RS直接发往Client
- lvs-dr:通过封装新的MAC首部实现,通过MAC网络转发
- lvs-tun:通过在原IP报文外封装新IP头实现转发,支持远距离通信
LVS调试算法
ipvs scheduler:根据其调度时是否考虑各RS当前的负载状态
分为两种:静态方法和动态方法
静态方法
- 仅根据算法本身进行调度
- RR:roundrobin,轮询 不考虑机器的性能好坏,轮询调度
- WRR:Weighted RR,加权轮询 权重越高,优先级高,调度更多资源给它 优先级高
- SH:Source Hashing,实现session sticky,源IP地址hash;将来自于同一个IP地址的请求始终发往第一次挑中的RS,从而实现会话绑定
- DH:Destination Hashing;目标地址哈希,第一次轮询调度至RS,后续将发往同一个目标地址的请求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡,如:宽带运营商
动态方法
主要根据每RS当前的负载状态及调度算法进行调度Overhead=value 较小的RS将被调度
-
LC:least connections 适用于长连接应用,主要考量连接数(活跃与非活跃连接)
Overhead=activeconns *256+inactiveconns
-
WLC:Weighted LC,默认调度方法,上面算法算完后除以一个权重
Overhead=(activeconns * 256+inactiveconns)/weight
-
SED:Shortest Expection Delay,初始连接高权重优先
Overhead=(activeconns+1)*256/weight
-
NQ:Never Queue,第一轮均匀分配,后续SED
-
LBLC:Locality-Based LC,动态的DH算法,使用场景:根据负载状态实现正向代理
-
LBLCR:LBLC with Replication,带复制功能的LBLC,解决LBLC负载不均衡问题,从负载重的复制到负载轻的RS
内核版本4.15版本后新增调度算法
- FO(Weighted Fail Over)调度算法,在此FO算法中,遍历虚拟服务所关联的真实服务器链表,找到还未过载(未设置IP_VS_DEST_F_OVERLOAD标志)的且权重最高的真实服务器,进行调度。方便调式上下线。
- OVF(Overflow-connection)调度算法,基于真实服务器的活动连接数量和权重值实现。将新连接调度到权重值最高的真实服务器,直到其活动连接数量超过权重值位置,之后调度到下一个权重值最高的真实服务器,在此OVF算法中,遍历虚拟服务相关联的真实服务器链表,找到权重值最高的可用真实服务器。一个可用的真实服务器需要同时满足以下条件:
- 未过载(未设置IP_VS_DEST_F_OVERLOAD标志)
- 真实服务器当前的活动连接数量小于其权重值
- 其权重值不为零
LVS 相关软件
程序包
- Unit File: ipvsadm.service
- 主程序:/usr/sbin/ipvsadm
- 规则保存工具:/usr/sbin/ipvsadm-save
- 规则重载工具:/usr/sbin/ipvsadm-restore
- 配置文件:/etc/sysconfig/ipvsadm-config
准备三台机器:
[root@localhost ~]# yum ‐y install ipvsadm #远程ssh连接下使用这个命令会出bug,需要直接在虚拟机里使用命令
[root@localhost ~]# cat /usr/lib/systemd/system/ipvsadm.service
[Unit]
Description=Initialise the Linux Virtual Server
After=syslog.target network.target
[Service]
Type=oneshot
ExecStart=/bin/bash -c "exec /sbin/ipvsadm-restore < /etc/sysconfig/ipvsadm"
ExecStop=/bin/bash -c "exec /sbin/ipvsadm-save -n > /etc/sysconfig/ipvsadm"
ExecStop=/sbin/ipvsadm -C
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
ipvsadm 命令
- ipvsadm核心功能:
- 集群服务管理:增、删、改
- 集群服务的RS管理:增、删、改
- 查看
#管理集群服务
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask]
[--pe persistence_engine] [-b sched-flags]
ipvsadm -A #创建集群
ipvsadm -E #修改集群
ipvsadm -D -t|u|f service-address #删除
ipvsadm –C #清空
ipvsadm –R #重载
ipvsadm -S [-n] #保存
ipvsadm -L #查看
#管理集群中的RS
ipvsadm -a|e -t|u|f service-address -r server-address [options]
ipvsadm -d -t|u|f service-address -r server-address
ipvsadm -L|l [options]
ipvsadm -Z [-t|u|f service-address] #清空计数器
#保存规则
‐S
# ipvsadm ‐S > /path/to/somefile
载入此前的规则:
‐R
# ipvsadm ‐R < /path/form/somefile
- 说明
service-address:
-t|u|f:
-t: TCP协议的端口,VIP:TCP_PORT 如:-t 192.168.175.20:80
-u: UDP协议的端口,VIP:UDP_PORT 如:-u 192.168.175.20:80
-f:firewall MARK,标记,一个数字
[-s scheduler]:指定集群的调度算法,默认为wlc
server-address:
rip[:port] 如省略port,不作端口映射
选项:
lvs类型:
-g: gateway, dr类型,默认
-i: ipip, tun类型
-m: masquerade, nat类型
-w weight:权重
- 举例
ipvsadm -A -t 192.168.175.100:80 -s wrr # 创建集群,算法为加权轮询
ipvsadm -D -t 192.168.175.100:80 # 删除集群
ipvsadm -a -t 192.168.175.100:80 -r 192.168.175.20:8080 -m -w 3 # 往集群中添加RS,-m配置为nat模式,配置权重为3
ipvsadm -d -t 192.168.175.100:80 -r 192.168.175.20:8080
# 删除RS
- 查看
ipvsadm -L|l [options]
–numeric, -n:以数字形式输出地址和端口号
–exact:扩展信息,精确值
–connection,-c:当前IPVS连接输出
–stats:统计信息
–rate :输出速率信息
三、LVS实战案例
- 使用VMnet8做DR的网卡,给LB服务器添加一个VMmet1网卡,网卡设置为仅主机模式,后面的WEB01和WEB01服务器都把原来网卡的NAT模式切换为仅主机模式,模拟内网环境通过DR做NAT,以DR为网关来实现上网
- 把lb的仅主机网卡配置和后面两个web服务在同一网段下
nmtui
修改ens37网卡,修改为下面的地址,不需要网关。因为这个机器后面会作为DR
systemctl restart network
ip a
- 配置两台后端web服务器ip
nmtui
一台配置为192.168.92.20/24另一台为192.168.92.30/24
注意把网关配为刚才的lb设备,并且添加好DNS
systemctl restart network
WEB01:
WEB02:
- 开启LVS流量转发功能,并且配置NAT
[root@lvs ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@lvs ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@lvs ~]# iptables -t nat -A POSTROUTING -s 192.168.92.0/24 -j MASQUERADE
[root@lvs ~]# iptables -t nat -L -n
#查看刚才配置的规则
- 先搭建web服务器
[root@rs1 ~]# yum -y install httpd
[root@rs1 ~]# systemctl start httpd
[root@rs1 ~]# systemctl enable httpd
[root@rs1 ~]# echo "RS1 ..." > /var/www/html/index.html
[root@rs1 ~]# firewall-cmd --add-service=http
[root@rs1 ~]# firewall-cmd --add-service=http --permanent
[root@rs2 ~]# yum -y install httpd
[root@rs2 ~]# systemctl start httpd
[root@rs2 ~]# systemctl enable httpd
[root@rs2 ~]# echo "RS2 ..." > /var/www/html/index.html
[root@rs2 ~]# firewall-cmd --add-service=http
[root@rs2 ~]# firewall-cmd --add-service=http --permanent
- 配置LVS
[root@lvs ~]# ipvsadm -A -t 192.168.175.10:80 -s rr #用192.168.175.10:80建一个集群用轮询的算法
[root@lvs ~]# ipvsadm -a -t 192.168.175.10:80 -r 192.168.92.20:80 -m #添加一个rs -m为nat模式
[root@lvs ~]# ipvsadm -a -t 192.168.175.10:80 -r 192.168.92.30:80 -m #再添加一个rs -m为nat模式
[root@lvs ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.175.100:80 rr
-> 192.168.92.20:80 Masq 1 0 0
-> 192.168.92.30:80 Masq 1 0 0
-
验证结果(四层负载均衡不是特别听话)
-
抓包可以观察到客户端都是与LVS进行通信,LVS对流量进行NAT
-
抓Vmware8网卡查看现象
LVS-DR模式案例
- 趁着还有网络,先把后面需要的工具装上
[root@rs1 ~]# yum install -y net-tools
[root@rs2 ~]# yum install -y net-tools
- 做这个实验之前,需要清空LVS之前配置的NAT规则和NAT LVS规则
[root@lvs ~]# iptables -t nat -F
[root@lvs ~]# iptables -L -n -t nat
[root@lvs ~]# ipvsadm -C
[root@lvs ~]# ipvsadm -Ln
- 修改RS1和RS2的网关地址
通过nmtui将网关从192.168.92.10改为192.168.92.2
改好后systemctl restart network
查看路由
[root@rs1 ~]# ip route
default via 192.168.92.2 dev ens33 proto static metric 100
通过nmtui将网关从192.168.92.10改为192.168.92.2
改好后systemctl restart network
查看路由
[root@rs2 ~]# ip route
default via 192.168.92.2 dev ens33 proto static metric 100
- 在RS上修改内核参数以限制arp通告及应答级别
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
#设置完成之后就不会响应对于vip arp请求来的数据包,就不会导致多个vip出现冲突的情况了
[root@rs2 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs2 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
- 给RS1和RS2设置VIP 192.168.92.100
[root@rs1 ~]# vim rs.sh
#!/bin/bash
vip=192.168.92.100/32
ifconfig lo:1 $vip
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
[root@rs1 ~]# . rs.sh
# 在RS2上也需要执行
ip a
- 配置LVS服务器
[root@lvs ~]# ifconfig lo:1 192.168.92.100/32
[root@lvs ~]# ipvsadm -A -t 192.168.92.100:80 -s rr
[root@lvs ~]# ipvsadm -a -t 192.168.92.100:80 -r 192.168.92.20 #不加-m,DR模式
[root@lvs ~]# ipvsadm -a -t 192.168.92.100:80 -r 192.168.92.30 #不加-m,DR模式
[root@lvs ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.92.100:80 rr
-> 192.168.92.20:80 Route 1 0 0
-> 192.168.92.30:80 Route 1 0 0
- 当多次访问192.168.92.100的时候可以负载均衡
- 验证,抓包VMnet 1网卡,发现源端的mac地址是不同的。有不同主机在回复