前言
版本化元件配置檔案是由華為在 Kubernetes 社群 v1.12 週期重點推動的特性,並在 Kubernetes 1.12 進入 alpha 階段。接下來我們將敘述版本化元件配置檔案的演變過程,以及以 kube-proxy 為例闡述如何將現有元件遷移到版本化配置檔案,最後,作出一些未來工作設想。 作為 Kubernetes 的忠實粉絲,也必然感受到部署各個核心叢集元件(kubelet,kube-proxy,scheduler 等)和管理命令列標誌的痛苦。近兩年,社群在嘗試努力將使用命令列標識管理各個元件模式切換到更貼合 Kubernetes 風格的版本化配置檔案模式,即元件配置。
從Kubernetes v1.10 開始,kubelet 正逐步從命令列標識遷移到版本配置檔案,而且已經轉換成 beta 版本(已支援動態 kubelet 配置)。為了支援這一特性,現有很多 kubelet 命令列標識已棄用或待刪除。且在 v1.12 中,kubelet 元件版本配置檔案特性已 GA。此外,kube-proxy 元件可以說已有GA版本的配置檔案特性,這可從 local-up 指令碼啟動 kube-proxy 元件得到佐證。在K8S v1.12週期中,社群已將 kube-scheduler, kube-controller-manager, kube-apiserver 元件遷移為配置檔案管理模式。社群將在 K8S v1.13 週期重點推動功能穩定性。
接下來,我將分以下幾個部分簡要展開敘述:
- 為什麼要為核心叢集元件遷移到版本化配置檔案
- 元件的配置API的理想形態是怎樣的
- 如何將現有元件遷移到版本化配置檔案
- 總結與願景
一、為什麼要為核心叢集元件遷移到版本化配置檔案
一言以蔽之:便於管理,高效部署。
具體來說,命令列標識存在但不限於以下問題:
-
標識是公共 API,但未進行版本化以及無法脫離元件二進位制單獨版本化:
- 對於核心元件,二進位制版本與 Kubernetes 版本相關聯。對二進位制檔案採用語義版本控制,一般情況下無法突破主要版本控制。
- 在一個 API 版本生命週期,我們會逐漸棄用單個引數,而不保證引數集的連續性。這將不但使使用者使用不方便,而且導致 API 不太穩定。
- 考慮到緊密耦合的介面相容性,我們部署基於標識的配置版本升級通常不能獨立於二進位制檔案。
-
在實際應用環境中,不免會重新配置元件某個引數值,流程複雜。目前情形是:以 kube-controller-manager 為例,假設啟動引數變化,則需要重新啟動元件二進位制(程式)。但如果程式管理器配置是靜態的,如配置命令列僅需要引用一個固定路徑下的檔案(如,kube-proxy 僅使用
—config
引數指定路徑),則可以消除對引數化工具的依賴(如元件二進位制)。 -
開發人員不可避免地將結構化資料嵌入到字串中,還需要特定的解析器處理相應標識欄位,這很容易引入錯誤。 想了解更多當前命令列標識模式的不足,可以查閱 mikedanese 提交的 kubernetes 元件配置、mtaufen 提交的版本化元件配置檔案以及 sttts 提交的為
api-server
建立配置結構體等文件。
二、元件的配置API的理想形態
在元件二進位制存在的目錄執行如下命令:
$ component —help
可以看到,kube-proxy
至少包含 30 個命令列標識,kube-controller-manager
包含近 100 個命令列標識,kubelet 至少包含 120 個命令列標識。如前文所述,管理這些龐大數目的命令列標識對於一個k8s開發者來說都很艱難,何況小白使用使用者。
我們期望每個核心叢集元件擁有如下理想化的命令列:
$ component --config = path
顯然,元件在其命令列上只顯示一個標誌。此標誌接受具有版本化格式的配置檔案的路徑,而且所有其他元件相關配置資訊都通過這個檔案進行引用。 一般來說,每個核心叢集元件應該:
- 維護一個名為
{component} .config.k8s.io
的唯一 Kubernetes API 組,其中包含版本化的配置物件集,主要是每個版本中的{Component}Configuration
結構,如 KubeProxyConfiguration。這個擁有元件配置特殊格式的結構將被API機制序列化。 - 確保
{component} .config.k8s.io
符合 Kubernetes 標準的 API 棄用策略、API 約定和 API 更改策略。 - 暴露名為
--config
的標識,該標識接受包含序列化{Component}Configuration
結構檔案的路徑。 - 使用 Kubernetes API 機制反序列化配置檔案資料、應用預設檔案和轉換為內部版本以供執行時使用。(一般由 API 目錄下 Install 包和 Scheme 包實現)
- 在使用 Configuration 配置前驗證內部版本(一般為 API 目錄下的 validate 包實現)。如果驗證失敗,則拒絕執行指定的配置。
- 確保第三方庫(如 pflag 庫)沒有暴露標識。
三、如何將現有元件遷移到版本化配置檔案
下面以 kube-proxy
為例,簡要解答一下幾個問題:
1、元件 API 組定義
如前文所述,kube-proxy 的組版本型別為:
kubeproxy.config.k8s.io/ v1alpha1.KubeProxyConfiguration
。
首先在 pkg/proxy/apis/kubeproxyconfig/register.go
中定義 GroupName
,並把 KubeProxyConfiguration
加入到 `SchemeGroupVersion中作為內部版本型別,然後在
pkg/proxy/apis/kubeproxyconfig/scheme/scheme.go`` 中定義解析和序列化特定版本的函式 Codecs,並把相應組型別加入到給定 Scheme 中。
2、如何讀取配置檔案
通過命令列標識 —config
提供的檔案路徑,首先呼叫 loadConfigFromFile(file string)
讀取配置檔案,再呼叫 loadConfig (data []byte)
將檔案內容解析為 {Componnet}Configuration
結構,並對 API 組組名進行驗證。
3、對配置檔案進行驗證
呼叫 Validate()
對 `{Componnet}Configuration`` 結構中屬性進行驗證,主要包含欄位取值以及不同欄位之間的關聯性。
對具體細節不再展開敘述,感興趣的童鞋可閱讀社群 kube-proxy 原始碼。
總結與願景
前文簡單介紹了版本化元件配置檔案的背景以及以 kube-proxy 為例大概瞭解的實現方式。
在接下來博文中,我將基於自己近期在 controller-manager 方面的經驗,介紹 kube-controller-manager(cloud-controller-manager 暫不暴露 API 介面)的版本化元件配置檔案思路以及實現。
最後,基於近期自己在 kube-controller-manager
元件配置方面的經驗,接下來各核心元件還需要開展以下相關工作:
- 解耦“累贅”的元件 API,已提交方案並在 1.1 已實現。
- 為元件增加
—config
命令列標識,切換到 alpha 版本 - 新增相應 e2e 測試,完整測試功能,切換到 beta 版本。
- 啟用或丟棄現有眾多命令列標識,使版本化元件配置功能切換 GA。
- 此外,kubeadm 和 cloud provider 也將 out of tree。
總的來說,Kubernetes 社群在朝著“核心做穩定,框架解耦、精簡”這一目標前行。在此,我也誠摯邀請感興趣的童鞋加入到社群上述或其他相關工作。