控制節點上的拓撲管理策略
Kubernetes v1.27 [穩定]
越來越多的系統利用 CPU 和硬體加速器結合來支援對延遲敏感的執行和高吞吐量的平行計算。這些系統包括電信、科學計算、機器學習、金融服務和資料分析等領域的工作負載。這些混合系統構成了高效能環境。
為了獲得最佳效能,需要進行與 CPU 隔離、記憶體和裝置區域性性相關的最佳化。然而,在 Kubernetes 中,這些最佳化由一組不相關的元件處理。
_拓撲管理器_是 kubelet 的一個元件,旨在協調負責這些最佳化的元件集合。
準備工作
你需要有一個 Kubernetes 叢集,並且 kubectl 命令列工具必須配置為與你的叢集通訊。建議在至少有兩個節點(不作為控制平面主機)的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用這些 Kubernetes 遊樂場之一
你的 Kubernetes 伺服器版本必須是 v1.18 或更高。要檢查版本,請輸入 kubectl version
。
拓撲管理器工作原理
在引入拓撲管理器之前,Kubernetes 中的 CPU 和裝置管理器彼此獨立地做出資源分配決策。這可能導致多套接字系統上出現不良分配,並且效能/延遲敏感的應用程式將因此類不良分配而受到影響。這裡所說的“不良”是指例如 CPU 和裝置從不同的 NUMA 節點分配,從而導致額外的延遲。
拓撲管理器是一個 kubelet 元件,它充當事實來源,以便其他 kubelet 元件可以做出拓撲對齊的資源分配選擇。
拓撲管理器為元件(稱為_提示提供者_)提供了一個介面,用於傳送和接收拓撲資訊。拓撲管理器擁有一組節點級策略,下文將進行解釋。
拓撲管理器從_提示提供者_接收拓撲資訊,該資訊以位掩碼形式表示可用的 NUMA 節點和首選分配指示。拓撲管理器策略對提供的提示執行一組操作,並根據策略確定的提示進行收斂以給出最佳結果。如果儲存了不合意的提示,則提示的首選欄位將設定為 false。在當前策略中,首選是最小的首選掩碼。選定的提示作為拓撲管理器的一部分進行儲存。根據配置的策略,pod 可以根據選定的提示被節點接受或拒絕。然後將該提示儲存在拓撲管理器中,供_提示提供者_在做出資源分配決策時使用。
Windows 支援
Kubernetes v1.32 [alpha]
(預設停用)透過使用 `WindowsCPUAndMemoryAffinity` 特性門,可以在 Windows 上啟用拓撲管理器支援,並且它需要容器執行時的支援。
拓撲管理器範圍和策略
拓撲管理器目前
- 對齊所有 QoS 類別的 Pod。
- 對齊提示提供者提供拓撲提示的請求資源。
如果滿足這些條件,拓撲管理器將對齊請求的資源。
為了自定義此對齊的執行方式,拓撲管理器提供了兩個不同的選項:`scope` 和 `policy`。
`scope` 定義了執行資源對齊的粒度,例如在 `pod` 或 `container` 級別。而 `policy` 定義了用於執行對齊的實際策略,例如 `best-effort`、`restricted` 和 `single-numa-node`。有關當今可用的各種 `scopes` 和 `policies` 的詳細資訊可在下文中找到。
注意
要使 Pod 規約中的 CPU 資源與其他請求資源對齊,應在節點上啟用 CPU 管理器並配置適當的 CPU 管理器策略。請參閱 控制節點上的 CPU 管理策略。注意
要使 Pod 規約中的記憶體(和 Hugepages)資源與其他請求資源對齊,應在節點上啟用記憶體管理器並配置適當的記憶體管理器策略。請參閱 記憶體管理器 文件。拓撲管理器作用域
拓撲管理器可以在幾個不同的作用域內處理資源的對齊:
- `container` (預設)
pod
可以在 kubelet 啟動時透過在 kubelet 配置檔案 中設定 `topologyManagerScope` 來選擇任一選項。
`container` 作用域
預設使用 `container` 作用域。你也可以在 kubelet 配置檔案 中將 `topologyManagerScope` 顯式設定為 `container`。
在此作用域內,拓撲管理器執行一系列順序資源對齊,即為每個容器(在 Pod 中)計算單獨的對齊。換句話說,對於這個特定的作用域,沒有將容器分組到特定 NUMA 節點集的概念。實際上,拓撲管理器執行單個容器到 NUMA 節點的任意對齊。
在以下作用域(例如 `pod` 作用域)中,分組容器的概念得到了認可並有意識地實現。
`pod` 作用域
要選擇 `pod` 作用域,請將 kubelet 配置檔案 中的 `topologyManagerScope` 設定為 `pod`。
此作用域允許將 Pod 中的所有容器分組到一組共同的 NUMA 節點。也就是說,拓撲管理器將一個 Pod 視為一個整體,並嘗試將整個 Pod(所有容器)分配到一個單個 NUMA 節點或一組共同的 NUMA 節點。以下示例說明了拓撲管理器在不同情況下產生的對齊方式:
- 所有容器都可以並已分配到單個 NUMA 節點;
- 所有容器都可以並已分配到一組共享的 NUMA 節點。
整個 Pod 的特定資源的總需求量根據有效請求/限制公式計算,因此,此總值等於以下各項的最大值:
- 所有應用容器請求的總和,
- 初始容器請求的最大值,
針對某個資源。
將 `pod` 作用域與 `single-numa-node` 拓撲管理器策略結合使用,對於對延遲敏感的工作負載或執行 IPC 的高吞吐量應用程式特別有價值。透過結合這兩個選項,你可以將 Pod 中的所有容器放置到單個 NUMA 節點上;因此,可以消除該 Pod 的 NUMA 間通訊開銷。
在 `single-numa-node` 策略的情況下,只有當可能的分配中存在合適的 NUMA 節點集時,Pod 才會被接受。重新考慮上面的例子:
- 一個只包含單個 NUMA 節點的集合——這將導致 Pod 被接納,
- 而一個包含多個 NUMA 節點的集合——這將導致 Pod 被拒絕(因為需要兩個或更多 NUMA 節點而不是一個 NUMA 節點來滿足分配)。
總而言之,拓撲管理器首先計算一組 NUMA 節點,然後根據拓撲管理器策略對其進行測試,這將導致 Pod 的拒絕或接納。
拓撲管理器策略
拓撲管理器支援四種分配策略。你可以透過 kubelet 標誌 `--topology-manager-policy` 設定策略。支援以下四種策略:
- `none`(預設)
best-effort
restricted
single-numa-node
注意
如果拓撲管理器配置了 **pod** 作用域,那麼被策略考慮的容器將反映整個 Pod 的要求,因此 Pod 中的每個容器都將得到**相同的**拓撲對齊決策。`none` 策略
這是預設策略,不執行任何拓撲對齊。
`best-effort` 策略
對於 Pod 中的每個容器,kubelet 在採用 `best-effort` 拓撲管理策略時,會呼叫每個提示提供者來發現其資源可用性。利用這些資訊,拓撲管理器會儲存該容器的首選 NUMA 節點親和性。即使親和性不是首選,拓撲管理器也會儲存此資訊並仍然接納 Pod 到該節點。
然後,_提示提供者_可以在做出資源分配決策時使用此資訊。
`restricted` 策略
對於 Pod 中的每個容器,kubelet 在採用 `restricted` 拓撲管理策略時,會呼叫每個提示提供者以發現其資源可用性。利用這些資訊,拓撲管理器會儲存該容器的首選 NUMA 節點親和性。如果親和性不是首選,拓撲管理器將拒絕該 Pod 從該節點上執行。這將導致 Pod 進入 `Terminated` 狀態,並出現 Pod 入場失敗。
一旦 Pod 進入 `Terminated` 狀態,Kubernetes 排程器將**不會**嘗試重新排程該 Pod。建議使用 ReplicaSet 或 Deployment 來觸發 Pod 的重新部署。也可以實現一個外部控制迴圈來觸發具有 `Topology Affinity` 錯誤的 Pod 的重新部署。
如果 Pod 被接納,_提示提供者_可以在做出資源分配決策時使用此資訊。
`single-numa-node` 策略
對於 Pod 中的每個容器,kubelet 在採用 `single-numa-node` 拓撲管理策略時,會呼叫每個提示提供者來發現其資源可用性。利用這些資訊,拓撲管理器會判斷是否可能實現單個 NUMA 節點親和性。如果可能,拓撲管理器將儲存此資訊,然後_提示提供者_可以在做出資源分配決策時使用此資訊。然而,如果不可能,拓撲管理器將拒絕該 Pod 從該節點上執行。這將導致 Pod 進入 `Terminated` 狀態,並出現 Pod 入場失敗。
一旦 Pod 進入 `Terminated` 狀態,Kubernetes 排程器將**不會**嘗試重新排程該 Pod。建議使用帶有副本的 Deployment 來觸發 Pod 的重新部署。也可以實現一個外部控制迴圈來觸發具有 `Topology Affinity` 錯誤的 Pod 的重新部署。
拓撲管理器策略選項
對拓撲管理器策略選項的支援要求啟用 `TopologyManagerPolicyOptions` 特性門(預設已啟用)。
你可以使用以下特性門控根據其成熟度級別來開啟或關閉選項組:
- `TopologyManagerPolicyBetaOptions` 預設啟用。啟用後顯示 Beta 級別的選項。
- `TopologyManagerPolicyAlphaOptions` 預設停用。啟用後顯示 Alpha 級別的選項。
你仍然需要使用 `TopologyManagerPolicyOptions` kubelet 選項來啟用每個選項。
prefer-closest-numa-nodes
`prefer-closest-numa-nodes` 選項自 Kubernetes 1.32 起已普遍可用。在 Kubernetes 1.34 中,只要啟用了 `TopologyManagerPolicyOptions` 特性門,此策略選項預設可見。
拓撲管理器預設不感知 NUMA 距離,在做出 Pod 准入決策時也不考慮它們。這種限制在多套接字以及單套接字多 NUMA 系統中都會出現,如果拓撲管理器決定在非相鄰 NUMA 節點上對齊資源,可能會導致對延遲敏感的執行和高吞吐量應用程式的效能顯著下降。
如果你指定 `prefer-closest-numa-nodes` 策略選項,`best-effort` 和 `restricted` 策略在做出准入決策時會優先選擇 NUMA 節點之間距離更短的集合。
你可以透過在拓撲管理器策略選項中新增 `prefer-closest-numa-nodes=true` 來啟用此選項。
預設情況下(不帶此選項),拓撲管理器在單個 NUMA 節點上對齊資源,或者在需要多個 NUMA 節點的情況下,使用最少數量的 NUMA 節點。
`max-allowable-numa-nodes` (Beta)
`max-allowable-numa-nodes` 選項自 Kubernetes 1.31 起為 Beta 版。在 Kubernetes 1.34 中,只要啟用了 `TopologyManagerPolicyOptions` 和 `TopologyManagerPolicyBetaOptions` 特性門,此策略選項預設可見。
Pod 入場所需的時間與物理機器上的 NUMA 節點數量有關。預設情況下,Kubernetes 不會在檢測到超過 8 個 NUMA 節點的(Kubernetes)節點上執行啟用拓撲管理器的 kubelet。
注意
如果你選擇 `max-allowable-numa-nodes` 策略選項,則允許擁有超過 8 個 NUMA 節點的節點執行啟用拓撲管理器的 kubelet。Kubernetes 專案關於在擁有超過 8 個 NUMA 節點的(Kubernetes)節點上使用拓撲管理器的影響的資料有限。由於缺乏資料,不**建議**在 Kubernetes 1.34 中使用此策略選項,後果自負。你可以透過在拓撲管理器策略選項中新增 `max-allowable-numa-nodes=true` 來啟用此選項。
設定 `max-allowable-numa-nodes` 的值本身不會影響 Pod 入場延遲,但將 Pod 繫結到具有多個 NUMA 的(Kubernetes)節點確實會產生影響。Kubernetes 未來的潛在改進可能會改善 Pod 入場效能以及隨著 NUMA 節點數量增加而出現的高延遲。
Pod 與拓撲管理器策略的互動
考慮以下 Pod 清單中的容器:
spec:
containers:
- name: nginx
image: nginx
由於未指定資源 `requests` 或 `limits`,此 Pod 執行在 `BestEffort` QoS 等級中。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
由於請求小於限制,此 Pod 執行在 `Burstable` QoS 類別中。
如果選擇的策略不是 `none`,拓撲管理器將考慮這些 Pod 規約。拓撲管理器會諮詢提示提供者以獲取拓撲提示。在 `static` 策略的情況下,CPU 管理器策略將返回預設拓撲提示,因為這些 Pod 沒有明確請求 CPU 資源。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
example.com/device: "1"
requests:
memory: "200Mi"
cpu: "2"
example.com/device: "1"
該 Pod 具有整數 CPU 請求,執行在 `Guaranteed` QoS 等級中,因為 `requests` 等於 `limits`。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "300m"
example.com/device: "1"
requests:
memory: "200Mi"
cpu: "300m"
example.com/device: "1"
此 Pod 具有共享 CPU 請求,執行在 `Guaranteed` QoS 類中,因為 `requests` 等於 `limits`。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
example.com/deviceA: "1"
example.com/deviceB: "1"
requests:
example.com/deviceA: "1"
example.com/deviceB: "1"
此 Pod 執行在 `BestEffort` QoS 等級中,因為它沒有 CPU 和記憶體請求。
拓撲管理器將考慮上述 Pod。拓撲管理器將諮詢提示提供者(即 CPU 和裝置管理器)以獲取 Pod 的拓撲提示。
對於具有整數 CPU 請求的 `Guaranteed` Pod,`static` CPU 管理器策略將返回與獨佔 CPU 相關的拓撲提示,而裝置管理器將返回所請求裝置的提示。
對於具有共享 CPU 請求的 `Guaranteed` Pod,`static` CPU 管理器策略將返回預設拓撲提示,因為沒有獨佔 CPU 請求,並且裝置管理器將返回所請求裝置的提示。
在上述兩種 `Guaranteed` Pod 的情況下,`none` CPU 管理器策略將返回預設拓撲提示。
對於 `BestEffort` Pod,`static` CPU 管理器策略將返回預設拓撲提示,因為沒有 CPU 請求,並且裝置管理器將返回每個請求裝置的提示。
利用這些資訊,拓撲管理器計算 Pod 的最佳提示並存儲此資訊,供提示提供者在分配資源時使用。
已知限制
拓撲管理器允許的最大 NUMA 節點數量為 8。如果 NUMA 節點超過 8 個,當嘗試列舉可能的 NUMA 親和性並生成其提示時,將發生狀態爆炸。有關更多選項,請參閱`max-allowable-numa-nodes`(Beta)。
排程器不感知拓撲,因此 Pod 可能會在某個節點上被排程,然後因為拓撲管理器而失敗。