最近跟大家分享一個 2020 年初左右的問題,這個問題的徵狀使用者透過 service 去存取相關服務時,會一直遲遲連接不上,直到 63 秒後服務才會通。
這個問題有兩種類型,一個是 63 秒後服務會通,一個則是 1 秒後會通,兩個背後的原因都一樣,這邊就來稍微簡介一下這個問題
# 發生條件
1. 使用 VXLAN 作為底層 Overlay Network,最常見的就是 Flannel 這套 CNI
2. Kubernetes 的版本不能太舊,至少要 1.16 以後,不過目前這個問題已經修復,所以現在要撞到除非特別指定版本
3. 使用的 Linux Kernel 版本也不能太新,目前該問題已經修復於大部分的 upstream
# 發生原因
1. VXLAN 本身是一個基於 UDP 的封裝協議,有一個已知的 bug 會使得其 checksum 發生錯誤,導致封包不會被遠端接收方給接收
2. kube-proxy 內關於 iptables 的設定沒有妥善,導致 VXLAN 封包會進行二次 SNAT
3. 第二次的 SNAT 就會觸發(1) 的 bug(當然還有其他條件,但是那些條件也剛好符合)
,最後導致封包的 checksum 不同,因此送到遠方就被拒絕
4. 底層的 TCP 建立連線時,會不停地嘗試,每次失敗都會等待更多時間,分別是1,2,4,8,16,32秒
5. 五次都失敗後, TCP 就會觸發重傳機制,下一次的重傳就不會進入到第二次的 SNAT,因此封包就不會踩到問題,因此通過
# 解決方法
1. 基本上這個問題要踩到要各方一起努力才會踩到,也因此修復方式也是多元化
2. Kernel 本身修復了關於 UDP 封裝的 Checksum 計算
3. Kubernetes 這邊則是針對 kube-proxy 進行強化,其使用的 iptables 規則會避免二次 SNAT 的情況
# 其他問題
1. 為什麼 TCP 重送後就不會踩到二次 SNAT? 這部分我看了相關的 issue 以及諸多文章都沒有看到解釋,都在探討 SNAT 後產生的 checksum,至於為什麼 TCP 重送後就通則是一個謎底
2. 為了解決這個謎體,我特別指定 kubernetes 版本並且重新編譯 Ubuntu 的 Linux Kernel 版本,盼望從 Kernel 中來觀察並且理解這個問題,目前已經有一些初步的進度。之後完成後會在撰寫文章跟大家分享這個問題
這個問題我認為非常有趣,也許自己的環境剛好沒有踩到,但是可以透過觀察不同的 issue 來研究各式各樣問題,也藉由這些過程來學習
相關 PR: https://github.com/kubernetes/kubernetes/pull/92035
同時也有10000部Youtube影片,追蹤數超過2,910的網紅コバにゃんチャンネル,也在其Youtube影片中提到,...
「kube-proxy iptables」的推薦目錄:
- 關於kube-proxy iptables 在 矽谷牛的耕田筆記 Facebook 的最佳貼文
- 關於kube-proxy iptables 在 矽谷牛的耕田筆記 Facebook 的最佳貼文
- 關於kube-proxy iptables 在 コバにゃんチャンネル Youtube 的最讚貼文
- 關於kube-proxy iptables 在 大象中醫 Youtube 的最讚貼文
- 關於kube-proxy iptables 在 大象中醫 Youtube 的最讚貼文
- 關於kube-proxy iptables 在 Deep Dive kube-proxy with iptables mode - 磕磕绊绊的蜗牛 的評價
- 關於kube-proxy iptables 在 kube-proxy would not update iptables rules when pod ... 的評價
- 關於kube-proxy iptables 在 How to find which mode kube-proxy is running in - Stack ... 的評價
- 關於kube-proxy iptables 在 想知道kube-proxy 如何利用iptables 將連入Service 的流量轉送 ... 的評價
- 關於kube-proxy iptables 在 iptables is the best-available proxy, while ipvs has advantages ... 的評價
- 關於kube-proxy iptables 在 Cilium github - Vo Zenaide 的評價
kube-proxy iptables 在 矽谷牛的耕田筆記 Facebook 的最佳貼文
今天這篇文章來分享一下對於昨天所談的 UDP Race Condition 的解法,主要是針對 Kubernetes dns 問題去探討,
一個作法就是透過 nodelocaldns 這種不同的架構,該架構下會於每個節點上部屬一個 DNS Cache,所有該節點上的 Pod 都會透過 UDP 與該 DNS Cache 溝通。 而這段網路請求因為發生於同節點上,所以 kube-proxy 產生的規則不會介入,因此那些 iptables/ipvs/conntrack 就不會影響到,就不會產生上次所說的 bug.
接者,每個節點上的 DNS cache 會透過 TCP 的方式去跟 kube-dns 來詢問最後的答案,透過 TCP 重送的方式來減緩封包遺失造成的 timeout 問題
https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/
https://github.com/kubernetes/kubernetes/issues/56903
kube-proxy iptables 在 kube-proxy would not update iptables rules when pod ... 的推薦與評價
iptables rules are also created by kube-proxy: ... NAME ENDPOINTS AGE kubernetes 192.168.122.58:6443 14d nginx-service 192.0.42.101:9999 23m. ... <看更多>
kube-proxy iptables 在 How to find which mode kube-proxy is running in - Stack ... 的推薦與評價
... <看更多>
kube-proxy iptables 在 Deep Dive kube-proxy with iptables mode - 磕磕绊绊的蜗牛 的推薦與評價
summary: in Kubernetes, a Service is a L4(TCP/UDP/SCTP) load balancer, it uses the DNAT to redirect inbound traffic to backend pods. ... <看更多>