為 Client-Go 引入功能閘道:提升彈性與控制能力

Kubernetes 組件使用稱為功能閘道的開關來管理新增功能的風險。功能閘道機制可實現功能逐步通過 Alpha、Beta 和 GA 階段。

Kubernetes 組件,例如 kube-controller-manager 和 kube-scheduler,使用 client-go 程式庫與 API 互動。Kubernetes 生態系統也使用相同的程式庫來建置控制器、工具、webhook 等。client-go 現在包含自己的功能閘道機制,讓開發人員和叢集管理員可以更精確地控制他們採用用戶端功能的方式。

若要深入瞭解 Kubernetes 中的功能閘道,請造訪功能閘道

動機

在沒有 client-go 功能閘道的情況下,每個新功能都以自己的方式(如果有的話)將功能可用性與啟用分開。某些功能是透過更新到較新版本的 client-go 來啟用的。其他功能需要在每個使用它們的程式中主動配置。少數功能可在執行時使用環境變數配置。使用 kube-apiserver 公開的功能閘道功能有時需要用戶端後備機制,以保持與由於伺服器的年限或配置而不支援該功能的伺服器的相容性。在後備機制中發現問題的情況下,緩解措施需要更新到固定版本的 client-go 或回滾。

這些方法都不能為在某些(但非全部)使用 client-go 的程式中預設啟用功能提供良好的支援。更改預設設定會立即影響所有 Kubernetes 組件的預設值,從而顯著擴大影響範圍,而不是最初僅為單一組件啟用新功能。

client-go 中的功能閘道

為了應對這些挑戰,重要的 client-go 功能將使用新的功能閘道機制逐步導入。它將允許開發人員和使用者以熟悉 Kubernetes 組件中功能閘道的方式啟用或停用功能。

開箱即用,僅需使用最新版本的 client-go,即可提供多項優勢。

對於使用使用 client-go 建置的軟體的人員

  • 早期採用者可以針對每個進程啟用預設關閉的 client-go 功能。
  • 無需建置新的二進位檔即可停用行為異常的功能。
  • 所有已知的 client-go 功能閘道的狀態都會記錄下來,允許使用者檢查它。

對於開發使用 client-go 建置的軟體的人員

  • 預設情況下,client-go 功能閘道覆寫是從環境變數中讀取的。如果在 client-go 功能中發現錯誤,使用者將能夠停用它,而無需等待新版本。
  • 開發人員可以在程式中替換預設的基於環境變數的覆寫,以變更預設值、從另一個來源讀取覆寫,或完全停用執行階段覆寫。Kubernetes 組件使用這種可自訂性將 client-go 功能閘道與現有的 --feature-gates 命令列標記、功能啟用指標和記錄整合。

覆寫 client-go 功能閘道

注意:這說明了在執行階段覆寫 client-go 功能閘道的預設方法。開發人員可以停用或自訂特定程式。在 Kubernetes 組件中,client-go 功能閘道覆寫由 --feature-gates 標記控制。

可以透過設定以 KUBE_FEATURE 為前綴的環境變數來啟用或停用 client-go 的功能。例如,若要啟用名為 MyFeature 的功能,請如下所示設定環境變數

 KUBE_FEATURE_MyFeature=true

若要停用該功能,請將環境變數設定為 false

 KUBE_FEATURE_MyFeature=false

注意:在某些作業系統上,環境變數區分大小寫。因此,KUBE_FEATURE_MyFeatureKUBE_FEATURE_MYFEATURE 會被視為兩個不同的變數。

自訂 client-go 功能閘道

對於 Kubernetes 生態系統中的許多程式來說,用於功能閘道覆寫的預設基於環境變數的機制可能已足夠,並且不需要特殊的整合。需要不同行為的程式可以用它們自己的自訂功能閘道提供者來替換它。這允許程式執行諸如強制停用已知運作不佳的功能、直接從遠端配置服務讀取功能閘道,或透過命令列選項接受功能閘道覆寫等操作。

Kubernetes 組件將 client-go 的預設功能閘道提供者替換為現有 Kubernetes 功能閘道提供者的墊片。就所有實際目的而言,client-go 功能閘道的處理方式與其他 Kubernetes 功能閘道相同:它們連接到 --feature-gates 命令列標記,包含在功能啟用指標中,並在啟動時記錄。

若要替換預設功能閘道提供者,請實作 Gates 介面,並在套件初始化時呼叫 ReplaceFeatureGates,如此簡單範例所示

import (
 k8s.io/client-go/features
)

type AlwaysEnabledGates struct{}

func (AlwaysEnabledGates) Enabled(features.Feature) bool {
 return true
}

func init() {
 features.ReplaceFeatureGates(AlwaysEnabledGates{})
}

需要已定義 client-go 功能完整清單的實作可以透過實作 Registry 介面並呼叫 AddFeaturesToExistingFeatureGates 來取得它。如需完整範例,請參閱 Kubernetes 內部的用法

摘要

隨著 client-go v1.30 中功能閘道的引入,推出新的 client-go 功能變得更安全、更輕鬆。使用者和開發人員可以控制他們自己採用 client-go 功能的速度。透過採用通用機制來逐步推出跨越 Kubernetes API 邊界兩側的功能,Kubernetes 貢獻者的工作得到了簡化。

特別感謝 @sttts@deads2k 協助塑造此功能。