问题背景
IPv6环境下,在浏览器中通过http://[vip:port]
访问web
业务,提示无法访问此网站,[vip]
的响应时间过长。
分析过程
之前碰到过多次在PC浏览器上无法访问vip
的情况,排查方法也很明确:
- 在集群的
vip
所在节点上访问是否正常; - 在集群范围内其他节点上访问是否正常;
- 在集群之外的同网段
linux
环境上访问是否正常; - 在其他环境的PC浏览器上访问是否正常;
验证发现,直接在vip
所在节点上访问竟然不通!登录vip
所在节点执行ip addr
可以看到该地址确实是正确配置了,但 ping6
该地址无回应,对应的ipv4
地址 ping
有回应。按说ping
本机的地址不应该和链路的状态有关系,那会是什么原因呢?在仔细检查地址配置情况后发现该地址有个标记tentative dadfailed
;
1 | 17: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 |
ip-address(8) 查到对该标记的解释如下:
1 | tentative |
显然该地址没有通过地址重复探测(duplicate address detection
,简称dad
),而且这种检查机制只针对IPv6
。经确认,该环境的IPv6
网段只有自己在用,且未手工配置过IPv6
地址,但该环境曾经发生过切主;
至此问题基本明确了,切主时会把老的主节点上的vip
删除,再到新的主节点上把vip
添加上去。如果一切正常,按照这个顺序切主没有问题,但也存在某些异常情况(比如老主上的vip
没有及时删掉,而新主上已经添加好了),此时就会触发dad
机制。经过验证,一旦出现dadfailed
,即使地址冲突解决了,该地址依然无法访问;
解决方案
方案1:在sysctl
配置中增加如下内核参数:
1 | net.ipv6.conf.all.accept_dad = 0 |
方案2:在ip addr add
命令执行时增加nodad
标识:
1 | ip addr add 2000::10:18/128 dev eth0 nodad |