講在前面
今天談談Kubernetes生态中目前非常活躍的一個概念“Operator”。是的,我認為它是一個概念,一個設計模式。它并不是一個開發架構,一種資源或者說一個項目,這個概念由CoreOS提出。Operator的概念是從Kubernetes的CRD(Custom Resource Definition)自定義資源衍生而來。Kubernetes 的API設計是跨時代的,這種面向資源模型的聲明式API體系,使得其能夠在分布式體系管理各種資源。CRD的提出更是為開發者打開了創新的大門,從最開始的分布式應用部署,到更廣闊的應用開發/釋出場景,再到各類雲服務場景。各類型資源都接入到Kubernetes API中有效協同管理。Operator的概念在這個過程中推波助瀾,我們可以從
awesome-operators這裡看到,各種Operator實作種類齊全。
Operator模式與實踐
Operator是一個設計模式,那它到底是一種什麼樣的模式。要分析這個問題我們可以先了解了解在Kubernetes中Deployment這個資源是如何設計和工作的。Deployment作為我們在Kubernetes中部署無狀态應用的标準化方式,其實它的完整工作方式也是Operator設計模式的一種官方實踐。在通過其他的标準Operator設計實踐來進行了解。我們從以下兩個方面來說明Operator模式。
資源定義
Deployment是一種資源,它有完整的定義和Kubernetes API原生的支援。資源的定義中大緻分為三個部分:
- Metadata
- Specification
- Status
我們先給它名一個名,資源三劍客,事實上不管是Statefulset等官方資源和CRD都是按照這樣的三劍客模式定義。Metadata部分定義這個資源最基礎的資訊,版本、類型、名稱、标簽等等。這些資訊會告訴所有人這個資源是什麼,可以通過什麼方式查詢擷取到它;Specification部分,簡稱Spec,該資源的規範性定義。這部分通俗的講就是告知所有人這個資源要做的事和做事需要的條件。比如Deployment這部分的定義基本上就是需要建立Pod,至于建立多少,怎麼建立,建立需要的資訊都在Spec裡定義了;Status部分就是展現目前資源的工作狀态或者結果了。比如Deployment這裡就展現Pod建立好沒有,建立了多少,分别運作狀态是什麼一類的狀态資訊。
我們再從另外一個次元來了解資源定義,Metadata和Specification部分一般是由資源建立者來提供資料,或者由資源完善控制器來做部分資料完善。Status部分由資源控制器來響應和指派。這裡出現了兩類角色,資源建立者,資源控制器。
Operator實踐時,我們通過CRD來定義我們需要的資源類型,舉個例子,
Rainbond-Operator項目目的是為了在Kubernetes叢集中實作
Rainbond所有的元件安裝和運維。那麼我們定義了一個資源來描述Rainbond 的元件。
type RbdComponent struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec RbdComponentSpec `json:"spec,omitempty"`
Status *RbdComponentStatus `json:"status,omitempty"`
}
使用Golang 語言對這個資源進行定義的化它大概是這樣的。滿足上訴講的三劍客原則。資源定義完成後使用operator sdk相關代碼生成工具即可生成CRD資源定義。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: rbdcomponents.rainbond.io
spec:
group: rainbond.io
names:
...
scope: Namespaced
subresources:
status: {}
validation:
...
version: v1alpha1
versions:
- name: v1alpha1
served: true
storage: true
它大概是這樣的,注意這裡是局部代碼。
控制器與狀态維護
控制器負責完成對資源執行個體的生命周期維護,資源執行個體的生命周期一般包括:建立、更新、删除。上面講了資源定義,資源定義在Kubernetes中的概念可以對應為CRD,資源執行個體那就是對應的CR。CRD的作用域是Kubernetes API,CR的主要作用域就是控制器。每一個CR的控制器實作基本上都是遵循1對多原則,及一個控制器支援管理多個CR。比如etcd-operator-controller 可以支援多個CR,建立出多個etcd叢集。每一個CR在由控制器管理的過程類似于流水線一樣。由CR的每一次狀态變更或定時時鐘驅動控制器完成相關的控制動作。基于這種類似的場景operator-sdk當然就給出了通用性開發架構來實作這個過程。
還是舉兩個例子,Deployment 的控制器在Kube-controller-manage中内置實作,Deployment的每次資料變更或特殊操作(更新)驅動控制器來判斷此資源需要的下級資源(包括ReplicaSet )是否符合資源需求。如果需要建立、删除、更新相應的二級資源,由控制器驅動完成,然後更新狀态到Deployment的status中。同樣的上文講到的rainbond-operator中的RbdComponent對應的控制器也一樣。根據不同的元件定義建立出不同的二級資源,再形成資源的相關狀态。
借用一下網絡中的一張圖來展示一下資源、控制器的工作流程。

