K8S 1.12大特性最快最深度解析:通過ComponentConfig更輕鬆安裝和升級

華為雲發表於2018-10-18

前言

版本化元件配置檔案是由華為在 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的理想形態是怎樣的
  • 如何將現有元件遷移到版本化配置檔案
  • 總結與願景

一、為什麼要為核心叢集元件遷移到版本化配置檔案

一言以蔽之:便於管理,高效部署

具體來說,命令列標識存在但不限於以下問題:

  1. 標識是公共 API,但未進行版本化以及無法脫離元件二進位制單獨版本化:

    • 對於核心元件,二進位制版本與 Kubernetes 版本相關聯。對二進位制檔案採用語義版本控制,一般情況下無法突破主要版本控制。
    • 在一個 API 版本生命週期,我們會逐漸棄用單個引數,而不保證引數集的連續性。這將不但使使用者使用不方便,而且導致 API 不太穩定。
    • 考慮到緊密耦合的介面相容性,我們部署基於標識的配置版本升級通常不能獨立於二進位制檔案。
  2. 在實際應用環境中,不免會重新配置元件某個引數值,流程複雜。目前情形是:以 kube-controller-manager 為例,假設啟動引數變化,則需要重新啟動元件二進位制(程式)。但如果程式管理器配置是靜態的,如配置命令列僅需要引用一個固定路徑下的檔案(如,kube-proxy 僅使用 —config 引數指定路徑),則可以消除對引數化工具的依賴(如元件二進位制)。

  3. 開發人員不可避免地將結構化資料嵌入到字串中,還需要特定的解析器處理相應標識欄位,這很容易引入錯誤。 想了解更多當前命令列標識模式的不足,可以查閱 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 社群在朝著“核心做穩定,框架解耦、精簡”這一目標前行。在此,我也誠摯邀請感興趣的童鞋加入到社群上述或其他相關工作。

相關文章