背景
因后續(xù)的A/B發(fā)布需要,在k8s環(huán)境中新部署一套程序。在驗(yàn)證過(guò)程中發(fā)現(xiàn)目前對(duì)外提供流量的環(huán)境A,(后續(xù)簡(jiǎn)稱A)可以正常訪問(wèn)集群外部的nginx。但在新部署的環(huán)境B(后續(xù)簡(jiǎn)稱B)卻無(wú)法訪問(wèn)集群外部的nginx(后續(xù)簡(jiǎn)稱C)
歷程
- k8s集群排查
- nginx排查
- C節(jié)點(diǎn)參數(shù)排查
排查
k8s集群排查
1.發(fā)生上訴問(wèn)題的第一個(gè)反應(yīng)是k8s的其中一個(gè)節(jié)點(diǎn)與C節(jié)點(diǎn)網(wǎng)絡(luò)不通導(dǎo)致的
kubectl get pod -n xx -owide |grep aaa
查詢后發(fā)現(xiàn)B中的pod和A中的pod位于同一個(gè)node上。此刻的我陷入沉思。嘗試進(jìn)入pod內(nèi)進(jìn)行curl
curl 172.16.0.50:1301
同樣的命令不同的結(jié)果。在A的pod中直接返回了請(qǐng)求信息,但是在B中卻一直等待響應(yīng)。直至curl超時(shí)。思緒全無(wú)

嘗試在該node節(jié)點(diǎn)進(jìn)行curl。發(fā)生了令人震驚的事情。curl不通,直接提示超時(shí)。
讓我們來(lái)分析一波首先Apod若需要訪問(wèn)C則需要通過(guò)該node節(jié)點(diǎn)的物理網(wǎng)卡于C進(jìn)行通信。即該node節(jié)點(diǎn)與C是能夠通信并建立TCP連接的。
2.由于剛剛將生產(chǎn)環(huán)境的k8s內(nèi)核版本升級(jí)只4.19.12.懷疑是否是內(nèi)核版本與網(wǎng)卡兼容性問(wèn)題導(dǎo)致的。于是乎找了個(gè)未升級(jí)內(nèi)核版本的k8s集群,進(jìn)行模擬驗(yàn)證。發(fā)現(xiàn)當(dāng)pod與C建立連接后,pod所在節(jié)點(diǎn)無(wú)法與C建立TCP連接。直至pod與C的TCP連接斷開(kāi)。所在節(jié)點(diǎn)可以與C建立連接。排查到這里,問(wèn)題答案似乎呼之欲出。似乎是pod建立了TCP連接占據(jù)了
nginx排查
根據(jù)上述的問(wèn)題,懷疑是nginx問(wèn)題,不是k8s集群?jiǎn)栴}。故把B的pod流量指向另一節(jié)點(diǎn)D上。(D上的nginx與C的nginx完全一致)在Bpod訪問(wèn)D時(shí),手動(dòng)在node節(jié)點(diǎn)curl。發(fā)現(xiàn)正??梢栽L問(wèn)
C節(jié)點(diǎn)排查
由于都是TCP??的問(wèn)題,所以面對(duì)google上去搜索了下 TCP 連接超時(shí)等關(guān)鍵字發(fā)現(xiàn)下面這片文章
https://juejin.im/post/6844903800323473422
文章中指出
SYN 重傳,第三次握手被重傳了,沒(méi)有收到服務(wù)器放的ACK確認(rèn)
在服務(wù)器上抓包能捕獲SYN的請(qǐng)求,那就說(shuō)明服務(wù)器端接收到了請(qǐng)求但是沒(méi)有回應(yīng)ACK包,于是想起了以前nat環(huán)境下tw_recyle的坑,當(dāng)多個(gè)客戶端使用同一個(gè)外網(wǎng)IP通過(guò)NAT訪問(wèn)內(nèi)網(wǎng)服務(wù)器的時(shí)候,服務(wù)器如果在內(nèi)核參數(shù)中打開(kāi)了net.ipv4.tcp_tw_recycle = 1
就有可能導(dǎo)致服務(wù)器收到SYN但是不會(huì)向客戶端發(fā)送SYN+ACK包。因?yàn)榇蜷_(kāi)recyle參數(shù)后會(huì)識(shí)別這些包的時(shí)間戳(net.ipv4.tcp_timestamps = 1),但是nat過(guò)來(lái)的數(shù)據(jù)包又因?yàn)闀r(shí)間戳有可能不是順序的,導(dǎo)致服務(wù)器認(rèn)為包不可信而丟棄。
故當(dāng)我們?cè)谑褂冒⒗镌频腣PC虛擬專網(wǎng)的時(shí)候,使用彈性IP接入,一定要注意NAT的問(wèn)題,在服務(wù)器參數(shù)上關(guān)閉net.ipv4.tcp_tw_recycle。 否則從一個(gè)ip來(lái)的不同客戶端請(qǐng)求很有可能導(dǎo)致大量請(qǐng)求失敗
故查看C節(jié)點(diǎn),發(fā)現(xiàn)開(kāi)啟了net.ipv4.tcp_tw_recycle = 1參數(shù)。
使用下列命令
sysctl -w net.ipv4.tcp_tw_recycle=0
問(wèn)題得以解決
?? 該參數(shù)在 kernel 的4.12后被移除