1、lvs-tun模式
- 转发方式:不修改请求报文的IP首部(源IP为CIP,目标IP为VIP),而在原IP报文之外再封装一个IP首部(源IP是DIP,目标IP是RIP),将报文发往挑选出的目标RS;RS直接响应给客户端(源IP是VIP,目标IP是CIP)
(1) DIP, VIP, RIP都应该是公网地址
(2) RS的网关不能,也不可能指向DIP
(3) 请求报文要经由Director,但响应不能经由Director
(4) 不支持端口映射
(5) RS的OS须支持隧道功能
(6)主要应用于VS和RS不在同一个城市 -
VS/TUN体系结构
-
TUN模式IP包调度过程
2、lvs-fullnat模式
lvs-fullnat:通过同时修改请求报文的源IP地址和目标IP地址进行转发
CIP --> DIP
VIP --> RIP
(1) VIP是公网地址,RIP和DIP是私网地址,且通常不在同一IP网络;因此,RIP的网关一般不会指向DIP
(2) RS收到的请求报文源地址是DIP,因此,只需响应给DIP;但Director还要将其发往Client
(3) 请求和响应报文都经由Director
(4) 支持端口映射;
注意:此类型kernel默认不支持,也就是不能用LVS实现。
3、 LVS工作模式总结
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头实现转发,支持远距离通信,也就是RS和VS可以在不同的城市。并且VIP、DIP、RIP都使用的是公网地址。
4、ipvs scheduler
根据其调度时是否考虑各RS当前的负载状态分为两种方法:静态方法和动态方法
- 静态方法:仅根据算法本身进行调度
1、RR:roundrobin,轮询
2、WRR:Weighted RR,加权轮询,将性能好的机器权重可以多分配一点
3、SH:Source Hashing,实现session sticky,源IP地址hash;将来自于同一个IP地址的请求始终发往第一次挑中的RS,从而实现会话绑定,其实根据源IP没有什么实际意义,因为有可能源IP是nat转换后的,最好是根据cookie,但lvs不识别应用层的协议,不能根据cookie调度
4、DH:Destination Hashing;目标地址哈希,将发往同一个目标地址的请求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡,如:宽带运营商 - 动态方法:主要根据每RS当前的负载状态及调度算法进行调度Overhead=value较小的RS将被调度
1、LC:least connections 适用于长连接应用,根据活动和非活动的连接数
Overhead=activeconns*256+inactiveconns
2、WLC:Weighted LC,默认调度方法
Overhead=(activeconns*256+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
5、ipvsadm包构成和ipvsadm命令
- 程序包:ipvsadm
Unit File: ipvsadm.service
主程序:/usr/sbin/ipvsadm
规则保存工具:/usr/sbin/ipvsadm-save
规则重载工具:/usr/sbin/ipvsadm-restore
配置文件:/etc/sysconfig/ipvsadm-config - 管理集群服务:增、改、删
增、改:
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] ---A增加、E修改,-p指定超时时间,默认是360s,表示360s之内来自同一个地址的请求始终发往同一个RS
删除:
ipvsadm -D -t|u|f service-address
service-address:VIP的地址
-t|u|f:
-t: TCP协议的端口,VIP:TCP_PORT
-u:UDP协议的端口,VIP:UDP_PORT
-f:firewall MARK,标记,一个数字
[-s scheduler]:指定集群的调度算法,默认为wlc
- 管理集群上的RS:增、改、删
增、改:ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight]
删:ipvsadm -d -t|u|f service-address -r server-address
server-address:前面一个是VIP,后面的是RIP
rip[:port]如省略port,不作端口映射,映射指的是访问VIP的80端口,经过VS调度转换后访问的是RS的其他端口
选项:
lvs类型:
-g: gateway, dr类型,默认
-i: ipip, tun类型
-m: masquerade, nat类型
-w weight:权重
- 清空和查看
清空定义的所有内容:ipvsadm –C
清空计数器:ipvsadm -Z [-t|u|fservice-address]
查看:ipvsadm -L|l[options],注意L必须在前面,与iptables正好相反
--numeric, -n:以数字形式输出地址和端口号
--exact:扩展信息,精确值
--connection,-c:当前IPVS连接输出
--stats:统计信息
--rate :输出速率信息
ipvs规则:/proc/net/ip_vs
ipvs连接:/proc/net/ip_vs_conn
- 保存及重载规则
保存:建议保存至/etc/sysconfig/ipvsadm
ipvsadm-save > /PATH/TO/IPVSADM_FILE
ipvsadm -S > /PATH/TO/IPVSADM_FILE
方法是将策略保存至/etc/sysconfig/ipvsadm中,但要先启动这个服务,启动之前先把这个文件创建好
systemctl stop ipvsadm.service
重载:
ipvsadm-restore < /PATH/FROM/IPVSADM_FILE
ipvsadm -R < /PATH/FROM/IPVSADM_FILE
systemctl restart ipvsadm.service ---以上三种方法都可以重载策略
6、LVS-NAT模型实现httpd负载均衡集群
1、把网络连通
将客户端主机的网关指向172.18.21.106
在vs上的设置
echo 1 > /proc/sys/net/ipv4/ip_forward
ip route add 192.168.74.0/24 via 192.168.19.129 ---添加到达192.168.74.0/24这个网段的路由记录
在router上的设置
echo 1 > /proc/sys/net/ipv4/ip_forward
ip route add 172.18.0.0/16 via 192.168.19.128 ---添加到达172.18.0.0/16这个网段的路由记录
在RS1上的设置
ip route add default via 192.168.74.132 ---添加一个默认路由并将网关指向192.168.74.132
在RS2上进行同样的设置
ip route add default via 192.168.74.132
在客户端和RS1及RS2上分别测试看能否互相ping通
2、在VS1和VS2上分别搭建好httpd服务,并在客户端测试
[root@station1 network-scripts]# curl 192.168.74.129
welcome to VS2
[root@station1 network-scripts]# curl 192.168.74.133
welcome to vs1
3、在VS上进行如下设置
在设置之前一定要确保防火墙已经关闭,并且没有设置任何策略
[root@centos6 ~]#ipvsadm -A -t 172.18.21.106:80 -s rr ---创建一个集群服务,表示访问172.18.21.106的80端口,并指定算法为轮询
[root@centos6 ~]#ipvsadm -a -t 172.18.21.106:80 -r 192.168.74.133 -m
[root@centos6 ~]#ipvsadm -a -t 172.18.21.106:80 -r 192.168.74.129 -m ---将两个VS加到集群服务里,表示访问VIP的80端口就调度到192.168.74.129这台RS,-m指定为nat类型
[root@centos6 ~]#ipvsadm -Ln --查看
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.18.21.106:80 rr
-> 192.168.74.129:80 Masq 1 0 0
-> 192.168.74.133:80 Masq 1 0 0
[root@centos6 ~]#ipvsadm -Ln --rate ---可以显示每秒钟进来的包和出去的包,以及每秒进来的字节和出去的字节数,显示速率
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port CPS InPPS OutPPS InBPS OutBPS
-> RemoteAddress:Port
TCP 172.18.21.106:80 0 0 0 0 0
-> 192.168.74.129:80 0 0 0 0 0
-> 192.168.74.133:80 0 0 0 0 0
4、在客户端测试
[root@station1 network-scripts]# for i in {1..10};do curl 172.18.21.106;done ---发现是轮询模式
welcome to VS2
welcome to vs1
welcome to VS2
welcome to vs1
welcome to VS2
welcome to vs1
welcome to VS2
welcome to vs1
welcome to VS2
welcome to vs1
也可以在VS上进行如下设置
ipvsadm -A -t 172.18.21.106:80 -s wrr ---指定算法为加权轮询
ipvsadm -a -t 172.18.21.106:80 -r 192.168.74.129 -m -w 3 ---w指定加权值
ipvsadm -a -t 172.18.21.106:80 -r 192.168.74.133 -m --未指定加权值默认为1
[root@station1 network-scripts]# for i in {1..20};do curl 172.18.21.106;done ---发现是1:3的关系
welcome to vs1
welcome to VS2
welcome to VS2
welcome to VS2
ipvsadm -E -t 172.18.21.106:80 -s sh ---修改集群服务的算法
ipvsadm -a -t 172.18.21.106:80 -r 192.168.74.129:8080 -m ---lvs-nat模式支持端口映射
ipvsadm -d -t 172.18.21.106:80 -r 192.168.74.129 ---把某个RS从集群服务中删除
ipvsadm -e -t 172.18.21.106:80 -r 192.168.74.129:8080 -m -w 3 ---修改集群上的RS的权重为3
[root@centos6 ~]#ipvsadm-save -n > /app/f1 ---保存策略,加上-n选项是以数字方式显示,不加-n会很慢,会将ip地址反向解析成名字
[root@centos6 ~]#ipvsadm -D -t 172.18.21.106:80 ---删除某一个集群服务
[root@centos6 ~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@centos6 ~]#ipvsadm-restore -n < /app/f1 ---从文件中恢复集群服务
[root@centos6 ~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.18.21.106:80 wrr
-> 192.168.74.129:8080 Masq 3 0 0
-> 192.168.74.133:80 Masq 1 0 0
[root@centos6 ~]#ipvsadm -C ---清空所有集群服务
[root@centos6 ~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
NAT模型实现https负载均衡集群
在VS1和VS2上进行如下设置
1、创建自签名证书
cd /etc/pki/tls/certs/
make httpd.crt ---在制作的过程中会让输入对称秘钥,也就是私钥的秘钥,此命令会生成私钥和自签名的证书文件
openssl rsa -in httpd.key -out httpd2.key ---对私钥进行解密,因为私钥被对称秘钥加密了,每次重启服务都需要输入秘钥才可以,为了方便我们将这个私钥解密
rm -f httpd.key
mv httpd2.key httpd.key ---将解密的私钥重命名
2、安装https的模块
yum install mod_ssl
3、修改配置文件
vim /etc/httpd/conf.d/ssl.conf
# Server Certificate:
SSLCertificateFile /etc/pki/tls/certs/httpd.crt ---指明证书文件的路径
# Server Private Key:
SSLCertificateKeyFile /etc/pki/tls/certs/httpd.key ---指明私钥文件的路径
注意:RS: 都要用同一个私钥和同一个证书
4、在VS上的设置
service httpd restart
[root@centos6 ~]#ipvsadm -A -t 172.18.21.106:443 -s rr
[root@centos6 ~]#ipvsadm -a -t 172.18.21.106:443 -r 192.168.74.133 -m
[root@centos6 ~]#ipvsadm -a -t 172.18.21.106:443 -r 192.168.74.129 -m
[root@centos6 ~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.18.21.106:443 rr
-> 192.168.74.129:443 Masq 1 0 0
-> 192.168.74.133:443 Masq 1 0 0
5、在客户端测试
[root@station1 network-scripts]# curl -k https://172.18.21.106:443
welcome to VS2
[root@station1 network-scripts]# curl -k https://172.18.21.106:443
welcome to VS1
总结:本次实验是将DIP和RIP的中间加了一个路由器,分成不同的网段,也可以将DIP和RIP放在同一个网段,中间加一个交换机。VS其实也相当于一个路由器,也要开启路由功能才可以,不然无法转发,到不了别的网络。最重要的是把网络先设置通了,如果中间是交换机将RS的网关指向DIP,如果是中间是路由器将RS的网关指和路由器的邻近接口的IP,不然无法经过director回来。
7、LVS-DR模型实现httpd负载均衡集群
lvs-dr:
dr模型中,director上和各VS主机上均需要配置VIP,解决地址冲突的方式有三种:
(1) 在前端网关做静态绑定,将VIP和director的MAC地址绑定,这样客户端发来的请求不会直接到达RS上,造成ip地址冲突,而是直接到达diretor
(2) 在各RS使用arptables
(3) 在各RS修改内核参数,来限制arp响应和通告的级别
三种方法中只有第三种方法修改RS的内核参数最实用
限制响应级别:arp_ignore = 1
0:默认值,表示可使用本地任意接口上配置的任意地址进行响应
1: 仅在请求的目标IP配置在本地主机的接收到请求报文的接口上时,才给予响应
限制通告级别:arp_announce = 2
0:默认值,把本机所有接口的所有信息向每个接口的网络进行通告
1:尽量避免将接口信息向非直接连接网络进行通告
2:必须避免将接口信息向非本网络进行通告
在VIP和RIP在同一网段情况
1、设置网络
将客户端的网关指向172.18.21.6
ip route add default via 172.18.21.6
在router上开启路由功能
echo 1 > /proc/sys/net/ipv4/ip_forward
将两台RS的网关指向192.168.74.128而不是192.168.74.132,这样他回来的报文就不会经过director
ip route add default via 192.168.74.128
将VS的网关指向192.168.74.128,这条很重要,不然总是实现不了,做实验时在这里浪费了好长时间
ip route add default via 192.168.74.128
这里VS和两台RS都只有一个网卡,设置的都是仅主机模式,表示VS和RS都在同一个网段
2、在两台RS上执行如下操作
搭建好httpd服务,设置内核参数
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
ip addr add 192.168.74.88/32 dev lo ---在回环网卡上添加一个ip地址为VIP,注意这里习惯上添加到回环网卡上,实际上添加到本地网卡上也可以,并且将 VIP的网络id位设置为32位,表示这个网段只有这一台主机
ip route add 192.168.74.88 dev lo ---再添加一条主机路由到达192.168.74.88,这一条不加也可以
3、在VS上的设置
iptables -F ---清空防火墙
systemctl status firewalld ---查看防火墙是否已经关闭
ip addr add 192.168.74.88/32 dev ens33 ---添加一个VIP
yum install ipvsadm
搭建集群服务
ipvsadm -A -t 192.168.74.88:80 -s rr
ipvsadm -a -t 192.168.74.88:80 -r 192.168.74.129 -g
ipvsadm -a -t 192.168.74.88:80 -r 192.168.74.133 -g
ipvsadm -Ln
4、在客户端测试
curl 192.168.74.88
可以在RS上抓包 tcpdump -i eth3 -nn port 80 ---看到反回报文是从RS上直接反回客户端的
VIP和RIP在不同网段的情况
1、网络设置
①将客户端的网关指向172.18.21.6
ip route add default via 172.18.21.6
②在router上增加一条主机路由到达10.0.0.1,并将网关指向192.168.74.132
ip route add 10.0.0.1/32 via 192.168.74.132
echo 1 > /proc/sys/net/ipv4/ip_forward
③在VS上将网关指向192.168.74.128
ip route add default via 192.168.74.128
④在两台RS服务器上将网关指向192.168.74.128
ip route add default via 192.168.74.128
2、在两台RS上执行如下设置
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
ip addr add 10.0.0.1/32 dev lo ---这里在本地网卡添加也可以
3、在VS上的设置
iptables -F ---清空防火墙
ip addr add 10.0.0.1/32 dev ens33
yum install ipvsadm
搭建集群服务
ipvsadm -A -t 10.0.0.1:80 -s rr
ipvsadm -a -t 10.0.0.1:80 -r 192.168.74.129 -g
ipvsadm -a -t 10.0.0.1:80 -r 192.168.74.133 -g
ipvsadm -Ln
4、测试
总结:路由器具有转发功能,只要开启路由功能后就会根据路由表的设置进行相应的转发,一般不需要指定网关,而客户端要想从本机出去访问别的网络,必须指定网关才可以,即使客户端和别的主机在同一个网络也不可以,因为只有指定网关了,才能知道从本地的哪个网卡出去,不然出不去,只能在本机能内,这就是为什么我们要将VS的网关指向192.168.74.128的原因,只有这样,请求报文到达VIP后,经过DIP封装目标RS的MAC地址,从vs出来后因为指定了网关,所以先到达192.168.74.128,再到达RS,如果不指定网关,虽然DIP和RIP在同一个网段,也到达不了RS。
8、FireWall Mark实现httpd和httpds同一调度
MARK target 可用于给特定的报文打标记
--set-mark value
其中:value 为十六进制数字
借助于防火墙标记来分类报文,而后基于标记定义集群服务;可将多个不同的应用使用同一个集群服务进行调度,本次实验是将http和https统一调度,可以实现无论你访问http和https都给你调度到后面的真实的服务器,不用每一个服务都单独的创建一个集群服务
实现方法:
在VS上进行如下设置
iptables -t mangle -A PREROUTING -d 192.168.74.88 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 12 ---无论访问VIP的80还是443端口统一打标签为12
iptables -t mangle -vnL
ipvsadm -A -f 12 -s wrr ---创建一个集群服务,只要标签是12的调度算法都是wrr
ipvsadm -a -f 12 -r 192.168.74.129 -g -w 3 --将RS添加到集群服务里
ipvsadm -a -f 12 -r 192.168.74.133 -g
ipvsadm -Ln
在客户端进行测试
curl 192.168.74.88
curl -k https://192.168.74.88/ ---k表示忽略证书访问
9、持久连接
持久连接(lvspersistence )模板:实现无论使用任何调度算法,在一段时间内(默认360s ),能够实现将来自同一个地址的请求始终发往同一个RS
持久连接实现方式:
每端口持久(PPC):每个端口对应定义为一个集群服务,每集群服务单独调度
每防火墙标记持久(PFWMC):基于防火墙标记定义集群服务;可实现将多个端口上的应用统一调度,即所谓的port Affinity
每客户端持久(PCC):基于0端口(表示所有服务)定义集群服务,即将客户端对所有应用的请求都调度至后端主机,也就是定义集群服务时访问VIP的0端口,这样访问VIP上的任意服务都会调度到后端的RS上,必须定义为持久模式
实现方法,这样做没有什么实际意义,你只是想让某个服务调度,而不是所有的服务都调度。
下面的例子是实现的每防火墙标记持久
在VS上进行如下操作
[root@centos7 ~]#ipvsadm -E -f 12 -s rr -p 300
[root@centos7 ~]#ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
FWM 12 rr persistent 300
-> 192.168.74.129:0 Route 1 0 0
-> 192.168.74.133:0 Route 1 0 0
10、LVS高可用性
某RS不可用时,Director依然会调度请求至此RS,解决方案:由Director对各RS健康状态进行检查,失败时禁用,成功时启用
方法一:在VS上跑一个脚本进行监控
#!/bin/bash
while true;do
curl 192.168.74.133 &> /dev/null && ipvsadm -a -f 12 -r 192.168.74.133 &>/dev/null || ipvsadm -d -f 12 -r 192.168.74.133 &>/dev/null
sleep 1
done
方法二:ldirectord:监控和控制LVS守护进程,可管理LVS规则
包名:ldirectord-3.9.6-0rc1.1.1.x86_64.rpm
/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文件
Ldirectord配置文件示例
checktimeout=3 ---如果三秒没有反应就认为是有故障了
checkinterval=1 ---表示一秒钟检查一下后端的服务器
autoreload=yes ----自动加载配置文件,不用重启都可以生效
logfile=“/var/log/ldirectord.log“ ----日志文件
quiescent=no ----down时yes权重为0,no为删除
virtual=5 -----指定VS的FWM,也可以写vs调度器的vip的地址和端口
real=172.16.0.7:80 gate 2 ---gate表示dr模式,2表示权重
real=172.16.0.8:80 gate 1
fallback=127.0.0.1:80 gate ----定义后面的vs全都宕机了,由谁来提供服务
service=http
scheduler=wrr
checktype=negotiate ---定义检查的类型为协商
checkport=80 ----监控rs的哪个端口
request="index.html"
receive=“Test Ldirectord" ---表示检查的时候看到有什么字样就认为是健康的,是index.html里面的字样,注意大小写敏感
示例
1、yum install ldirectord-3.9.5-5.1.x86_64.rpm
rpm -ql ldirectord
cp /usr/share/doc/ldirectord-3.9.5/ldirectord.cf /etc/ha.d/ ---把模板拷贝到配置文件的目录当做配置文件
2、ipvsadm -C ---清空之前的集群服务,在配置文件里可以定义集群服务,并对RS进行实时监控
ipvsadm -Ln
3、vim /etc/ha.d/ldirectord.cf
checktimeout=3
checkinterval=1
autoreload=yes
quiescent=no
# Sample for an http virtual service
virtual=192.168.74.88:80
real=192.168.74.133:80 gate
real=192.168.74.129:80 gate
fallback=127.0.0.1:80 ---表示两台VS都有故障了就由本机来代替,这样本机也得装一个httpd服务
service=http
scheduler=rr
#persistent=600
#netmask=255.255.255.255
protocol=tcp
checktype=negotiate
checkport=80
request="index.html"
receive="welcom" --表示收到index.html里有welcom字样就认为机器是好的
在本机也安装一个httpd服务
vim /var/www/html/index.html ---这样两台RS都宕机了就有本机提供服务显示sorry server字样
sorry server
4、测试
分别宕机一台和两台RS
[root@centos7 resource.d]#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.74.88:80 rr
-> 127.0.0.1:80 Route 1 0 0
此时在客户端
[root@redhat7 ~]#curl 192.168.74.88
sorry server
总结:使用ldirectord工具定义集群服务,就不用使用ipvsadm命令去定义了,直接在配置文件里面都定义好了,很方便,而且可以监控后端服务器的状态,对后端服务器进行健康性检查。