公有云 Loadbalancer 與 Cilium 網(wǎng)絡(luò)組件聯(lián)通故障一例

我是 LEE岁经,老李隐锭,一個(gè)在 IT 行業(yè)摸爬滾打 16 年的技術(shù)老兵携悯。

事件背景

我們的幾個(gè)核心 k8s 集群規(guī)則持續(xù)增長(zhǎng)获询,網(wǎng)絡(luò)穩(wěn)定性和效能之間的平衡性成為目前主要需要攻克的問題。目前單個(gè)集群的節(jié)點(diǎn) 270+ 漠酿、Pod 40000+ 冯凹,這樣的規(guī)模 Pod 之間的請(qǐng)求流量規(guī)模十分巨大,而且網(wǎng)絡(luò)流量壓力對(duì)傳統(tǒng)的 k8s 網(wǎng)絡(luò)組件壓力很大炒嘲。為了要解決這個(gè)問題宇姚,我把目標(biāo)轉(zhuǎn)向了基于 ebpf 的 cilium 組件匈庭,決定使用 cilium 來替換 kubelet 中的 kubenet 組件。

我選擇了一個(gè)有點(diǎn)量的測(cè)試 k8s 集群浑劳,安裝了 cilium 1.11.8 后阱持,做了集群內(nèi)部的網(wǎng)絡(luò)測(cè)試,Pod 到節(jié)點(diǎn)以及 Pod 之間都是可以 ping 通呀洲,而且端口訪問是正常紊选。隨后我們對(duì)外發(fā)布測(cè)試服務(wù)的時(shí)候,發(fā)現(xiàn)外部無法連接到測(cè)試 k8s 集群內(nèi)的應(yīng)用道逗。這個(gè)事情讓我百思不得其解,明明網(wǎng)絡(luò)測(cè)試都是 OK 的献烦,為什么對(duì)外發(fā)布的測(cè)試服務(wù)卻無法正常訪問滓窍。

現(xiàn)象獲取

這個(gè)時(shí)候拉來了底層云平臺(tái)供應(yīng)商的小伙伴一起排查,也是毫無進(jìn)展巩那。此時(shí)我只能逐一層次網(wǎng)絡(luò)測(cè)試排查吏夯,通過一個(gè)下午的排查,最后發(fā)現(xiàn)外部直接訪問 Pod 提供的服務(wù)是 OK即横,但是通過 Service 中 Loadbalancer 模式發(fā)布的服務(wù)確實(shí)訪問不通的噪生。

我們登錄到云供應(yīng)商上的 Loadbalancer 服務(wù)上,查看對(duì)應(yīng)服務(wù)實(shí)例的狀態(tài)和日志东囚。通過觀察跺嗽,發(fā)現(xiàn) Loadbalancer upstream 的 RealServer 狀態(tài)不停的翻滾,一會(huì)狀態(tài)“健康”页藻,一會(huì)狀態(tài)“異辰凹蓿”。我想這個(gè)“現(xiàn)象”應(yīng)該是導(dǎo)致外部流量沒有辦法通過 Loadbalancer 到后端服務(wù)的原因份帐。

公有云的 Loadbalancer 與后端健康檢測(cè)異常

另外一個(gè)問題:我們直接訪問 Node 和 Pod 的端口提供的服務(wù)都是正常的璃吧,但是 Loadbalancer 健康檢測(cè)這個(gè)服務(wù)端口卻是失敗的?

一看究竟就必須要請(qǐng)出 tcpdump 大法废境,抓包復(fù)原 Loadbalancer 健康檢測(cè)會(huì)話流畜挨。

健康檢測(cè)會(huì)話流分析

正常情況

公有云的 Loadbalancer 正確健康檢測(cè)步驟

按照原供應(yīng)商小伙伴提供的信息,同時(shí)結(jié)合抓包結(jié)果噩凹,我們得知正常的一個(gè)健康檢測(cè)是:

  1. Loadbalancer --> RealServer: sync
  2. RealServer --> Loadbalancer: sync,ack
  3. Loadbalancer --> RealServer: rst,ack

公有云的 Loadbalancer 會(huì)與 RealServer 嘗試建立 tcp 連接巴元,1,2 步交換 syncsync,ack栓始,Loadbalancer 再收到了 sync,ack务冕,就會(huì)向 RealServer 發(fā)送 rst,ack 關(guān)閉 tcp 連接,成功完成一次健康檢測(cè)

異常情況

公有云的 Loadbalancer 異常健康檢測(cè)步驟

我們看過了正常的健康檢測(cè)的樣子幻赚,那么我們這邊公有云的 Loadbalancer 健康異常檢測(cè)如上圖所示禀忆。
經(jīng)過分析臊旭,總結(jié)出現(xiàn)異常的情況如下:

  1. Loadbalancer --> RealServer 發(fā)送了 sync
  2. Loadbalancer --> RealServer RealServer 沒有回應(yīng) sync,ack,然后公有云 Loadbalancer 嘗試重傳 sync
  3. RealServer(另外 IP) --> Loadbalancer 另外一個(gè) IP 的 RealServer 回應(yīng) sync,ack

感覺到了一絲絲不對(duì)的情況箩退,我想心細(xì)的小伙伴應(yīng)該看到了問題所在离熏。問題出現(xiàn)在 RealServer --> Loadbalancer 這里,為什么回應(yīng) Loadbalancer 的 RealServer IP 地址不對(duì)戴涝,導(dǎo)致 Loadbalancer 認(rèn)為正確的 RealServer 沒有回應(yīng)自己的檢測(cè)滋戳,隨之將此 RealServer 的狀態(tài)標(biāo)記成“異常”啥刻。

