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