本文說明如何解決 Kubernetes 服務流量分配不均的問題。
找出流量分配不均的徵兆
流量分配不均 (通常稱為熱點) 是指部分 Pod 或節點處理的工作負載量過多,其他 Pod 或節點則未充分利用。
常見症狀包括:
- 效能瓶頸:使用者可能會在過度使用的網路連線上,遇到間歇性逾時、HTTP 5xx 錯誤或封包遺失。
- 資源耗盡:特定 Pod 或節點的 CPU 或記憶體使用率明顯高於機群中的其他項目。
- 流量失衡模式:
- 每個 Pod 的流量不平衡:即使所有 Pod 都回報為健康狀態良好且已準備就緒,流量仍只會傳送至少數可用的 Pod。
- 節點間負載不均:一或多個節點收到的封包或要求明顯多於其他節點,通常在使用
externalTrafficPolicy: Local時,Pod 放置位置不均就會發生這種情況。 - 黏性用戶端工作階段:來自單一高流量用戶端的所有要求,都會持續轉送至同一個後端 Pod。
使用 Cloud Monitoring 診斷問題
如要確認這些徵兆,請使用下列指標呈現流量模式:
- 第 7 層 (Ingress/Gateway):繪製
loadbalancing.googleapis.com/backend/request_count並依backend_target分組依據,比較不同後端的請求量。
瞭解流量分配不均的常見原因
本節說明 Kubernetes 服務流量分配不均的常見原因。 這種不平衡可能會導致效能瓶頸、特定 Pod 資源耗盡,以及應用程式可用性降低,因為某些 Pod 接收的流量明顯多於其他 Pod,而某些 Pod 接收的流量很少或根本沒有。
工作階段相依性導致分配不均
如果啟用工作階段相依性的負載平衡器,持續將同一用戶端的要求轉送至相同後端 Pod,就會發生下列問題。如果特定用戶端產生大量流量,該 Pod 就會過載,導致熱點的負載量遠高於其他 Pod,而其他 Pod 則未充分利用。
您可以使用 sessionAffinity 欄位,在 Kubernetes Service 物件中設定工作階段相依性。
當 sessionAffinity 設為 ClientIP 時,Service 會確保來自相同用戶端 IP 位址的所有連線,一律路由至相同後端 Pod。這可提供真正的用戶端 IP 工作階段相依性。
如果 sessionAffinity 設為 None (預設行為),第 4 層負載平衡器通常會使用各種網路參數的雜湊值分配連線,例如 4 元組 (用戶端 IP 位址、目的地 IP 位址、目標通訊埠、通訊協定) 或 5 元組 (包含來源通訊埠)。雖然這項雜湊功能可將具有相同元組值的連線一律路由至相同後端,提供某種程度的連線「黏性」,但如果其他元組元素有所變更,就無法保證來自特定用戶端 IP 位址的所有連線一律會連至相同 Pod。
詳情請參閱「工作階段相依性」。
如果是 GKE Gateway,則 GCPTrafficDistributionPolicy CRD 會設定工作階段相依性。詳情請參閱「使用政策設定閘道資源」。
對於區域外部直通式網路負載平衡器,您可以使用工作階段相依性,將連線維持在特定後端。不過,請注意,如果某些用戶端產生的流量比其他用戶端多,工作階段相依性本身可能會導致分配不均。
詳情請參閱「工作階段相依性」和「後端服務型外部直通式網路負載平衡器簡介」。
以下範例顯示含有 sessionAffinity: ClientIP 的 Service 資訊清單:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
sessionAffinity: ClientIP # This can cause uneven distribution
ports:
- port: 80
targetPort: 8080
selector:
app: my-app
連線集區導致分配不均
當負載平衡器重複使用與特定 Pod 的現有連線時,就會發生連線集區,即使其他 Pod 有可用容量也一樣。如果某些連線的存留時間較長,或處理的要求數量明顯多於其他連線,這種行為可能會導致不平衡。這會將流量集中在特定 Pod 上 (類似於工作階段相依性),導致這些 Pod 負載過重,而其他 Pod 則未充分利用。
負載平衡器會實作連線集區,減少建立新連線的負擔,進而提升效能。不過,如果管理不當,連線集區可能會導致流量分配不均,尤其是維護長期連線的應用程式。
為減輕連線集區造成的分配不均問題,請在應用程式或用戶端層級實作策略:
將用戶端設為使用多個連線:不要依賴單一長期連線,而是將用戶端設為開啟及管理負載平衡器的多個連線集區。這樣一來,負載平衡器就能將新的連線嘗試分配至可用的後端 Pod,改善整體流量分配。
定期關閉並重新開啟連線:對於自然維持長期連線的應用程式,請設定應用程式或其用戶端,定期關閉並重新開啟連線。雖然這會稍微增加重新建立連線的負載,但負載平衡器有機會將後續的連線嘗試分配給使用率較低的不同後端 Pod。如果服務不會因連線終止和重新建立而受到過度干擾,就特別適合採用這種做法。
實作積極的連線排除功能:請確認 Pod 已設定為正常關機和連線排除。當 Pod 正常終止時 (例如在部署或縮減期間),負載平衡器應停止向其傳送新連線,並允許現有連線完成或排除。這有助於流量更順暢地轉移至其他 Pod,並避免流量集中在終止 Pod。
主動管理連線行為,可協助負載平衡器更平均地分配流量,即使是長期連線也一樣。
5 元組雜湊導致分配不均
如果未明確設定工作階段相依性,許多第 4 層負載平衡器都會採用這種預設行為。如果許多連線來自同一個用戶端,或使用相同的通訊埠組合,就會導致分配不均。
如要解決雜湊造成的負載不平衡問題,請考慮下列事項:
使用第 7 層負載平衡:GKE Ingress 和 Gateway 會在要求層級運作,因此可將單一用戶端的要求分配至多個後端 Pod。
調整用戶端行為:設定用戶端以使用多個連線或較大的來源連接埠集區。
節點間的 Pod 分布不均,導致分布不均
如果 Pod 未平均分配到各個節點,且負載平衡器未使用容器原生負載平衡,就會發生這個問題。Pod 較多的節點會接收較多流量,可能導致部分節點超載,其他節點則未充分利用。
使用 externalTrafficPolicy: Local 時,這個問題尤其重要。
外部流量政策設定導致分配不均
服務的 externalTrafficPolicy 設定會影響流量路徑。
- 叢集:允許負載平衡器將流量分配給叢集中的任何節點。使用
Cluster設定,在所有可用節點和 Pod 之間最平均地分配。 - Local:只將流量轉送至在接收流量的同一節點上執行的 Pod。如果沒有在節點間平均分配 Pod,可能會導致分配不均。
節點親和性導致分配不均
使用節點親和性將 Pod 限制在部分節點,可能會導致這些節點過載,尤其是當工作負載在節點間的分配不均時。
確認 Pod 並未固定在特定節點上。