原理分析

在沉思片刻后奸鸯,我覺得最復(fù)雜的問題導(dǎo)致的原因可能最簡(jiǎn)單,一定是 cilium 組件哪里設(shè)置有問題可帽,因?yàn)楣性?Loadbalancer 到后端 Pod 的這樣業(yè)務(wù)模型在其他的沒有部署 cilium 的集群內(nèi)都是正常娄涩。

既然知道數(shù)據(jù)流的情況,也知道出問題的組件映跟,問題就好解決了蓄拣。

cilium 網(wǎng)絡(luò)架構(gòu)

Cilium 網(wǎng)絡(luò)架構(gòu)

cilium 的安裝命令

helm upgrade -i cilium cilium/cilium --version 1.11.8 --namespace kube-system \
    --set tunnel=disabled \
    --set ipam.mode=kubernetes \
    --set nativeRoutingCIDR=10.192.32.0/19  \
    --set loadBalancer.mode=hybrid \    # 此參數(shù)是問題所在
    --set kubeProxyReplacement=probe \
    --set prometheus.enabled=true \
    --set operator.prometheus.enabled=true \
    --set hubble.enabled=true \
    --set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,http}"

庖丁解牛

結(jié)合 cilium 網(wǎng)絡(luò)架構(gòu)看來看去,最值得懷疑的地方就是 loadBalancer.mode=hybrid 這個(gè)參數(shù)努隙,按照 cilium 官方的參考文檔解釋如下:

Cilium also supports a hybrid DSR and SNAT mode, that is, DSR is performed for TCP and SNAT for UDP connections. This has the advantage that it removes the need for manual MTU changes in the network while still benefiting from the latency improvements through the removed extra hop for replies, in particular, when TCP is the main transport for workloads.

The mode setting loadBalancer.mode allows to control the behavior through the options dsr, snat and hybrid. By default the snat mode is used in the agent.

By default, Cilium’s eBPF NodePort implementation operates in SNAT mode. That is, when node-external traffic arrives and the node determines that the backend for the LoadBalancer, NodePort or services with externalIPs is at a remote node, then the node is redirecting the request to the remote backend on its behalf by performing SNAT. This does not require any additional MTU changes at the cost that replies from the backend need to make the extra hop back that node in order to perform the reverse SNAT translation there before returning the packet directly to the external client.

This setting can be changed through the loadBalancer.mode Helm option to dsr in order to let Cilium’s eBPF NodePort implementation operate in DSR mode. In this mode, the backends reply directly to the external client without taking the extra hop, meaning, backends reply by using the service IP/port as a source. DSR currently requires Cilium to be deployed in Native-Routing, i.e. it will not work in either tunneling mode.

Note that usage of DSR mode might not work in some public cloud provider environments due to the Cilium-specific IP options that could be dropped by an underlying fabric. Therefore, in case of connectivity issues to services where backends are located on a remote node from the node that is processing the given NodePort request, it is advised to first check whether the NodePort request actually arrived on the node containing the backend. If this was not the case, then switching back to the default SNAT mode would be advised as a workaround.

一大堆英文的看完了球恤,大概的意思是同時(shí)使用 NativeRoutingloadBalancer.mode=hybrid,cilium 內(nèi)部的 Loadbalancer 工作在了 DSR 的模式下荸镊。 那么公有云的 Loadbalancer 對(duì)后端 RealServer 檢測(cè)異常的問題就能很好解釋了咽斧。整個(gè)異常的過程跟 DSR 工作模式完全一樣。

處理方法

通過一通復(fù)雜的分析與驗(yàn)證后贷洲,我們?cè)?cilium 的安裝命令中去掉了 loadBalancer.mode=hybrid 參數(shù)收厨,重新部署 cilium,然后重啟相關(guān)的 Pod优构。

最終效果

公有云的 Loadbalancer 與 Node 節(jié)點(diǎn)之間健康檢測(cè)恢復(fù)正常诵叁,對(duì)外發(fā)布的服務(wù)也能夠正常的訪問。

公有云的 Loadbalancer 與后端健康檢測(cè)正常
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钦椭,一起剝皮案震驚了整個(gè)濱河市拧额,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌彪腔,老刑警劉巖侥锦,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異德挣,居然都是意外死亡恭垦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來番挺,“玉大人唠帝,你說我怎么就攤上這事⌒兀” “怎么了襟衰?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)粪摘。 經(jīng)常有香客問我瀑晒,道長(zhǎng),這世上最難降的妖魔是什么徘意? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任苔悦,我火速辦了婚禮,結(jié)果婚禮上映砖,老公的妹妹穿的比我還像新娘间坐。我一直安慰自己,他們只是感情好邑退,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著劳澄,像睡著了一般地技。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上秒拔,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天莫矗,我揣著相機(jī)與錄音,去河邊找鬼砂缩。 笑死作谚,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的庵芭。 我是一名探鬼主播妹懒,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼双吆!你這毒婦竟也來了眨唬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤好乐,失蹤者是張志新(化名)和其女友劉穎匾竿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔚万,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岭妖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昵慌。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡假夺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出废离,到底是詐尸還是另有隱情侄泽,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布蜻韭,位于F島的核電站悼尾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏肖方。R本人自食惡果不足惜闺魏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望俯画。 院中可真熱鬧析桥,春花似錦、人聲如沸艰垂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猜憎。三九已至娩怎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胰柑,已是汗流浹背截亦。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柬讨,地道東北人崩瓤。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像踩官,于是被迫代替她去往敵國(guó)和親却桶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容