tw_recycle引發(fā)的故障

背景

因后續(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ú)


image.png

嘗試在該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后被移除

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容