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