本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

Kubernetes v1.26:Kubernetes 流量工程的進展

Kubernetes v1.26 包含了網路流量工程方面的重大進展,其中兩項功能(服務內部流量策略支援和 EndpointSlice 終止條件)已正式發布 (GA),第三項功能(Proxy 終止端點)已進入 Beta 階段。這些增強功能的結合旨在解決人們今天面臨的流量工程方面的缺點,並為未來釋放新的能力。

滾動更新期間來自負載平衡器的流量遺失

在 Kubernetes v1.26 之前,當將 externalTrafficPolicy 欄位設定為 Local 時,叢集可能會在滾動更新期間遇到來自服務負載平衡器的 流量遺失。這裡有很多活動部件在起作用,因此快速概述 Kubernetes 如何管理負載平衡器可能會有所幫助!

在 Kubernetes 中,您可以建立 type: LoadBalancer 的服務,以使用負載平衡器在外部公開應用程式。負載平衡器實作在叢集和平台之間有所不同,但服務提供了一個通用抽象,表示在所有 Kubernetes 安裝中都一致的負載平衡器。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app.kubernetes.io/name: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  type: LoadBalancer

在底層,Kubernetes 為服務分配一個 NodePort,然後 kube-proxy 使用它來提供從 NodePort 到 Pod 的網路資料路徑。然後,控制器會將叢集中的所有可用節點新增到負載平衡器的後端池,並使用服務的指定 NodePort 作為後端目標端口。

Figure 1: Overview of Service load balancers

圖 1:服務負載平衡器概述

通常,為服務設定 externalTrafficPolicy: Local 是有益的,以避免在未運行支援該服務的健康 Pod 的節點之間進行額外的躍點。當使用 externalTrafficPolicy: Local 時,會為健康檢查目的分配一個額外的 NodePort,以便將不包含健康 Pod 的節點從負載平衡器的後端池中排除。

Figure 2: Load balancer traffic to a healthy Node, when externalTrafficPolicy is Local

圖 2:當 externalTrafficPolicy 為 Local 時,負載平衡器流量到健康節點

可能發生流量遺失的一種情況是,當節點遺失服務的所有 Pod 時,但外部負載平衡器尚未探測健康檢查 NodePort。這種情況發生的可能性在很大程度上取決於負載平衡器上配置的健康檢查間隔。間隔越大,這種情況發生的可能性就越大,因為即使在 kube-proxy 移除了該服務的轉發規則後,負載平衡器仍將繼續向節點發送流量。當 Pod 在滾動更新期間開始終止時,也會發生這種情況。由於 Kubernetes 不將終止中的 Pod 視為“Ready”,因此在滾動更新期間,當任何給定節點上只有終止中的 Pod 時,可能會發生流量遺失。

Figure 3: Load balancer traffic to terminating endpoints, when externalTrafficPolicy is Local

圖 3:當 externalTrafficPolicy 為 Local 時,負載平衡器流量到終止端點

從 Kubernetes v1.26 開始,kube-proxy 預設啟用 ProxyTerminatingEndpoints 功能,這在流量原本會被丟棄的情況下,為終止端點新增了自動故障轉移和路由。更具體地說,當發生滾動更新且節點僅包含終止中的 Pod 時,kube-proxy 將根據終止中 Pod 的就緒狀態將流量路由到這些 Pod。此外,如果只有終止中的 Pod 可用,kube-proxy 將主動使健康檢查 NodePort 失敗。這樣做,kube-proxy 會提醒外部負載平衡器,不應向該節點發送新連線,但會優雅地處理現有連線的請求。

Figure 4: Load Balancer traffic to terminating endpoints with ProxyTerminatingEndpoints enabled, when externalTrafficPolicy is Local

圖 4:當 externalTrafficPolicy 為 Local 時,啟用 ProxyTerminatingEndpoints 的負載平衡器流量到終止端點

EndpointSlice 條件

為了支援 kube-proxy 中的這項新功能,EndpointSlice API 為端點引入了新的條件:servingterminating

Figure 5: Overview of EndpointSlice conditions

圖 5:EndpointSlice 條件概述

serving 條件在語義上與 ready 相同,只是它可以在 Pod 終止時為 truefalse,這與 ready 不同,由於相容性原因,ready 對於終止中的 Pod 始終為 falseterminating 條件對於正在終止的 Pod(非空 deletionTimestamp)為 true,否則為 false。

這兩個條件的添加使此 API 的消費者能夠了解以前不可能的 Pod 狀態。例如,我們現在可以追蹤“就緒”和“未就緒”且也正在終止的 Pod。

Figure 6: EndpointSlice conditions with a terminating Pod

圖 6:具有終止中 Pod 的 EndpointSlice 條件

EndpointSlice API 的消費者(例如 Kube-proxy 和 Ingress 控制器)現在可以使用這些條件來協調連線耗盡事件,方法是繼續轉發現有連線的流量,但將新連線重新路由到其他非終止端點。

優化內部節點本地流量

與服務可以設定 externalTrafficPolicy: Local 以避免外部來源流量的額外躍點類似,Kubernetes 現在支援 internalTrafficPolicy: Local,以針對叢集內部的流量啟用相同的優化,特別是對於使用服務叢集 IP 作為目標地址的流量。此功能在 Kubernetes v1.24 中升級到 Beta 版,並在 v1.26 中升級到 GA 版。

服務預設將 internalTrafficPolicy 欄位設定為 Cluster,其中流量隨機分配到所有端點。

Figure 7: Service routing when internalTrafficPolicy is Cluster

圖 7:當 internalTrafficPolicy 為 Cluster 時的服務路由

internalTrafficPolicy 設定為 Local 時,kube-proxy 僅在存在與同一節點本地可用的端點時,才會轉發服務的內部流量。

Figure 8: Service routing when internalTrafficPolicy is Local

圖 8:當 internalTrafficPolicy 為 Local 時的服務路由

參與其中

如果您對未來關於 Kubernetes 流量工程的討論感興趣,您可以透過以下方式參與 SIG Network