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