一、前言
本文針對我們生產(chǎn)上出現(xiàn)的流量不均的問題,介紹一下解決方案。
k8s是一個特別復(fù)雜的系統(tǒng),而網(wǎng)絡(luò)相關(guān)的問題是其中最復(fù)雜的問題,要通過一兩篇文章介紹清楚是很難的。這個流量不均的問題出現(xiàn)的原因并不復(fù)雜,就是因為kube-proxy使用了默認(rèn)的iptables做負(fù)載均衡,而它是以概率的方式轉(zhuǎn)發(fā),使用長連接且連接數(shù)較少時,偏差會比較大。下面介紹兩種場景。
二、場景
2.1滾動更新負(fù)載不均
在連接數(shù)比較固定或波動不大的情況下,滾動更新時,舊 Pod 上的連接逐漸斷掉,重連到新啟動的 Pod 上,越先啟動的 Pod 所接收到的連接數(shù)越多,造成負(fù)載不均:
2.2rr 策略負(fù)載不均
假如長連接服務(wù)的不同連接的保持時長差異很大,而 ipvs 轉(zhuǎn)發(fā)時默認(rèn)是 rr 策略轉(zhuǎn)發(fā),如果某些后端 Pod "運(yùn)氣較差",它們上面的連接保持時間比較較長,而由于是 rr 轉(zhuǎn)發(fā),它們身上累計的連接數(shù)就可能較多,節(jié)點(diǎn)上通過 ipvsadm -Ln -t CLUSTER-IP:PORT 查看某個 service 的轉(zhuǎn)發(fā)情況:
我們發(fā)現(xiàn)部分 Pod 連接數(shù)高,它們相比連接數(shù)低的 Pod 要同時處理更多的連接,消耗的資源也就相對更多從而造成負(fù)載不均。
將 kube-proxy 的 ipvs 轉(zhuǎn)發(fā)模式設(shè)置為 lc (Least-Connection) ,即傾向轉(zhuǎn)發(fā)給連接數(shù)少的 Pod,可能會有所緩解,但也不一定,因為 ipvs 的負(fù)載均衡狀態(tài)是分散在各個節(jié)點(diǎn)的,并沒有收斂到一個地方,也就無法在全局層面感知哪個 Pod 上的連接數(shù)少,并不能真正做到 lc。可以嘗試設(shè)置為 sh (Source Hashing),并且這樣可以保證即便負(fù)載均衡狀態(tài)沒有收斂到同一個地方,也能在全局盡量保持負(fù)載均衡。
這邊很多對kupe-proxy的ipvs模式可能不太了解,ipvs和iptables都是基于netfilter的,兩者差別如下:
ipvs 為大型集群提供了更好的可擴(kuò)展性和性能
ipvs 支持比 iptables 更復(fù)雜的負(fù)載均衡算法(最小負(fù)載、最少連接、加權(quán)等等)
ipvs 支持服務(wù)器健康檢查和連接重試等功能
2.3、擴(kuò)容失效問題 在連接數(shù)比較固定或波動不大的情況下,工作負(fù)載在 HPA 自動擴(kuò)容時,由于是長鏈接,連接數(shù)又比較固定,所有連接都 "固化" 在之前的 Pod 上,新擴(kuò)出的 Pod 幾乎沒有連接,造成之前的 Pod 高負(fù)載,而擴(kuò)出來的 Pod 又無法分擔(dān)壓力,導(dǎo)致擴(kuò)容失效:
三、最佳實踐
業(yè)務(wù)層面自動重連,避免連接 "固化" 到某個后端 Pod 上。比如周期性定時重連,或者一個連接中處理的請求數(shù)達(dá)到閾值后自動重連。
不直接請求后端,通過七層代理訪問。比如 gRPC 協(xié)議,可以 使用 nginx ingress 轉(zhuǎn)發(fā) gRPC,也可以 使用 istio 轉(zhuǎn)發(fā) gRPC,這樣對于 gRPC 這樣多個請求復(fù)用同一個長連接的場景,經(jīng)過七層代理后,可以自動拆分請求,在請求級別負(fù)載均衡。
kube-proxy 的 ipvs 轉(zhuǎn)發(fā)策略設(shè)置為 sh (--ipvs-scheduler=sh)。
編輯:黃飛
-
負(fù)載均衡
+關(guān)注
關(guān)注
0文章
101瀏覽量
12346
原文標(biāo)題:K8S之長連接負(fù)載均衡問題
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論