由于服务器数量限制,所以将keepalived和nginx装在同一台,结果出现了一个很奇葩的问题,在这儿描述一下。
拓补图:(虽然是同一台,但是还是照下面的架构)
配置文件:(这儿只放keepalived主节点配置文件)
global_defs {
router_id master_015
}
vrrp_instance VI_1 {
state MASTER
interface eth0
lvs_sync_daemon_inteface eth0
virtual_router_id 51
priority 180
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
10.97.10.100
}
}
virtual_server 10.97.10.100 80 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 30
protocol TCP
real_server 10.97.10.15 80 {
weight 100
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 10.97.10.16 80 {
weight 100
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
环境情况大致如上。
现在出现的问题就是,通过VIP访问80端口,会出现时通时不通的情况,注意是时通时不通,而不是一直不通 ,而且只有80端口出现这个问题,我们在keepalived下还配置了MariaDB集群,Redis集群,都没有出现这个问题。
(这个问题前段时间提过一次问,可能是描述的问题,所以一直没有人回答:)
检查各个参数,VIP飘移情况,日志都是正常的。最初怀疑是网络的问题,但后续也排除了,抓报文,请求已经到达了服务器,是服务器没有返回。
然而并不会调试源码,所以开始各种折腾~省略10000字。。。
最后发现关键点就在 时通时不通
如图:通过VIP访问,请求会先到达A的LVS,然后根据权重选举真实服务器,接着将请求的报文改为选举出来真实服务器的MAC地址,并将报文广播至当前LAN中。此时arp协议会根据MAC地址找到真实服务IP将报文传给它。但是~~当选举出来的是A节点的Nginx,那就没问题,访问正常,关键是当选举出来的是B节点的Nginx,此时报文传到B节点,但是B节点也有LVS,会首先将其拦截了,然后再选举一次。。。如图所示,是不是发现有一定几率会出现报文在LVS之间来回跳(抓包应该体现在Mac地址上的变化)的死循环。
这就是为什么会出现时通时不通的情况。。
解决办法:
1、将keepalived放在独立的服务器,折中一下放在不归它自己负载服务的服务器;
2、采用热双机互备的模式,但是会启用多个VIP,然后当同一台服务器的keepalived或Nginx挂了,那么这台服务器都将不可用,可用性差了;
3、两台服务器通过脚本及crond定时任务去互相检测对方80端口,以此来起停nginx服务,保持始终只有一台Nginx是启动的,另一台是关闭的。
3、哪位大神还有其它解决办法或是我没有说到的,希望分享一下哇~