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

GSoC 2020 - 為叢集外掛構建 Operator

引言

Google 程式設計之夏是一個全球性專案,旨在向學生介紹開源。學生們與開源組織配對,在夏季與他們一起工作三個月。

我叫 Somtochi Onyekwere,來自奈及利亞奧韋裡聯邦科技大學。今年,我有機會與 Kubernetes(隸屬於 CNCF 組織)合作,這使我度過了一個令人驚歎的夏天,學習、貢獻並與社群互動。

具體來說,我致力於“叢集附加元件:打包所有內容!”專案。該專案專注於構建運算子以更好地管理各種叢集附加元件,擴充套件構建這些運算子的工具,並使這些運算子的建立過程順暢。

背景

Kubernetes 在過去幾年中取得了巨大進步,擁有繁榮的社群和大量的貢獻者。程式碼庫正在逐漸從所有程式碼都位於kubernetes/kubernetes倉庫的單體結構,轉變為拆分為多個子專案。叢集附加元件的重點之一是使其中一些子專案以易於組裝、自監控、自修復和 Kubernetes 原生方式協同工作。它使它們能夠無縫工作,無需人工干預。

社群正在探索使用 Operator 作為一種機制來監控叢集中的各種資源並妥善管理這些資源。此外,它還提供了自我修復功能,並且是一種 Kubernetes 原生模式,可以編碼這些附加元件的最佳工作方式並妥善管理它們。

什麼是叢集附加元件?叢集附加元件是資源(如 Services 和 Deployment)的集合,用於為 Kubernetes 叢集提供額外的功能。它們包括從簡單的 Kubernetes Dashboard(用於視覺化)到更復雜的 Calico(用於網路)等。這些附加元件對於叢集中執行的不同應用程式和叢集本身都是必不可少的。附加元件 Operator 提供了一種更好的方式來管理這些附加元件,並瞭解構成附加元件的各種資源的健康狀況和狀態。您可以在這篇文章中獲得更深入的概述。

Operator 是具有自定義資源定義的自定義控制器,它們編碼特定於應用程式的知識,並用於管理複雜的有狀態應用程式。這是一種被廣泛接受的模式。透過 Operator 管理附加元件,這些 Operator 編碼了關於附加元件最佳工作方式的知識,引入了許多優勢,同時設定了易於遵循和擴充套件的標準。這篇文章很好地解釋了 Operator。

附加元件 Operator 可以解決很多問題,但它們也面臨挑戰。在 cluster-addons 專案下,它們缺少一些元件,並且仍處於概念驗證階段。為 Operator 生成 RBAC 配置很痛苦,有時 Operator 被賦予了過多的特權。Operator 的可擴充套件性不強,因為它只能從本地檔案系統或 HTTP(s) 伺服器拉取清單,而且許多簡單的附加元件都在生成相同的程式碼。我花了一個夏天來解決這些問題,用全新的視角審視它們,併為已知和未知的問題提出瞭解決方案。

對 kubebuilder-declarative-pattern 的各種補充

kubebuilder-declarative-pattern(以下簡稱 KDP)倉庫是 kubebuilder SDK 之上的一層附加元件特定工具,透過將實驗性的 --pattern=addon 標誌傳遞給 kubebuilder create 命令來啟用。它們共同為附加元件 Operator 建立了基礎程式碼。在實習期間,我致力於 KDP 和叢集附加元件中的一些功能。

Operator 版本檢查

即使 Operator 具有複雜的邏輯,為 Operator 啟用版本檢查也有助於使附加元件不同版本的升級/降級更安全。這是一種將附加元件的版本與知道如何很好地管理它的 Operator 版本匹配的方法。大多數附加元件都有不同的版本,這些版本可能需要以不同的方式管理。此功能檢查自定義資源是否存在 addons.k8s.io/min-operator-version 註解,該註解聲明瞭管理該版本所需的最低 Operator 版本,並與 Operator 的版本進行比較。如果 Operator 版本低於所需的最低版本,Operator 將暫停並顯示錯誤,告知使用者 Operator 版本過低。這有助於確保為附加元件使用正確的 Operator。

用於儲存清單的 Git 倉庫

以前,僅支援本地檔案目錄和 HTTPS 倉庫來儲存清單。讓附加元件 Operator 的建立者能夠將清單儲存在 GitHub 倉庫中,可以加快開發速度並進行版本控制。啟動控制器時,您可以傳遞一個標誌來指定您的通道目錄的位置。通道目錄包含不同版本的清單,控制器從該目錄中拉取清單並將其應用於叢集。在實習期間,我將其擴充套件為包含 Git 倉庫。

用於暫時停用協調的註解

確保所需狀態與實際狀態匹配的協調迴圈會阻止叢集中物件的修改。這使得實驗或調查叢集中可能出現的問題變得困難,因為任何更改都會迅速恢復。我透過允許使用者在他們不希望控制器協調的資源上放置 addons.k8s.io/ignore 註解來解決這個問題。控制器會檢查此註解,並且不協調該物件。要恢復協調,可以從資源中移除該註解。

kubebuilder-declarative-pattern 中的非結構化支援

我所研究的其中一個 Operator 是一個通用控制器,它可以管理多個不需要額外配置的叢集附加元件。為此,該 Operator 不能使用特定型別,並且需要 kubebuilder-declarative-repo 支援使用 unstructured.Unstructured 型別。kubebuilder-declarative-pattern 中有各種函式無法處理這種型別,如果傳入的物件不是 addonsv1alpha1.CommonObject 型別,則會返回錯誤。這些函式被修改為可以處理 unstructured.Unstructuredaddonsv1alpha.CommonObject

