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

使用 EndpointSlices 擴充套件 Kubernetes 網路

EndpointSlices 是一種令人興奮的新 API,它提供了可擴充套件、可伸縮的 Endpoints API 替代方案。EndpointSlices 跟蹤支援 Service 的 Pod 的 IP 地址、埠、就緒狀態和拓撲資訊。

在 Kubernetes 1.19 中,此功能預設啟用,kube-proxy 從 EndpointSlices 而不是 Endpoints 讀取。儘管這主要是一個不可見的更改,但它應該會在大型叢集中帶來顯著的伸縮性改進。它還為未來 Kubernetes 版本中的重要新功能(如拓撲感知路由)提供了基礎。

Endpoints API 的伸縮性限制

對於 Endpoints API,一個 Service 只有一個 Endpoints 資源。這意味著它需要能夠儲存與相應 Service 相關聯的每個 Pod 的 IP 地址和埠(網路端點)。這導致了巨大的 API 資源。為了加劇這個問題,kube-proxy 在每個節點上執行,並監視 Endpoints 資源的任何更新。即使 Endpoints 資源中的單個網路端點發生更改,整個物件也必須傳送到每個 kube-proxy 例項。

Endpoints API 的另一個限制是它限制了可以為一個 Service 跟蹤的網路端點數量。etcd 中儲存的物件的預設大小限制為 1.5MB。在某些情況下,這可以將 Endpoints 資源限制為 5,000 個 Pod IP。這對於大多數使用者來說不是問題,但對於接近此大小的 Service 的使用者來說,這會成為一個嚴重問題。

為了展示這些問題在大規模部署中變得多麼嚴重,一個簡單的例子會有所幫助。假設一個 Service 有 5,000 個 Pod,它最終可能會有一個 1.5MB 的 Endpoints 資源。如果該列表中的單個網路端點發生更改,則整個 Endpoints 資源將需要分發到叢集中的每個節點。這在擁有 3,000 個節點的大型叢集中會成為一個相當大的問題。每次更新都會涉及在叢集中傳送 4.5GB 的資料(1.5MB Endpoints * 3,000 個節點)。這幾乎足以裝滿一張 DVD,並且每次 Endpoints 更改都會發生。想象一次滾動更新導致所有 5,000 個 Pod 被替換——這將傳輸超過 22TB(或 5,000 張 DVD)的資料。

使用 EndpointSlice API 拆分端點

EndpointSlice API 旨在透過類似於分片的方法解決此問題。我們不再使用單個 Endpoints 資源跟蹤 Service 的所有 Pod IP,而是將它們拆分為多個更小的 EndpointSlices。

考慮一個 Service 由 15 個 Pod 支援的示例。我們最終會得到一個跟蹤所有 Pod 的單個 Endpoints 資源。如果 EndpointSlices 配置為每個儲存 5 個端點,我們最終會得到 3 個不同的 EndpointSlices:EndpointSlices

預設情況下,EndpointSlices 每個儲存多達 100 個端點,儘管這可以透過 kube-controller-manager 上的 --max-endpoints-per-slice 標誌進行配置。

EndpointSlices 提供了 10 倍的伸縮性改進

這個 API 極大地提高了網路伸縮性。現在,當新增或刪除 Pod 時,只需要更新 1 個小的 EndpointSlice。當數百或數千個 Pod 支援單個 Service 時,這種差異會變得非常明顯。

更重要的是,現在 Service 的所有 Pod IP 不需要儲存在單個資源中,我們不再需要擔心 etcd 中儲存的物件的尺寸限制。EndpointSlices 已經用於將 Service 擴充套件到超過 100,000 個網路端點。

所有這些都與 kube-proxy 中所做的一些顯著效能改進結合在一起。在大規模使用 EndpointSlices 時,端點更新傳輸的資料量將顯著減少,並且 kube-proxy 更新 iptables 或 ipvs 規則的速度應該更快。除此之外,Service 現在可以擴充套件到至少是以前限制的 10 倍。

EndpointSlices 啟用新功能

EndpointSlices 在 Kubernetes v1.16 中作為 Alpha 功能引入,旨在為未來的 Kubernetes 版本啟用一些令人興奮的新功能。這可能包括雙棧服務、拓撲感知路由和端點子集。

雙棧服務是一個令人興奮的新功能,它與 EndpointSlices 一起開發。它們將為服務同時使用 IPv4 和 IPv6 地址,並依賴 EndpointSlices 上的 addressType 欄位來按 IP 家族跟蹤這些地址。

拓撲感知路由將更新 kube-proxy 以優先路由同一區域或區域內的請求。這利用了 EndpointSlice 中每個端點儲存的拓撲欄位。作為進一步的完善,我們正在探索端點子集的潛力。這將允許 kube-proxy 僅監視 EndpointSlices 的子集。例如,這可能與拓撲感知路由結合使用,以便 kube-proxy 只需監視包含同一區域內端點的 EndpointSlices。這將提供另一個非常顯著的伸縮性改進。

這對 Endpoints API 意味著什麼?

儘管 EndpointSlice API 提供了 Endpoints API 的更新、更具伸縮性的替代方案,但 Endpoints API 將繼續被視為普遍可用和穩定的。Endpoints API 計劃的最顯著的更改將涉及開始截斷那些否則會遇到伸縮性問題的 Endpoints。

Endpoints API 不會消失,但許多新功能將依賴於 EndpointSlice API。為了利用 EndpointSlices 提供的新的伸縮性和功能,目前使用 Endpoints 的應用程式可能需要考慮將來支援 EndpointSlices。