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

API 優先順序與公平性 Alpha 版

此部落格描述「API 優先順序與公平性」,這是 Kubernetes 1.18 中的一項新 Alpha 功能。API 優先順序與公平性允許集群管理員將控制平面的並行性劃分為不同的加權優先順序層級。每個抵達 kube-apiserver 的請求都將被分類到其中一個優先順序層級,並獲得控制平面輸送量的公平份額。

這解決了什麼問題?

如今,apiserver 具有一種簡單的機制來保護自身免受 CPU 和記憶體過載的影響:針對變更和唯讀請求的最大執行中限制。除了變更和唯讀之間的區別之外,請求之間沒有其他區別;因此,可能會出現不希望發生的情況,即請求的一個子集排擠了其他請求。

簡而言之,Kubernetes 工作負載非常容易意外地對 apiserver 造成阻斷服務 (DoS) 攻擊,導致其他重要流量(例如系統控制器或領導者選舉)間歇性失敗。在最壞的情況下,少數幾個損壞的節點或控制器可能會將繁忙的集群推向崩潰邊緣,從而將局部問題轉變為控制平面中斷。

我們如何解決這個問題?

新功能「API 優先順序與公平性」旨在概括每個 apiserver 中現有的最大執行中請求處理常式,以使行為更智慧化且可配置。整體方法如下。

  1. 每個請求都由流程架構比對。流程架構宣告與其比對的請求的優先順序層級,並為這些請求指派「流程識別碼」。流程識別碼是系統判斷請求是否來自同一來源的方式。
  2. 優先順序層級可以配置為以多種方式運作。每個優先順序層級都有其自身的隔離並行池。優先順序層級還引入了將無法立即處理的請求排隊的概念。
  3. 為了防止任何單一使用者或命名空間壟斷優先順序層級,它們可以配置為具有多個佇列。「Shuffle Sharding」用於將每個請求流程指派給佇列的子集。
  4. 最後,當有容量可服務請求時,將使用 「公平佇列」演算法來選擇下一個請求。在每個優先順序層級內,佇列以均等的公平性競爭。

早期結果非常令人鼓舞!請查看此分析

我該如何試用?

您需要準備以下事項才能試用此功能

  • 下載並安裝大於 v1.18.0 版本的 kubectl
  • 在 kube-apiserver 上使用命令列旗標 --runtime-config="flowcontrol.apiserver.k8s.io/v1alpha1=true" 啟用新的 API 群組
  • 在 kube-apiserver 上使用命令列旗標 --feature-gates=APIPriorityAndFairness=true 開啟功能閘道

成功啟動 kube-apiserver 後,您將在集群中看到一些預設的 FlowSchema 和 PriorityLevelConfiguration 資源。這些預設配置旨在為您的集群提供一般保護和流量管理。您可以透過執行常用工具來檢查和自訂預設配置,例如

  • kubectl get flowschemas
  • kubectl get prioritylevelconfigurations

這在底層是如何運作的?

請求抵達處理常式時,會被指派給正好一個優先順序層級和該優先順序層級內正好一個流程。因此,了解 FlowSchema 和 PriorityLevelConfiguration 的運作方式將有助於您管理流經 kube-apiserver 的請求流量。

  • FlowSchema:FlowSchema 將識別 PriorityLevelConfiguration 物件以及計算請求「流程識別碼」的方式。目前,我們支援根據以下項目比對請求:發出請求的身分、動詞和目標物件。身分可以根據以下項目進行比對:使用者名稱、使用者群組名稱或 ServiceAccount。至於目標物件,我們可以依據 apiGroup、resource[/subresource] 和命名空間進行比對。

    • 流程識別碼用於 Shuffle Sharding,因此重要的是,如果請求來自同一來源,則它們具有相同的流程識別碼!我們喜歡考慮「大象」(發送許多/繁重請求)與「老鼠」(發送少量/輕量請求)的情境:重要的是確保大象的所有請求都獲得相同的流程識別碼,否則它們在系統看來會像許多不同的老鼠!
    • 請參閱此處的 API 文件
  • PriorityLevelConfiguration:定義優先順序層級。

    • 對於 apiserver 自我請求和任何重新進入流量(例如,本身發出 API 請求的 admission webhook),優先順序層級可以標記為「豁免」,這表示不會進行任何形式的佇列或限制。這是為了防止優先順序反轉。
    • 每個非豁免優先順序層級都配置了許多「並行性份額」,並獲得隔離的並行池以供使用。該優先順序層級的請求在該池未滿時在其中執行,絕不在其他地方執行。每個 apiserver 都配置了總並行性限制(視為變更和唯讀請求的舊限制之總和),然後根據其並行性份額在優先順序層級之間分配。
    • 非豁免優先順序層級可以選擇許多佇列和用於 Shuffle Sharding 的「手牌大小」。Shuffle Sharding 以比一致性雜湊更好的方式將流程對應到佇列。給定的流程可以存取一小組佇列,並且對於每個傳入的請求,都會選擇最短的佇列。當優先順序層級具有佇列時,它也會設定佇列長度限制。還對請求可以在其佇列中等待的時間設定了限制;這是 apiserver 請求逾時的固定比例。無法執行且無法(再)排隊的請求將被拒絕。
    • 或者,非豁免優先順序層級可以選擇立即拒絕,而不是在佇列中等待。
    • 請參閱此功能的 API 文件

缺少什麼?何時會有 Beta 版?

我們已經根據 Alpha 版規劃了一些增強功能,並且隨著使用者向我們的社群發送回饋,還會有更多增強功能。以下是它們的列表

  • WATCH 和 EXEC 請求的流量管理
  • 調整和改進預設的 FlowSchema/PriorityLevelConfiguration 集
  • 增強對此功能運作方式的可觀察性
  • 在此處加入討論

可能會根據對其結果大小的估計,以不同的方式處理 LIST 請求。

我該如何參與?

一如既往!在 Slack 上聯絡我們 #sig-api-machinery,或透過 郵寄清單。我們有許多令人興奮的功能要建構,並且可以運用各種協助。

非常感謝促成此功能至今的貢獻者:Aaron Prindle、Daniel Smith、Jonathan Tomer、Mike Spreitzer、Min Kim、Bruce Ma、Yu Liao、Mengyi Zhou!