簡介
你可能聽過Kubernetes中Operator的概念,Operator可以幫助我們擴展Kubernetes功能,包括管理任何有狀態應用程序。我們看到了它被用於有狀態基礎設施應用程序的許多可能性,包括版本升級、節點恢復、調整集群大小等。
本文我們將揭開Operator的神秘面紗,為如何構建可應用於實際的自定義Operator打下堅實的基礎。
operator到底是什么?
為了說明operator到底是什么,讓我們回到Kubernetes的架構上來,Kubernetes本質上是理想的狀態管理器。你為你的應用程序提供了所需的狀態(實例數,磁盤空間,使用的鏡像等),並且如果任何事情失控,它都會嘗試保持該狀態。Kubernetes在Master節點上使用控制面,控制面包含許多控制器,這些控制器的工作是按照下面的方式與期望的狀態進行協調(Reconcile):
- 監視現有的K8S對象(pods,deployments等)去確定他們的狀態
- 比較該對象和它的K8s yaml配置
- 如果狀態和配置不同,控制器將嘗試進行修復(remedy)
進行協調的一個常見的場景是:
一個pod被定義了三個副本,當一個掛了,K8s控制器的監視(watching)下,它意識到應該運行三個pod,而不是兩個,然后,它將創建一個新的pod實例。
下圖簡單展示了控制器在K8s架構中的作用:
- kubectl CLI發送一個對象配置(Pod,Deployment等)到Master Node的API Server以便在集群運行
- Master Node將調度(schedule)對象去運行
- 一旦運行,一個控制器將持續件事這個對象並根據它的配置不斷協調(Reconcile)
通過這種方式,Kubernetes方便的代替了大量手動工作,以維護運行時的無狀態應用。然而,它僅限於K8S預定義的對象類型(Pod,Deployment,Namespace,Service,DaemonSet等),這些對象類型中的每一個都具有預定的行為和方式,如果它們和配置發生了偏離,他們就會與配置相協調(Reconcile),以達到所期望的配置。
現在,如果您的應用程序有更多復雜性,那么你需要自定義Operator以將達到期望的運行狀態。
我們考慮一個有狀態的應用程序,有一個運行在多個節點上的數據庫應用程序。如果大多數節點出現故障,則需要按照特定步驟從指定快照重新加載數據庫。使用Kubernetes中現有的對象類型和控制器,這是不可能實現的。再考慮節點擴容,升級新版本,或為我們的有狀態應用程序進行災難恢復。這些類型的操作通常需要非常具體的步驟,並且通常需要手動干預。
Kubernetes Operators允許你定義一個自定義控制器來watch你的應用程序並根據其狀態執行自定義任務,從而擴展了Kubernetes(這是使我們上述的有狀態應用程序自動維護的完美選擇)。
你想要watch的應用程序在Kubernetes中被定義為一個新對象,一個CR(Custom Resource),它有自己的yaml spec和被API Server理解的對象類型(kind)。這樣,你可以在自定義spec中定義任何需要關注的特定標准,並在實例與期望不匹配時進行協調。雖然Operator Controller主要使用自定義組件,但是它的spec和本地Kubernetes的控制器非常相似。
Operator 運行自定義控制器以協調spec。雖然API server能感知到自定義控制器,但是Operator是獨立運行的,可以在集群內部或外部運行。
由於Operator是有狀態應用程序的強大工具,因此我們看到CoreOS和其他貢獻Etcd,Prometheus等提供了許多Operator,而這些是一個偉大的起點,但是Operator的價值實際上取決於你對它的處理方式:針對故障的具體做法是什么?以及Operator的功能如何與手動干預一起使用。
嘗試構建Operator:
- 定義我們要watch的應用程序的自定義資源CR spec以及該CR的API
- 編寫一個Custom Controller來監視我們的應用程序
- 新控制器中的自定義代碼,讓我們知道如何使我們的CR與spec一致。
- 管理自定義控制器中的Operator
- 為了Operator和CR的一個Deployment
以上這些都可以通過手動編寫go代碼和spec來實現,同時我們可以使用kubebuild、operator-sdk來生成骨架代碼,讓我們更方便的去關注核心代碼的編寫。
參考文章:
https://www.linux.com/topic/cloud/demystifying-kubernetes-operators-operator-sdk-part-1/