1. 问题描述
在网络没有搭错的情况下,DR模式LVS不能正常负载调度。
(注:还没有设置防火墙DNAT,直接访问VIP)
LBC:
[root@C7Base03 ~]# 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.20.100:80 rr
-> 192.168.20.14:80 Route 1 0 0
-> 192.168.20.15:80 Route 1 0 0
[root@C7Base03 ~]#
调度情况:
[root@C7Base01 ~]# curl 192.168.20.100; curl 192.168.20.100
from RS2...
from RS2...
[root@C7Base01 ~]#
2. 集群架构规划
3. 错误原因
没有修改两台真实服务器的arp_ignore参数,或者修改错误。
导致后端的真实服务器RS-1和RS-2的回环网卡中设置的VIP回应了路由器的arp广播,在作为路由器的虚拟机的路由表(arp命令查看)中存入了错误的条目。
看网上很多的帖子都是设置的:(包括有些讲师也是这样讲的)
vim /etc/sysctl.conf
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.lo.arp_announce=2net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
这个设置不能算数错误,但是一定是没有明白其中的机理。
4. 重点原理
回环网卡lo和网卡ens33是物理隔离的,不在一个网段,在回环网卡上加一个IP,默认设置下(net.ipv4.conf.lo.arp_ignore=0)是不会把回应ens33所在局域网的arp广播的。
所以net.ipv4.conf.lo.arp_ignore=1是无效设置。
如果只设置这一条,那么就会出现不能正常调度的问题,此时真实服务器RS-1和RS-2的ens33网卡是会回应arp广播的,会导致在路由服务器的路由表中VIP对应一个真实服务器的情况。如下:
[root@C7Base02 ~]# arp
Address HWtype HWaddress Flags Mask Iface
192.168.20.100 ether 00:0c:29:aa:56:9b C ens34
192.168.20.14 ether 00:0c:29:aa:56:9b C ens34
....
[root@C7Base02 ~]#
此时再curl VIP根本不会走调度器,而是直接从路由到真实服务器。这就是调度器失效的原因。
此时,调度器的ens33:0网卡或许根本就不会开启,因为IP被真实服务器的IP占了(arp协议的机制,先到先得)。
所以,我们需要约束的其实是真实服务器RS-1和RS-2的ens33的arp广播的响应。
5. 解决问题
vim /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore=1
#或者
net.ipv4.conf.ens33.arp_ignore=1
#查看是否设置成功,默认值为0
sysctl -a | grep arp_ignore
net.ipv4.conf.all.arp_announce参数可以不设置,应为在这个架构中真实服务器不发arp广播,只接收和回应arp广播。
查看参数设置:
[root@C7Base04 ~]# sysctl -a | grep arp_ignore
net.ipv4.conf.all.arp_ignore = 0
net.ipv4.conf.default.arp_ignore = 0
net.ipv4.conf.ens33.arp_ignore = 1
net.ipv4.conf.ens34.arp_ignore = 0
net.ipv4.conf.lo.arp_ignore = 0
net.ipv4.conf.virbr0.arp_ignore = 0
net.ipv4.conf.virbr0-nic.arp_ignore = 0
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"
sysctl: reading key "net.ipv6.conf.ens34.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret"
[root@C7Base04 ~]#