Operator協同
Operator這種模式目前應用中我們各類進階運維場景中,實作各種自動化運維特征。以Mysql資料庫運維為例,或許會存在Mysql叢集部署Operator,Mysql資料庫資料備份Operator,Mysql資料庫監控、日志分析Operator等等。我們是否可以想到這樣一個問題,在同一個叢集中各種各樣的Operator同時存在時,會不會産生沖突、重複等等問題。比如一個Operator實作負責擴容,一個Operator實作負責縮容,他們共同作用于一類資源類型,如何協同将成為首要問題。
Operator模式的實作定義是不受限制的。其實在整個體系中,CRD定義、Operator模式實作,helm打包工具等等都是沒有規範可循的,沒有規範的資源和功能定義越來越多的時候我們想要讓其能夠協同工作将越來越困難。
我們想要的狀态肯定是可以像搭積木一樣選擇各類Operator協同工作,是以我們需要上升一個次元,去探索Operator能否一定層面的标準規範化。
Operator标準化、規範化
标準化三個字在Kubernetes體系中針對實體資源管理層面來說效果顯著。針對網絡接入提出并實作了CNI規範,針對存儲系統接入提出CSI規範,針對運作時接入提出CRI規範等等。這些規範提出都是為了解決異構的資源提供方以一種統一的、标準的方式接入Kubernetes體系的問題。
回到Operator上來,在Operator的實作上實作方式、使用方式越來越多。那麼我們是否可以有一種較為規範的方式對Operator的實作進行準入。我們舉一個例子,helm工具作為目前kubernetes app最常用的部署管理工具,但我認為其有一個最大的問題點在于不能展現app的實際狀态。我們使用helm list 類的指令查詢app清單時隻能擷取到它的部署狀态,無法擷取其真實狀态,這就是由于資源狀态定義沒有規範導緻(當然,不是說這種設計有問題,有缺陷,相反我們上文說了這種設計是大家各種各樣建立的基礎)。當Operator越來越多時我們需要一種管理工具可以有效管理和協同使用各種Operator實作。
我認為Operator的規範化将展現在下述幾個方面:
- 資源狀态展現規範化。
- 功能、能力邊界規範化。
- 協同方式規範化。
願景:Operator技術下沉,體驗上浮
所有的技術都是為業務服務的,我們都有一個追求目标,把複雜的技術實作往下沉,讓使用者可以最簡單的方式體驗到Operator模式的能力。我們希望可以逐漸打造一種工具或是形成一種規範,讓廣大的開發者能夠發揮創新能力創造各種Operator,讓後将其共享出來。對于大多數的使用者可以便捷的選擇需要的功能,像搭積木一樣注入到自己的叢集環境,應用于業務應用運維中。或許體驗是這樣的:
從一種平台中,我們可以一目了然的知道目前叢集中有哪些應用運維能力,比如可以部署etcd叢集,可以進行mysql資料備份,可以建立阿裡雲RDS,可以進行大資料計算等待。有了這些能力我們在部署和運維應用的同時可以友善的選擇需要的運維功能,而不需要去關注它是如何實作。甚至這樣的應用釋出到其他環境去部署時依然可以找到對應的運維功能實作。
相關項目:
是以企業雲原生應用開發、架構、運維、共享、傳遞為核心的Kubernetes多雲賦能平台, 向下結合Kubernetes雲原生資源管理模式,對接管理各類基礎設施,通過多元度的軟體定義屏蔽了底層資源的差異,甚至包括CPU架構差異和作業系統差異,進而對上層提供以應用為中心的基礎設施; 向上定義了标準應用模型(RAM,
OAM),内置ServiceMesh微服務架構架構, 提供使用者基于源碼/已有鏡像建構服務元件的能力,編排服務元件的能力,釋出共享完整應用模型的能力,傳遞運維業務應用的能力。