問(wèn)題背景
IPv6環(huán)境下,在瀏覽器中通過(guò)http://[vip:port]訪問(wèn)web業(yè)務(wù),提示無(wú)法訪問(wèn)此網(wǎng)站,[vip]的響應(yīng)時(shí)間過(guò)長(zhǎng)。
分析過(guò)程
之前碰到過(guò)多次在PC瀏覽器上無(wú)法訪問(wèn)vip的情況,排查方法也很明確:
- 在集群的vip所在節(jié)點(diǎn)上訪問(wèn)是否正常;
- 在集群范圍內(nèi)其他節(jié)點(diǎn)上訪問(wèn)是否正常;
- 在集群之外的同網(wǎng)段linux環(huán)境上訪問(wèn)是否正常;
- 在其他環(huán)境的PC瀏覽器上訪問(wèn)是否正常;
驗(yàn)證發(fā)現(xiàn),直接在vip所在節(jié)點(diǎn)上訪問(wèn)竟然不通!登錄vip所在節(jié)點(diǎn)執(zhí)行ip addr可以看到該地址確實(shí)是正確配置了,但 ping6該地址無(wú)回應(yīng),對(duì)應(yīng)的ipv4地址 ping有回應(yīng)。按說(shuō)ping本機(jī)的地址不應(yīng)該和鏈路的狀態(tài)有關(guān)系,那會(huì)是什么原因呢?在仔細(xì)檢查地址配置情況后發(fā)現(xiàn)該地址有個(gè)標(biāo)記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
inet 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) 查到對(duì)該標(biāo)記的解釋如下:
tentative
(IPv6 only) only list addresses which have not yet passed duplicate address detection.
顯然該地址沒有通過(guò)地址重復(fù)探測(cè)(duplicate address detection,簡(jiǎn)稱dad),而且這種檢查機(jī)制只針對(duì)IPv6。經(jīng)確認(rèn),該環(huán)境的IPv6網(wǎng)段只有自己在用,且未手工配置過(guò)IPv6地址,但該環(huán)境曾經(jīng)發(fā)生過(guò)切主;
至此問(wèn)題基本明確了,切主時(shí)會(huì)把老的主節(jié)點(diǎn)上的vip刪除,再到新的主節(jié)點(diǎn)上把vip添加上去。如果一切正常,按照這個(gè)順序切主沒有問(wèn)題,但也存在某些異常情況(比如老主上的vip沒有及時(shí)刪掉,而新主上已經(jīng)添加好了),此時(shí)就會(huì)觸發(fā)dad機(jī)制。經(jīng)過(guò)驗(yàn)證,一旦出現(xiàn)dadfailed,即使地址沖突解決了,該地址依然無(wú)法訪問(wèn);
解決方案
方案1:在sysctl配置中增加如下內(nèi)核參數(shù):
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命令執(zhí)行時(shí)增加nodad標(biāo)識(shí):
ip addr add 2000::10:18/128 dev eth0 nodad
參考資料
- https://blog.clanzx.net/network/ipv6-dad.html