- 博客/
LVS DR 负载均衡实现
上篇关于 LVS-nat 模式的负载均衡实现博客中已经简单介绍了有关LVS集群的概念、四种IP负载均衡技术以及十种调度算法,本文将详细介绍LVS-DR(直接路由)模式的实现
LVS-DR:Direct Routing, LVS默认模式, 通过为请求报文重新封装一个MAC首部进行转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源IP/PORT,以及目标IP/PORT均保持不变。请求报文同样要经由 Director,但与nat不同的是DR模式下的响应报文不经由 Director,而由RS直接发往Client
DR模式调度流程#
网络传输时,经过路由转发,会修改源mac为该转发路由的mac
Director和各RS都配置有VIP
确保RS响应报文中源IP为VIP,进而走直接路由返回client
解决地址冲突, 确保前端路由器将目标IP为VIP的请求报文发往Director,而不是RS,三种方法:
在前端网关做静态绑定VIP和Director的MAC地址
在RS上使用arptables工具
arptables -A IN -d VIP -j DROP arptables -A OUT -s VIP -j mangle –mangle -ip -s RIP
在各RS修改内核参数,来限制arp响应和通告的级别
限制响应级别: arp_ignore
1 –> 仅在请求的目标IP配置在本地主机的接收到请求报文的接口上时,才给予响应
eg:
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
限制通告级别:arp_announce
2 –> 必须避免将接口信息向非本网络进行通告
eg:
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
HTTP服务负载均衡实验#
网络拓扑搭建#
使用VMware搭建实验网络拓扑
VIP与RIP可以在一个网段也可以不在同一网段。此实验中,VIP是与RIP在同一网段,前端路由临近的接口只用配一个地址,否则要额外配置一个vip网段的地址
调度器Director要打开核心转发功能
$ echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
如果要启用sorry server, VS 的网关要指向前端路由临近的接口;否则,指向RIP所在网段任意IP皆可
RS 网关要指向前端路由
配置RS httpd服务并启动
RS1 –>
$ echo “RS1 SRV” > /var/www/html/index.html
RS2 –>
$ echo “RS2 SRV” > /var/www/html/index.html
脚本实现RS配置
$ bash lvs_dr_rs.sh start
#!/bin/bash
vip=192.168.196.186
dev=lo:1 <-- 配置VIP在回环lo的别名上
case $1 in
start)
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
ifconfig $dev $vip netmask 255.255.255.255 broadcast $vip up
;;
stop)
ifconfig $dev down
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
;;
*)
echo "Usage: $(basename $0) start|stop"
exit 1
;;
esac
DIRECTOR上管理集群服务并测试#
脚本实现集群服务管理
$ bash lvs_dr_vs.sh start
#!/bin/bash
vip=192.168.196.186
port=80
service=$vip:$port
dev=ens33:1
RS1=192.168.196.155
RS2=192.168.196.196
scheduler=rr
tp="-g"
case $1 in
start)
ifconfig $dev $vip/32 broadcast $vip up
ipvsadm -A -t $service -s $scheduler
ipvsadm -a -t $service -r $RS1 $tp -w 1
ipvsadm -a -t $service -r $RS2 $tp -w 1
;;
stop)
ipvsadm -C
ifconfig $dev down
;;
*)
echo "Usage $(basename $0) start|stopr";exit 1
;;
esac
查看当前状态
$ 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.196.186:80 rr
-> 192.168.196.155:80 Route 1 0 0
-> 192.168.196.196:80 Route 1 0 1
客户端测试
$ for i in {1..10}; do curl 192.168.196.186;sleep 1;done
RS2 SRV
RS1 SRV
RS2 SRV
RS1 SRV
RS2 SRV
RS1 SRV
RS2 SRV
RS1 SRV
RS2 SRV
RS1 SRV
ldirectord工具实现高可用的lvs#
ldirectord:监控和控制LVS守护进程,可管理LVS规则 rpm包 –> ldirectord-3.9.6-0rc1.1.1.x86_64.rpm
$ rpm -ql ldirectord
/etc/ha.d
/etc/ha.d/resource.d
/etc/ha.d/resource.d/ldirectord
/etc/logrotate.d/ldirectord
/usr/lib/ocf/resource.d/heartbeat/ldirectord
/usr/lib/systemd/system/ldirectord.service
/usr/sbin/ldirectord
/usr/share/doc/ldirectord-3.9.6
/usr/share/doc/ldirectord-3.9.6/COPYING
/usr/share/doc/ldirectord-3.9.6/ldirectord.cf <-- 配置文件模板
/usr/share/man/man8/ldirectord.8.gz
$cp /usr/share/doc/ldirectord-3.9.6/ldirectord.cf /etc/ha.d
修改配置文件#
$ vim /etc/ha.d/ldirectord.cf
checktimeout=3 <-- 响应超时时间
checkinterval=1 <-- 检查间隔时间
#fallback=127.0.0.1:80
#fallback6=[::1]:80
autoreload=yes <-- 自动读取加载配置文件
logfile="/var/log/ldirectord.log"
#logfile="local0" <-- 指定rsyslog日志服务的facility名称
#emailalert="admin@x.y.z"
#emailalertfreq=3600
#emailalertstatus=all
quiescent=no <-- no代表一旦宕机则从集群中移除RS;yes代表一旦宕机则将该RS权重设置为0
# Sample for an http virtual service <-- Director Server的配置(以上文实验配置为例)
virtual=192.168.196.186:80
real=192.168.196.155:80 gate <-- gate 对应-g dr模式
real=192.168.196.196:80 gate
fallback=127.0.0.1:80 gate <-- sorry server; RS全部宕机时的响应
service=http
scheduler=rr
#persistent=600
#netmask=255.255.255.255
protocol=tcp
checktype=negotiate
checkport=80
request="index.html"
receive="SRV" <-- 抓取网页关键字,判断
$ echo "Sorry, server is down" > /var/www/html/index.html
$ systemctl start httpd <-- 启动调度服务器的http服务
启动ldirector服务#
$ ifconfig ens33:1 192.168.196.186/32 broadcast 192.168.196.186 up <-- VS上手动添加VIP
$ systemctl start ldirectord
$ 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.196.186:80 rr
-> 192.168.196.155:80 Route 1 0 0
-> 192.168.196.196:80 Route 1 0 0
客户端测试#
- lvs集群已经实现轮询算法的调度
$ for i in {1..5}; do curl --connect-timeout 1 192.168.196.186;sleep 1; done
RS2 SRV
RS1 SRV
RS2 SRV
RS1 SRV
RS2 SRV
停止RS1的http服务模拟宕机
VS上查看集群服务状态
$ 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.196.186:80 rr
-> 192.168.196.196:80 Route 1 0 0 <--自动移除宕机的RS1
客户端测试显示RS1宕机后,DR将请求自动调度到RS2上
$ for i in {1..5}; do curl --connect-timeout 1 192.168.196.186;sleep 1; done
RS2 SRV
RS1 SRV
RS2 SRV
RS2 SRV <-- 此时RS1 http服务停止
RS2 SRV
停止所有RS的http服务
VS上查看集群服务状态
$ 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.196.186:80 rr
-> 127.0.0.1:80 Route 1 0 0 <--自动启用本机sorry server
客户端测试结果
[root@Centos7 ~]#for i in {1..100}; do curl --connect-timeout 1 192.168.196.186;sleep 1; done
RS1 SRV
RS2 SRV
RS1 SRV
RS2 SRV
RS1 SRV
RS1 SRV <--RS2宕机
RS1 SRV
sorry,server is down <--RS1同时宕机,启用sorry server
sorry,server is down