LVS负载均衡集群
LVS介绍
官网:http://www.linuxvirtualserver.org/
LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统,可以在UNIX/LINUX平台下实现负载均衡集群功能。该项目在1998年5月由章文嵩博士组织成立,是中国国内最早出现的自由软件项目之一。
LVS:Linux Virtual Server,负载调度器,集成内核。
早在2.2内核时, IPVS就已经以内核补丁的形式出现。
从2.4.23版本开始,IPVS软件就合并到Linux内核的常用版本的内核补丁的集合。
从2.4.24以后IPVS已经成为Linux官方标准内核的一部分。
LVS无需安装 安装的是管理工具,第一种叫ipvsadm,第二种叫keepalive ipvsadm是通过命令行管理,而keepalive读取配置文件管理 后面我们会用Shell脚本实现keepalive的功能
工作原理:VS根据请求报文的目标IP和目标协议及端口将其调度转发至某RS,根据调度 算法来挑选RS
CIP:Client IP #客户端的IP
VIP: Virtual serve IP VS外网的IP #调度器连接外网的地址
DIP: Director IP VS内网的IP #调度器连接内网的地址
RIP: Real server IP #真实服务器的IP
访问流程:CIP <–> VIP == DIP <–> RIP
lvs集群的类型
lvs-nat:修改请求报文的目标IP ,多目标IP的DNAT
lvs-dr:操纵封装新的MAC地址
lvs-tun:在原请求IP报文之外新加一个IP首部
lvs-fullnat:修改请求报文的源和目标IP
lvs-nat模式
本质是多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑 出的RS的RIP和PORT实现转发
特性:
- 集群节点和director应该在同一个IP网络中
- RIP地址通常都是私有地址,仅用于各集群节点之间通信
- director位于client和real server之间,并负责处理进出的所以通信
- real server必须将网关指向DIP
- director支持端口映射
- real server可以使用任意操作系统
- 较大规模应用场景中,director易成为整个集群的瓶颈,大约10个real server
LVS-nat模式的实现(支持端口映射)
1)在LVS服务器上
必须关闭iptablse和selinux
[root@lvs ~]#yum -y install ipvsadm #安装LVS服务包 [root@lvs ~]#echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf #启用路由 [root@lvs ~]# sysctl -p #让其生效 net.ipv4.ip_forward = 1 [root@lvs ~]# sysctl -a |grep ip_forward #查看是否生效 sysctl: reading key "net.ipv6.conf.all.stable_secret" sysctl: reading key "net.ipv6.conf.default.stable_secret" sysctl: reading key "net.ipv6.conf.ens33.stable_secret" net.ipv4.ip_forward = 1 net.ipv4.ip_forward_use_pmtu = 0 sysctl: reading key "net.ipv6.conf.ens37.stable_secret" sysctl: reading key "net.ipv6.conf.lo.stable_secret" [root@lvs ~]# getenforce #查看防火墙状态 Disabled [root@lvs~]# ipvsadm -A -t 172.20.81.200:80 -s rr #rr:使用轮询调度;172.20.130.200为VIP地址 [root@lvs ~]# ipvsadm -a -t 172.20.81.200:80 -r 192.168.130.6 -m [root@lvs ~]# ipvsadm -a -t 172.20.81.200:80 -r 192.168.130.7 -m [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 172.20.81.200:80 rr -> 192.168.130.6:80 Masq 1 0 0 -> 192.168.130.7:80 Masq 1 0 0
RS状态检测脚本 #!/bin/bash # rip1=192.168.130.6 rip2=192.168.130.7 vip=172.20.81.200 scheduler=rr port=80 testsite="index.html" timeinterval=1 lvstart() { echo 1 > /proc/sys/net/ipv4/ip_forward ipvsadm -A -t $vip:$port -s $scheduler ipvsadm -a -t $vip:$port -r $rip1 -m ipvsadm -a -t $vip:$port -r $rip2 -m ipvsadm -a -t $vip:$port -r $rip3 -m } lvstop() { echo 0 > /proc/sys/net/ipv4/ip_forward ipvsadm -C } check() { while :; do nowtime=`date +%S |awk -F '' '{print $2}'` for i in $rip1 $rip2 $rip3; do if curl http://$i/$testsite &>/dev/null; then [ "$nowtime" -eq 0 ] && echo "`date +%F-%T` $i online" >> /var/log/lvs_rs_state.log ipvsadm -Ln |grep -q $i || ipvsadm -a -t $vip:$port -r $i -m else [ "$nowtime" -eq 0 ] && echo "`date +%F-%T` $i offline" >> /var/log/lvs_rs_state.log ipvsadm -Ln |grep -q $i && ipvsadm -d -t $vip:$port -r $i fi done sleep $timeinterval done } case $1 in start) lvstart;; stop) lvstop;; check) check;; *) echo "Usage: `basename $0` start|stop|check" esac
2)在web-RS1上
安装httpd
[root@RS1~]#yum -y install httpd #安装包 [root@RS1~]#service httpd start #重启httpd服务 [root@RS1~]#echo "RS1" > /var/www/html/index.html #建立访问主页面
配置网卡信息:(按照拓扑图来配置) DEVICE=eth0 IPADDR=192.168.130.6 PREFIX=24 GATEWAY=192.168.130.200 service network restart #重启网络服务
3)在web-RS2上
[root@RS2~]#yum -y install httpd #安装包 [root@RS2~]#systemctl start httpd #重启httpd服务 [root@RS2~]#echo "RS2" > /var/www/html/index.html #建立访问主页面
配置网卡信息:(按照拓扑图来配置) DEVICE=ens33 IPADDR=192.168.130.7 PREFIX=24 GATEWAY=192.168.130.200 systemctl restart network #重启网络服务
4)在客户端访问
[root@centos7 ~]# curl 172.20.81.200 RS2 [root@centos7 ~]# curl 172.20.81.200 RS1 [root@centos7 ~]# curl 172.20.81.200 RS2
LVS-DR模式
Direct Routing,直接路由,LVS默认模式,应用最广泛,通过为请求报文重新封装一个MAC首部进行转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源IP/PORT,以及目标IP/PORT均保持不变
特性:
- 集群节点跟director必须在同一个物理网络中
- RIP可以不用是私有地址了
- director只负责处理入站请求,响应报文则由real server直接发往客户端
- real server不能将网关指向DIP
- director不支持端口映射
- 大多数的操作系统都可以用于real server,因为需要具有隐藏VIP的功能
- 可以支持的real server是NET模型的数十倍
确保前端路由器将目标IP为VIP的请求报文发往Director的方法:
- 在前端网关做静态绑定VIP和Director的MAC地址
- 在RS上使用arptables工具
- 在RS上修改内核参数以限制arp通告及应答级别
/proc/sys/net/ipv4/conf/all/arp_ignore
/proc/sys/net/ipv4/conf/all/arp_announce
限制ARP响应/通告级别:
限制响应级别:arp_ignore
- 0:默认值,表示可使用本地任意接口上配置的任意地址进行响应
- 1: 仅在请求的目标IP配置在本地主机的接收到请求报文的接口上时,才给予响应
限制通告级别:arp_announce
- 0:默认值,把本机所有接口的所有信息向每个接口的网络进行通告
- 1:尽量避免将接口信息向非直接连接网络进行通告
- 2:必须避免将接口信息向非本网络进行通告
arp协议说明
ARP协议,全称"Address Resolution Protocol",中文名是地址解析协议,使用ARP协议可实现通过IP地址获得对应主机的物理地址(MAC地址)。
ARP协议要求通信的主机双方必须在同一个物理网段(即局域网环境)!
为了提高IP转换MAC的效率,系统会将解析结果保存下来,这个结果叫做ARP缓存。
Windows查看ARP缓存命令 arp -a Linux查看ARP缓存命令 arp -n Linux解析IP对应的MAC地址 arping -c 1 -I eth0 VIP
ARP缓存表是把双刃剑
a) 主机有了arp缓存表,可以加快ARP的解析速度,减少局域网内广播风暴。因为arp是发广播解析的,频繁的解析也是消耗带宽的,尤其是机器多的时候。
b) 正是有了arp缓存表,给恶意黑客带来了攻击服务器主机的风险,这个就是arp欺骗攻击。
c) 切换路由器,负载均衡器等设备时,可能会导致短时网络中断。因为所有的客户端ARP缓存表没有更新
LVS-DR模式(单网络,此阶段使用的网络都是公网地址)由于实际生产中用不到,具体过程省略
LVS-DR模式(跨网络,VIP与DIP/RIP不在同一网络 )
实验结构拓扑图:此网络中10.0.0.100为VIP使用的一个公网的地址;然后LVS和RS1;RS2使用的都是私网地址来连通;同时都绑定公网的VIP 这样做可以节省公网地址。
1)在RS1上
[root@RS1~]#yum -y install httpd #安装包 [root@RS1~]#service httpd start #重启httpd服务 [root@RS1~]#echo "RS1" > /var/www/html/index.html #建立访问主页面 配置网卡信息:(按照拓扑图来配置) DEVICE=eth0 IPADDR=192.168.130.6 PREFIX=24 GATEWAY=192.168.130.200 service network restart #重启网络服务 #修改内核配置来防止VIP地址的相互冲突(临时生效) [root@RS1~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore [root@RS1~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore [root@RS1~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce [root@RS1~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce [root@RS1 ~]# ip a a 10.0.0.100/32 dev lo #将VIP地址绑定到本机的回环网卡上(临时生效)
2)在RS2上
[root@RS2~]#yum -y install httpd #安装包 [root@RS2~]#systemctl start httpd #重启httpd服务 [root@RS2~]#echo "RS2" > /var/www/html/index.html #建立访问主页面 配置网卡信息:(按照拓扑图来配置) DEVICE=ens33 IPADDR=192.168.130.7 PREFIX=24 GATEWAY=192.168.130.200 systemctl restart network #重启网络服务 #修改内核配置来防止VIP地址的相互冲突(临时生效) [root@RS2~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore [root@RS2~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore [root@RS2~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce [root@RS2~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce [root@RS2 ~]# ip a a 10.0.0.100/32 dev lo #将VIP地址绑定到本机的回环网卡上(临时生效)
3)配置路由器虚拟主机的网卡
先配置192.168.130.200 和172.20.81.200/16的IP地址 [root@route~]# ip a a 10.0.0.200/8 dev ens33 #将此IP和192.168.130.200绑在同一块网卡上 [root@route ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:19:bc:ad brd ff:ff:ff:ff:ff:ff inet 192.168.130.200/24 brd 192.168.130.255 scope global ens33 valid_lft forever preferred_lft forever inet 10.0.0.200/8 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe19:bcad/64 scope link valid_lft forever preferred_lft forever 3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:19:bc:b7 brd ff:ff:ff:ff:ff:ff inet 172.20.81.200/16 brd 172.20.255.255 scope global ens37 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe19:bcb7/64 scope link valid_lft forever preferred_lft forever [root@route ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf #启动路由功能,新加的路由器(在centos7上) [root@route ~]# sysctl -p #让其生效 net.ipv4.ip_forward = 1
4)配置LVS服务器的网卡配置(VIP和DIP)
[root@LVS~]#yum -y install ipvsadm #安装包 [root@LVS~]# ip a a 10.0.0.100/8 dev ens33 #将VIP绑定到DIP的网卡上 [root@LVS ~]# ipvsadm -A -t 10.0.0.100:80 -s rr #定义规则;此IP地址为VIP的地址 [root@LVS ~]# ipvsadm -a -t 10.0.0.100:80 -r 192.168.130.6 #添加后台服务的主机 [root@LVS~]# ipvsadm -a -t 10.0.0.100:80 -r 192.168.130.7 [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 10.0.0.100:80 rr -> 192.168.130.6:80 Route 1 0 0 -> 192.168.130.7:80
5)配置客户端访问,配置一个172.20网段的一个网卡即可,需添加GETAWAY(172.20.81.200)
[root@centos7 ~]# cur l0.0.0.100
RS2 [root@centos7 ~]# curl 10.0.0.100 RS1 [root@centos7 ~]# curl 10.0.0.100 RS2
还可以实现域名服务器(DNS)数据库连接(mariadb),文件共享(NFS),由于涉及主机台数,若有需参考博客
https://www.cnblogs.com/L-dongf/p/9260293.html
ldirectord(高可用性)
监控和控制LVS守护进程,可管理LVS规则
/etc/ha.d/ldirectord.cf 主配置文件
/usr/share/doc/ldirectord-3.9.6/ldirectord.cf 配置模版
/usr/lib/systemd/system/ldirectord.service 服务
/usr/sbin/ldirectord 主程序
/var/log/ldirectord.log 日志
/var/run/ldirectord.ldirectord.pid pid文件
基于上述实验完成高可用性的实现
[root@LVS ~]# yum install ldirectord-3.9.6-0rc1.1.1.x86_64.rpm #安装包
[root@LVS ~]# cp /usr/share/doc/ldirectord-3.9.6/ldirectord.cf /etc/ha.d/ #将配置文件复制出来一份
[root@LVS ~]# vim /etc/ha.d/ldirectord.cf #修改配置文件
# Global Directives
checktimeout=3 #检查后端服务器连接状态超时时间为3S(出故障时就自动将ipvs里出故障的服务器删除)
checkinterval=1 #检查后端服务器的时间
fallback=127.0.0.1:80 #当后台所有服务器都宕机时启用本机的http服务来提供sorry server界面的提示
#fallback6=[::1]:80
autoreload=yes #配置文件修改完自动加载
logfile="/var/log/ldirectord.log" #启用日志信息
#logfile="local0"
#emailalert="admin@x.y.z"
#emailalertfreq=3600
#emailalertstatus=all
quiescent=no #当出现故障时,不删除权重
# Sample for an http virtual service
virtual=10.0.0.100:80 #VIP的地址
real=192.168.130.6:80 gate 1
real=192.168.130.7:80 gate 2
service=http
scheduler=wrr
#persistent=600
#netmask=255.255.255.255
protocol=tcp
checktype=negotiate
checkport=80
request="index.html"
receive="Test Page" #测试网站的返回值,来判断服务器是否还在运行
[root@LVS ~]# yum install httpd -y
[root@LVS ~]# systemctl enable httpd
[root@LVS ~]# systemctl start httpd
echo “sorry server” > /var/www/html/index.html
此时如果将后台的两台http服务器都停止服务:systemctl stop httpd
就会显是LVS服务器本机提供的http服务提供sorry server
LVS-TUN隧道模式
不修改请求报文的IP首部(源IP为CIP,目标IP为VIP),而在原IP报文之外再封装一个IP首部(源IP是DIP,目标IP是RIP),将报文发往挑选出的目标RS;RS直接响应给客户端(源IP是VIP,目标IP是CIP)
特性:
- DIP, VIP, RIP都应该是公网地址
- RS的网关一般不能指向DIP
- 请求报文要经由Director,但响应不能经由Director
- 不支持端口映射
- RS的OS须支持隧道功能
LVS-FULLNAT模式
通过同时修改请求报文的源IP地址和目标IP地址进行转发
特性:
-
VIP是公网地址,RIP和DIP是私网地址,且通常不在同一IP网络;因此,RIP的网关一般不会指向DIP
-
RS收到的请求报文源地址是DIP,因此,只需响应给DIP;但Director还要将其发往Client
-
请求和响应报文都经由Director
-
支持端口映射
注意:此类型kernel默认不支持
scheduler 调度算法
根据其调度时是否考虑各RS当前的负载状态分为动态调度算法和静态调度算法
静态方法:
仅根据算法本身进行调度
1、RR:roundrobin,轮询
2、WRR:Weighted RR,加权轮询
3、SH:Source Hashing,源地址哈希;实现session sticky,源IP地址hash;将来自于同一个IP地址的请求始终发往第一次挑中的RS,从而实现会话绑定
4、DH:Destination Hashing,目标地址哈希;将发往同一个目标地址的请求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡
动态方法:
主要根据每RS当前的负载状态及调度算法进行调度Overhead=value较小的RS将被调度
1、LC:least connections,适用于长连接应用;Overhead=activeconns256+inactiveconns
2、WLC:Weighted LC,默认调度方法;Overhead=(activeconns256+inactiveconns)/weight
3、SED:Shortest Expection Delay,初始连接高权重优先;Overhead=(activeconns+1)*256/weight
4、NQ:Never Queue 永不排队;第一轮均匀分配,后续SED
5、LBLC:Locality-Based LC,动态的DH算法,使用场景:根据负载状态实现正向代理
6、LBLCR:LBLC with Replication,带复制功能的LBLC 解决LBLC负载不均衡问题,从负载重的复制到负载轻的RS
七、ipvsadm/ipvs
ipvs集成kernel中
管理工具包:ipvsadm
主程序:/usr/sbin/ipvsadm
规则保存工具:/usr/sbin/ipvsadm-save -n > ipvs.txt
规则重载工具:/usr/sbin/ipvsadm-restore < ipvs.txt
配置文件:/etc/sysconfig/ipvsadm-config
ipvsadm命令:
增加/修改集群服务:
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]]
删除集群服务:
ipvsadm -D -t|u|f service-address
- -t:TCP协议的端口,VIP:TCP_PORT
- -u:UDP协议的端口,VIP:UDP_PORT
- -f:firewall MARK,防火墙标记,一个数字
- -s:指定调度方法,默认为wlc
- -p:指定长连接时间
增加/修改RS:
ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight]
删除RS:
ipvsadm -d -t|u|f service-address -r server-address
- -r:指定rs的地址
- -g:gateway, dr类型,默认
- -i:ipip,tun类型
- -m:masquerade,nat类型
- -w:指定权重
清空ipvs规则:
ipvsadm -C
清空计数器:
ipvsadm -Z [-t|u|f service-address]
查看ipvs工作状态:ipvsadm -L|l [options]
- --numeric, -n:以数字形式输出地址和端口号
- --exact:扩展信息,精确值
- --connection,-c:当前IPVS连接输出
- --stats:统计信息
- --rate :输出速率信息
ipvs规则:/proc/net/ip_vs
ipvs连接:/proc/net/ip_vs_conn
FireWall Mark
MARK target 可用于给特定的报文打标记,--set-mark value
,其中:value 可为0xffff格式,表示十六进制数字
借助于防火墙标记来分类报文,而后基于标记定义集群服务;可将多个不同的应用使用同一个集群服务进行调度
iptables -t mangle -A PREROUTING -d VIP -p PROTOCOL –m multiport --dports $port1,$port2,… -j MARK --set-mark NUMBER ipvsadm -A -f NUMBER [options]
实现:
~]# iptables -t mangle -A PREROUTING -d 192.168.130.200 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 10 ~]# ipvsadm -A -f 10 -s wlc ~]# ipvsadm -a -f 10 -r 192.168.0.13 -w 2 ~]# ipvsadm -a -f 10 -r 192.168.0.14 -w 2
持久连接
session 绑定:对共享同一组RS的多个集群服务,需要统一进行绑定,lvs sh算法无法实现
持久连接( lvs persistence )模板:实现无论使用任何调度算法,在一段时间内(默认360s ),能够实现将来自同一个地址的请求始终发往同一个RS
持久连接实现方式:
- 每端口持久(PPC):每个端口对应定义为一个集群服务,每集群服务单独调度
- 每防火墙标记持久(PFWMC):基于防火墙标记定义集群服务;可实现将多个端口上的应用统一调度,即所谓的port Affinity
- 每客户端持久(PCC):基于0端口(表示所有服务)定义集群服务,即将客户端对所有应用的请求都调度至后端主机,必须定义为持久模式