工具和 CLI 程式

我還編寫了一些命令列程式,可以使使用附加元件 Operator 更容易。它們中的大多數在附加元件 Operator 之外也有用處,因為它們試圖解決在使用 Kubernetes 時可能出現的特定問題。我鼓勵您在有機會時檢視它們

RBAC 生成器

Operator 最大的擔憂之一是 RBAC。您必須手動檢視清單併為每個資源新增 RBAC 規則,因為它需要 RBAC 許可權才能在叢集中執行時建立、獲取、更新和刪除清單中的資源。構建 RBAC 生成器使編寫 RBAC 角色和角色繫結過程自動化。RBAC 生成器的功能很簡單。它接受清單的檔名作為標誌。然後,它解析清單並獲取資源的 API 組和資源名稱,並將其新增到角色中。如果解析了 --out 標誌,它將角色和角色繫結輸出到標準輸出或檔案中。

此外,該工具允許您透過分離清單中的叢集角色來拆分 RBAC。這減少了 Operator 許可權過高的安全問題,因為它需要擁有叢集角色所擁有的所有許可權。如果您想自己應用叢集角色而不授予 Operator 這些許可權,您可以傳入一個 --supervisory 布林標誌,以便生成器不會將這些許可權新增到角色中。該 CLI 程式位於此處

Kubectl Ownerref

一眼很難看出哪些物件是由附加元件自定義資源建立的。這個 kubectl 外掛透過顯示叢集中資源擁有者引用的所有物件來緩解這種痛苦。您只需將資源的型別和名稱作為引數傳遞給程式,它就會檢查叢集中的物件,並提供該物件的型別、名稱和名稱空間。透過傳入自定義資源的名稱和型別,它可以幫助您全面瞭解控制器正在協調的所有物件。該 CLI 程式位於此處

附加元件 Operator

要完全理解附加元件 Operator 並更改其建立方式,您必須嘗試建立和使用它們。夏季的一部分時間用於為一些流行的附加元件構建 Operator,例如 Kubernetes Dashboard、Flannel、NodeLocalDNS 等。請檢視cluster-addons倉庫以獲取不同的附加元件 Operator。在本節中,我將重點介紹一個與其他附加元件 Operator 略有不同的。

通用控制器

通用控制器可以在不需要太多配置的附加元件之間共享。這最大限度地減少了叢集上的資源消耗,因為它減少了需要執行的控制器數量。此外,您無需構建自己的 Operator,只需使用通用控制器;當您覺得您的需求增長,需要一個更復雜的 Operator 時,您可以使用 kubebuilder 搭建程式碼,並從通用 Operator 停止的地方繼續。要使用通用控制器,您可以使用此工具(generic-addon)生成 CustomResourceDefinition (CRD)。您傳入種類、組和通道目錄的位置(也可以是 Git 倉庫!)。該工具會為您生成 CRD、RBAC 清單和兩個自定義資源。

過程如下:

此工具建立

  1. 您的附加元件的 CRD
  2. CustomResourceDefinitions 的 RBAC 規則
  3. 應用清單的 RBAC 規則
  4. 您的附加元件的自定義資源
  5. 一個通用自定義資源

通用自定義資源看起來像這樣

apiVersion: addons.x-k8s.io/v1alpha1
kind: Generic
metadata:
 	name: generic-sample
spec:
  objectKind:
  kind: NodeLocalDNS
  version: "v1alpha1"
  group: addons.x-k8s.io
channel: "../nodelocaldns/channels"

應用這些清單,但請確保在 CR 之前應用 CRD。然後,在您的機器上或叢集中執行通用控制器。

如果您對構建 Operator 感興趣,請檢視本指南

相關連結

後續工作

在 GSoC 期間,叢集附加元件上確實做了很多工作。但我們需要更多的人構建 Operator 並在叢集中使用它們。我們需要在社群中更廣泛的採用。為您最喜歡的附加元件構建 Operator,並告訴我們進展如何以及您是否遇到任何問題。請檢視此README.md開始。

致謝

我真心感謝我的導師 Justin Santa Barbara (Google) 和 Leigh Capili (Weaveworks)。我的實習非常棒,因為他們非常棒。他們為導師制度樹立了黃金標準。他們平易近人,隨時可以解答任何困惑。我想我最喜歡的是他們不只是分派任務,而是我們就哪裡出了問題以及如何改進進行了開放式討論。他們真的是最棒的,我希望將來能再次與他們合作!此外,我還要特別感謝 Lubomir I. Ivanov 審閱這篇博文!

結論

到目前為止,我學到了很多關於 Go、Kubernetes 內部結構和 Operator 的知識。最後,我想鼓勵大家(尤其是 Kubernetes :))無論經驗水平如何,都為開源做出貢獻。對我來說,這是一次全面的經歷,我愛上了這個社群。這是一個很棒的倡議,也是學習和結識優秀人才的好方法。特別感謝 Google 組織了這個專案。

如果您對叢集附加元件以及瞭解更多關於附加元件 Operator 感興趣,歡迎加入我們在 Kubernetes 上的 Slack 頻道 #cluster-addons


Somtochi Onyekwere 是一位熱愛為開源做貢獻和探索雲原生解決方案的軟體工程師。