本文简单介绍一下,如何基于ECMP,使用Quagga+LVS+Keepalived构建多活负载均衡方案
1. 背景介绍
负载均衡,主要用于大规模分布式集群下,提供高性能服务。为了给负载均衡器提供高可用,一般利用主备或者主主模式实现。主备模式即只有主负载均衡器提供负载均衡功能,当主负载均衡器出现异常时,自动切换到备负载均衡器,继续提供负载均衡功能。主主模式(也称之为双活负载均衡),两个负载均衡器同时提供负载均衡服务,全部为主模式,流量均摊到两个负载均衡设备。本文基于LVS+OSPF+Keepalived搭建了一套多活负载均衡。
1.1 LVS
LVS(Linux Virtual Server)即linux虚拟服务器。是一个虚拟的服务器集群系统,讲发送给VIP的请求,转发给对应的后端服务器。从而起到负载均衡的作用。后端服务器处理完请求,将结果返还给用户。LVS主要通过工作在linux内核层的ipvs来实现。而对于ipvs,我们可以用ipvsadm来进行配置。ipvsadm工作
在用户空间,ipvs工作在内核空间。ipvsadm和ipvs的关系就好比是iptables和netfilter的关系。综上所述,LVS由两部分组成,ipvs和ipvsadm
ipvsadm: LVS管理工具,通过ipvsadm定义和管理集群规则。
ipvs:LVS核心实现,根据定义好的集群规则进行工作。
注: LVS为四层负载均衡,基于ip和端口进行转发。
1.2 OSPF/ECMP
OSPF,开放式最短路径优先协议,一种基于链路状态的内部网关协议。每个OSPF路由器都包含了整个网络的拓扑。并计算通过网络的最短路径。OSPF会通过多播的方式自动对外传播检测到的网络变化。
RIP,即路由信息协议,是一个老的协议。RIP路由器向网络中周期性多播它的整个路由表,而不像ospf只多播网络的变化。RIP通过跳数来测量路由,任何超过15跳的路由,都被视为不可达。
ECMP:等价多路径协议。即当存在多条不同的链路到达同一目的地址时,利用ECMP可以同时使用多条链路,不仅增加了传输带宽,还可以无时延、无丢包的备份失效链路的数据传输。如果利用传统的路由算法,只能利用其中的一条链路进行数据的传输。
1.3 quagga
quagga是一个实现ospf的路由软件,用于模拟ospf协议。
2. 双活负载均衡架构
2.1 方案一、利用DNS轮训
配置两套主备模式的负载均衡器,分别配置VIP A和VIP B。在DNS server测针对同一域名,同时注册VIP A和VIP B。然后在请求域名的时候,dns通过轮训返回VIP A或者 VIP B。在服务端,需要通过memcached集群来共享不同节点的内存数据。从而保证session的持久性
2.2 方案二、利用ECMP
在此方案中,不存在主备模式的负载均衡器,所有负载均衡器均为主模式,配置同一VIP。在router测,利用quagga模拟ospf,可以看到到达VIP的链路有两条,当请求到达router的时候,会将流量分配到两台主负载均衡器上。
3. 环境准备
本文利用fusion创建了6台虚拟机。基于centos 7.5,具体信息如下:
- VIP: 10.0.1.100
- client: 10.0.1.132
- router: 10.0.1.136
- lb1: 10.0.1.133
- lb2: 10.0.1.135
- real_server1: 10.0.1.129
- real_server2: 10.0.1.131
注: 所有虚拟机关闭防火墙
1 2 |
systemctl stop firewalld systemctl disable firewalld |
4. 环境部署
4.1 real server端
- 安装nginx提供http服务。
1 2 3 4 5 6 |
yum install nginx -y systemctl start nginx systemctl enable nginx 对于real_server1: echo "RealServer1 10.0.1.129" > /usr/share/nginx/html/index.html 对于real_server2: echo "RealServer2 10.0.1.131" > /usr/share/nginx/html/index.html systemctl restart nginx |
- 配置vip
由于接收数据包的目的IP是VIP,所以需要将vip绑定到lo网卡,因为lo:vip不是用来通信的,所以这里的一定设置/32位子网掩码。对应修改脚本中的”VIP”变量。
由于real_server1, real_sever2, lb1, lb2均绑定vip到lo,所以需要关闭real_server1和real_server2的arp响应。对于linux内核参数arp_ignore和arp_announce的配置,参考文档 https://www.cnblogs.com/lipengxiang2009/p/7451050.html
arp_ignore设置为1:只响应目的IP地址为接收网卡上的本地地址的arp请求。所以对于lo网卡绑定VIP(lo是不接收外部数据包的),所以不会做出响应
arp_announce设置为2:忽略IP数据包的源IP地址,选择该发送网卡上最合适的本地地址作为arp请求的源IP地址。arp_announce的作用是控制系统在对外发送arp请求的数据包时,如何选择发送的源ip地址。因为对于任一主机,当接收到arp请求时,如果该arp的目的ip不是自己的ip,主机会把对端的ip和mac地址的对应关系存储到本地的mac地址表中。所以,如果real_server1发送arp的ip是lo的VIP,那么其他主机就会将VIP和mac的对应关系存储到mac地址表中,当下次像vip发送请求的时候,会直接到达real_server1,而不会经过lb。所以要设置arp_announce为2,这样就避免了通过lo:vip发送arp请求包。
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 36 37 38 39 40 41 42 43 44 |
[root@localhost ~]# cat relserver.sh #!/bin/bash # Script to start LVS DR real server. # description: LVS DR real server . /etc/rc.d/init.d/functions VIP=10.0.1.100 #修改为VIP host=`/bin/hostname` case "$1" in start) /sbin/ifconfig lo down /sbin/ifconfig lo up 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 /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up /sbin/route add -host $VIP dev lo:0 ;; stop) /sbin/ifconfig lo:0 down echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce ;; status) islothere=`/sbin/ifconfig lo:0 | grep $VIP` isrothere=`netstat -rn | grep "lo" | grep $VIP` if [ ! "$islothere" -o ! "isrothere" ];then # Either the route or the lo:0 device not found. echo "LVS-DR real server Stopped." else echo "LVS-DR real server Running." fi ;; *) # Invalid entry. echo "$0: Usage: $0 {start|status|stop}" exit 1 ;; esac exit 0 [root@localhost ~]# ./realserver.sh start |
4.2 lb端
配置lb1和lb2,lb1和lb2为双主的负载均衡器,基于LVS和keepalived配置。
由于我们使用ospf来实现高可用,所以keepalived不需要配置vrrp功能。keepalived只使用期后端服务检测功能。
在keepalived-LVS集群的抢占模式下,master节点的网卡挂在VIP,此时VIP的设备是唯一的。但是在OSPF-LVS集群下,router根据ospf信息,通过修改报文的目的mac地址,转发到对应的LVS来实现负载均衡。并不根据VIP对应的arp信息,所以对应的每台LVS将VIP挂载在lo上。
- 配置keepalived
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
yum install keepalived -y [root@localhost ~]# cat /etc/keepalived/keepalived.conf global_defs { router_id LVS1 #路由器标识 script_user root enable_script_security } virtual_server 10.0.1.100 80 { #此处是VIP delay_loop 5 #定义健康检查的时间间隔,单位为秒。 lb_algo rr #后端的负载均衡算法,rr为round-robin lb_kind DR #lvs的调度类型,DR/TUN/NAT #persistence_timeout 60 #保持客户端的请求在<INT>时间段内全部发到同一个真实服务器。适用于动态网页session共享的环境。默认六分钟。 persistence_granularity 255.255.255.255 #会话保持粒度,配合persistence_timeout使用,通过子网掩码来定义会话保持对一个IP生效还是对一组IP生效。默认值为255.255.255.255,表示单个客户端分配到一个RS上;255.255.255.0表示客户端IP所在的整个网段的请求都会分配给同一台RS protocol TCP # 使用协议,TCP|UDP|SCTP inhibit_on_failure on #配置该项,在检测到后端RS节点故障后将weight值改为0,而不是从IPVS中删除 ha_suspend # 在LB节点状态从Master切换到Backup时,不启用对RS节点的健康检查 sorry_server 127.0.0.1 80 real_server 10.0.1.131 80 { weight 10 HTTP_GET { url { path / status_code 200 } connect_port 80 connect_timeout 2 retry 1 delay_before_retry 1 } } real_server 10.0.1.129 80 { weight 10 HTTP_GET { url { path / status_code 200 } connect_port 80 connect_timeout 2 retry 1 delay_before_retry 1 } } } [root@localhost ~]# systemctl reload keepalived [root@localhost ~]# systemctl enable keepalived 验证结果: [root@localhost ~]# ipvsadm -L IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP localhost.localdomain:http rr -> 10.0.1.129:http Route 10 0 0 -> 10.0.1.131:http Route 10 0 0 [root@localhost ~]#
- 配置vip
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
[root@localhost ~]#ifconfig lo:0 10.0.1.100 netmask 255.255.255.255 up [root@localhost ~]# ifconfig ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.1.133 netmask 255.255.255.0 broadcast 10.0.1.255 inet6 fe80::af35:1bc3:d630:16c1 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:4a:64:33 txqueuelen 1000 (Ethernet) RX packets 169865 bytes 20546055 (19.5 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 131247 bytes 23749082 (22.6 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 746 bytes 57280 (55.9 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 746 bytes 57280 (55.9 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 10.0.1.100 netmask 255.255.255.255 loop txqueuelen 1000 (Local Loopback) [root@localhost ~]#
- 配置quagga
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 36
[root@localhost ~]# yum install quagga -y [root@localhost ~]# cat /etc/quagga/ospfd.conf hostname 10.0.1.133 #用主机ip代替即可 password test log file /var/log/quagga/ospfd.log log stdout log syslog service password-encryption interface ens33 #主机ip所在的网卡名 ip ospf hello-interval 1 ip ospf dead-interval 4 ip ospf priority 0 ip ospf cost 1 router ospf ospf router-id 10.0.1.133 #用主机ip代替 log-adjacency-changes network 10.0.1.0/24 area 0.0.0.0 access-list 1 permit 127.0.0.1 line vty access-class 1 [root@localhost ~]# cat /etc/quagga/zebra.conf hostname 10.0.1.133 # 主机ip代替 password test enable password test log file /var/log/quagga/zebra.log service password-encryption interface ens33 access-list 1 permit 127.0.0.1 ip prefix-list ANY seq 5 permit 0.0.0.0/0 le 32 route-map ANY deny 10 match ip address prefix-list ANY ip protocol ospf route-map ANY line vty access-class 1 [root@localhost ~]# systemctl start zebra [root@localhost ~]# systemctl start ospfd
4.3 router端
quagga配置
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 36 37 38 39 40 |
//开启转发 [root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward //Router作为网关的接口必须开启arp proxy: [root@localhost ~]# echo 1 > /proc/sys/net/ipv4/conf/ens33/proxy_arp [root@localhost ~]# yum install -y quagga [root@localhost ~]# cat /etc/quagga/ospfd.conf hostname 10.0.1.136 #主机ip地址 password test log file /var/log/quagga/ospfd.log log stdout log syslog service password-encryption interface ens33 ip ospf hello-interval 1 ip ospf dead-interval 4 ip ospf priority 1 ip ospf cost 1 router ospf ospf router-id 10.0.1.136 log-adjacency-changes network 10.0.1.0/24 area 0.0.0.0 access-list 1 permit 127.0.0.1 line vty access-class 1 [root@localhost ~]# cat /etc/quagga/zebra.conf hostname 10.0.1.136 # HOSTNAME改为IP也可以 password test enable password test log file /var/log/quagga/zebra.log #log syslog service password-encryption interface ens33 access-list 1 permit 127.0.0.1 ip prefix-list ANY seq 5 permit 0.0.0.0/0 le 32 route-map ANY permit 10 #将ospf路由映射到kernel match ip address prefix-list ANY ip protocol ospf route-map ANY line vty access-class 1 [root@localhost ~]# |
验证结果:可以看到访router到达vip 10.0.1.100有两条链路,一条是10.0.1.133(lb1),一条是10.0.1.135(lb2)
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 |
[root@localhost ~]# vtysh Hello, this is Quagga (version 0.99.22.4). Copyright 1996-2005 Kunihiro Ishiguro, et al. localhost.localdomain# show ip ospf neighbor Neighbor ID Pri State Dead Time Address Interface RXmtL RqstL DBsmL 10.0.1.133 0 Full/DROther 3.274s 10.0.1.133 ens33:10.0.1.136 0 0 0 10.0.1.135 0 Full/DROther 3.934s 10.0.1.135 ens33:10.0.1.136 0 0 0 localhost.localdomain# show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, A - Babel, > - selected route, * - FIB route K>* 0.0.0.0/0 via 10.0.1.2, ens33 O 10.0.1.0/24 [110/1] is directly connected, ens33, 00:03:18 C>* 10.0.1.0/24 is directly connected, ens33 O>* 10.0.1.100/32 [110/11] via 10.0.1.133, ens33, 00:03:09 * via 10.0.1.135, ens33, 00:03:09 C>* 127.0.0.0/8 is directly connected, lo localhost.localdomain# exit [root@localhost ~]# ip route default via 10.0.1.2 dev ens33 proto dhcp metric 100 10.0.1.0/24 dev ens33 proto kernel scope link src 10.0.1.136 metric 100 10.0.1.100 proto zebra metric 11 nexthop via 10.0.1.133 dev ens33 weight 1 nexthop via 10.0.1.135 dev ens33 weight 1 [root@localhost ~]# |
4.4 client端
client端,需要配置路由,针对访问VIP的请求均跳转到router,这样router就可以利用ospf的ECMP,将流量分发到后端的lb1和lb2。
5. 结果验证
为了验证router确实最client端数据做了分流。将后端lb做了改动,lb1来对接real_server1, lb2来对接real_server2。通过返回的信息就可以确定lb是否为真的双活。
client1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[root@localhost ~]# ifconfig|grep 10.0 inet 10.0.1.138 netmask 255.255.255.0 broadcast 10.0.1.255 ether 00:0c:29:c8:e5:37 txqueuelen 1000 (Ethernet) loop txqueuelen 1000 (Local Loopback) [root@localhost ~]# ip route default via 10.0.1.2 dev ens33 proto dhcp metric 100 10.0.1.0/24 dev ens33 proto kernel scope link src 10.0.1.138 metric 100 10.0.1.100 via 10.0.1.136 dev ens33 [root@localhost ~]# traceroute 10.0.1.100 traceroute to 10.0.1.100 (10.0.1.100), 30 hops max, 60 byte packets 1 10.0.1.136 (10.0.1.136) 0.260 ms 0.146 ms 0.146 ms 2 10.0.1.100 (10.0.1.100) 0.293 ms 0.303 ms 0.226 ms [root@localhost ~]# curl 10.0.1.100 server 10.0.1.129 [root@localhost ~]# |
client2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[root@localhost ~]# ifconfig|grep 10.0 inet 10.0.1.137 netmask 255.255.255.0 broadcast 10.0.1.255 ether 00:0c:29:09:ae:d5 txqueuelen 1000 (Ethernet) loop txqueuelen 1000 (Local Loopback) [root@localhost ~]# ip route default via 10.0.1.2 dev ens33 proto dhcp metric 100 10.0.1.0/24 dev ens33 proto kernel scope link src 10.0.1.137 metric 100 10.0.1.100 via 10.0.1.136 dev ens33 [root@localhost ~]# traceroute 10.0.1.100 traceroute to 10.0.1.100 (10.0.1.100), 30 hops max, 60 byte packets 1 10.0.1.136 (10.0.1.136) 0.278 ms 0.180 ms 0.091 ms 2 10.0.1.100 (10.0.1.100) 0.452 ms 0.370 ms 0.266 ms [root@localhost ~]# curl 10.0.1.100 server 10.0.1.131 [root@localhost ~]# |
参考文献
- https://www.cnblogs.com/lipengxiang2009/p/7451050.html
- linux – 【均衡负载之LVS 系列四】 – OSPF(ECMP)-LVS 集群 – 个人文章 – SegmentFault 思否
今天的文章ecmp 负载均衡_nginx负载均衡策略配置分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/84935.html