1. 程式人生 > >基於Helm和Operator的K8S應用管理的分享

基於Helm和Operator的K8S應用管理的分享

Helm Operator Kubernetes

本文由3月7日晚李平輝,Rancher Labs 研發工程師所做的技術分享整理而成。
李平輝熟悉應用容器化解決方案設計和實施,熟悉持續集成方案,關註並參與K8S生態的發展,負責Rancher中國區持續集成服務研發。
搜索微信號RancherLabsChina,添加Rancher小助手為好友,可加入官方技術交流群,實時參加下一次分享~
?
?
??

大家好,今天我們分享的內容是基於Helm和Operator的K8S應用管理。我們知道,Kubernetes基於服務粒度提供了多種資源描述類型。描述一個應用系統尤其是微服務架構系統,需要組合使用大量的Kubernetes資源。針對有狀態應用,常常還需要復雜的運維管理操作以及更多的領域知識。

?
今晚的分享就將介紹如何用Helm這一Kubernetes應用包管理的社區主導方案來簡化應用的部署管理,如何制作應用模板以及打造Kubernetes版應用商店,以及如何利用operator自動化應用的運維。
? ?
我們知道在K8S社區裏面,根據不同的領域,分成了不同的興趣小組,英文叫SIG。今晚的話題屬於APP這個領域。它們是為了解決K8S的應用管理裏面的一些問題而生的。
??

一、Helm

??

讓我們從零開始吧。比如說我們現在已經部署了一個K8S的集群。不管是用GKE或者是EKS,都不是難事,因為現在部署K8S已經不是以前那麽麻煩的事情了。然後我們做了應用的容器化。接下來,我們要試著去把我們的應用部署到K8S上面去。

??
其實在K8S裏面,資源對象是很多的:

技術分享圖片


對於一些微服務架構來說,會有不同的服務在上面運行,你可能要管理諸如deployment、service、有狀態的Statefulset、權限的控制等等。你會發現,部署應用後還會有很多其他關聯的東西以及你需要考慮的點:比如說你的不同團隊,要去管理這樣一個應用,從開發到測試再到生產,在不同的環境中,同樣一套東西可能都需要不同的配置。例如,你在開發的時候,不需要用到PV,而是用一些暫時的存儲就行了;但是在生產環境中,你必須要持久存儲;並且你可能會在團隊之間做共享,然後去存檔。
?
另外,你不僅僅要部署這個應用資源,你還要去管理其生命周期,包括升級、更新換代、後續的刪除等。我們知道,K8S裏面的deployment是有版本管理的,但是從整個應用或某個應用模塊來考慮的話,除了deployment,可能還會有其他的configmap之類的去跟其關聯。這時我們會想,是否有這樣一個工具可以在更上層的維度去管理這些應用呢?這個時候我們就有了社區的一個包管理工具:Helm


? ?
我們知道K8S的意思是舵手,即掌控船舵的那個人。而Helm其實就是那個舵。在Helm裏面,它的一個應用包叫Charts,Charts其實是航海圖的意思。它是什麽東西呢?
??
它其實就是一個應用的定義描述。裏面包括了這個應用的一些元數據,以及該應用的K8S資源定義的模板及其配置。其次,Charts還可以包括一些文檔的說明,這些可以存儲在chart的倉庫裏面。

怎麽用Helm這個工具呢?Helm其實就是一個二進制工具。你只要把它下載下來,已經配置好了kubeconfig的一些相關配置信息,就可以在K8S中做應用的部署和管理了。
用Helm可以做什麽事情呢?其實Helm分為服務端跟客戶端兩部分,你在helm init之後,它會把一個叫做Tiller的服務端,部署在K8S裏面。這個服務端可以幫你管理Helm Chart應用包的一個完整生命周期。
??
Release == Chart 的安裝實例:

技術分享圖片

接著說說Helm Chart。它本質上是一個應用包,你可以把它理解成dpkg或者像rpm這樣的包。只不過,它是基於K8S領域的一個應用包的概念。你可以對同一個chart包進行多次部署,每次安裝它都會產生一個Release。這個Release相當於一個chart中的安裝實例。
? ?
現在我們已經把Tiller部署進去了,那麽就可以去做我們應用的管理了:

$ helm install <chart>
# (stable/mariadb, ./nginx-1.2.3.tgz, ./nginx, https://example.com/charts/nginx-1.2.3.tgz)
$ helm upgrade <release>
$ helm delete <release>

關於一些常用的命令例如安裝一個應用包,可以用install,它其實是可以支持不同格式的:比如說本地的一些chart包,或者說你的遠程倉庫路徑。
對於應用的更新,用Helm upgrade。
如果要刪除的話,就用Helm Delete。
?
Helm的一個Release會生成對應的Configmap,由它去存儲這個Release的信息,並存在K8S裏面。它相當於把應用的一個生命周期的叠代,直接跟K8S去做關聯,哪怕Tiller掛了,但只要你的配置信息還在,這個應用的發布和叠代歷程不會丟失:例如想回滾到以前的版本,或者是查看它的升級路徑等。
?
接下來我們看一個chart的結構。
?
$ helm create demoapp

技術分享圖片
用Helm create的話,它會提供一個大概的框架,你可以去創建自己的一個應用。比如說這個應用就叫做Demoapp,裏面會有如下內容:

技術分享圖片
其中最核心的是templates,即模板化的K8S manifests文件,這裏面會包括資源的定義,例如deployment、service等。現在我們create出來的是一個默認的、用一個nginx deployment去部署的應用。
??
它本質上就是一個Go的template模板。Helm在Go template模板的基礎上,還會增加很多東西。如一些自定義的元數據信息、擴展的庫以及一些類似於編程形式的工作流,例如條件語句、管道等等。這些東西都會使得我們的模板變得非常豐富。
??
有了模板,我們怎麽把我們的配置融入進去呢?用的就是這個values文件。這兩部分內容其實就是chart的核心功能。

技術分享圖片

技術分享圖片
這個deployment,就是一個Go template的模板。裏面可以定義一些預設的配置變量。這些變量就是從values文件中讀取出來的。這樣一來,我們就有了一個應用包的模板,可以用不同的配置將這個應用包部署在不同的環境中去。除此之外,在Helm install/upgrade時候,可以使用不同的value。
?
配置選項:
技術分享圖片

技術分享圖片

$ helm install --set image.tag=latest ./demoapp
$ helm install -f stagingvalues.yaml ./demoapp
?
比如說你可以set某個單獨的變量,你可以用整個File去做一個部署,它會用你現在的配置覆蓋掉它的默認配置。因此我們可以在不同的團隊之間,直接用不同的配置文件,並用同樣的應用包去做應用管理。Chart.yaml即chart的元數據,描述的就是這個chart包的信息。

技術分享圖片

技術分享圖片
另外還有一些文檔的說明,例如NOTES.txt,一般放在templates裏面,它是在你安裝或者說你察看這個部署詳情之時(helm status),自動列出來的。通常會放一些部署了的應用和如何訪問等一些描述性的信息。

技術分享圖片


除了模板以外,Helm chart的另一個作用就是管理依賴。

技術分享圖片
技術分享圖片

比如說你部署一個Wordpress,它可以依賴一些數據庫服務。你可以把數據庫服務作為一個chart形式,放在一個依賴的目錄下面。這樣的話應用之間的依賴管理就可以做的很方便了。
假如現在已經創建了我們自己的應用包,想要有一個倉庫去管理這個包,在團隊之間共享應該怎麽做?
?
chart的倉庫其實就是一個HTTP服務器。只要你把你的chart以及它的索引文件放到上面,在Helm install的時候,就可以通過上面的路徑去拿。
?
Helm工具本身也提供一個簡單的指令,叫Helm serve,幫你去做一個開發調試用的倉庫。
?
例如 https://example.com/charts 的倉庫目錄結構:
技術分享圖片

?
關於 Helm,社區版其實已經有了很多的應用包,一般放在K8S下面的一些項目中,比如安裝Helm時候,它默認就有一個Stable的項目。裏面會有各種各樣的應用包。Stable和incubator chart 倉庫:https://github.com/kubernetes/charts
?
另外,社區版還會提供類似於Rancher Catalog應用商店的這樣一個概念的UI,你可以在這上面做管理。它叫Monocular,即單筒望遠鏡的意思,這些項目的開發都非常的活躍,一直在隨著K8S的叠代做著更新。
?
Monocular: chart的UI管理項目:https://github.com/kubernetes-helm/monocular

技術分享圖片


那麽怎麽去部署K8S版的應用商店呢?其實也非常簡單。因為有了Helm之後,你只要使用Helm install這個Monocular,先把它的倉庫加進來,再install一下,就可以把這個應用部署到你的K8S集群之中了。它其實也是利用了Helm Tiller去做部署。我們可以在上面去搜索一些chart,管理你的倉庫,例如官方的stable,或者是incubator裏面的一些項目。

技術分享圖片


你也可以管理一些已經部署的應用。比如說你要搜索一個應用,點一下部署,就可以把它部署上去了。不過這其中還有很多亟待完善的東西,比如這裏的部署不能配置各種不同的參數,它只能輸入namespace。其次,裏面的一些管理依然存在局限性,比如不能很方便地在UI上做更新。
?
圍繞Helm chart我們也會跟一些公有雲廠商有相關的合作。因為Helm chart的好處就是:一個應用包可以在多個地方部署。比如公有雲的服務,可以基於它去實現應用的編排和管理,把一個服務便利地提供給不同的用戶。Rancher也會在2.0的應用商店中加入對helm chart的支持,希望幫助用戶在方便利用已有模板的同時提供良好的體驗。
?
在stable的倉庫裏面已經有很多chart,其實並不是特別完善,還有很多應用是可以補充和增強的。就我們的實踐經驗來說,什麽都可以chart化,不管是分布式的數據庫集群,還是並行計算框架,都可以以這樣的形式在K8S上部署和管理起來。
?
另外一點就是Helm是插件化的,helm的插件有Helm-templates, helm-github,等等。
?
比如你在Helm install的時候,它可以調用插件去做擴展。它沒有官方的倉庫,但是已經有一些功能可用。其實是把Restless/release的信息以及你的chart信息以及Tiller的連接信息交給插件去處理。Helm本身不管插件是用什麽形式去實現的,只要它是應用包,則對傳入的這些參數做它自己的處理就行。
?
Helm的好處,大概就有這些:
? 利用已有的Chart快速部署進行實驗
? 創建自定義Chart,方便地在團隊間共享
? 便於管理應用的生命周期
? 便於應用的依賴管理和重用
? 將K8S集群作為應用發布協作中心
?

二、Operator

?
我們接下來說說Operator。為什麽講Operator呢?Operator其實並不是一個工具,而是為了解決一個問題而存在的一個思路。什麽問題?就是我們在管理應用時,會遇到無狀態和有狀態的應用。管理無狀態的應用是相對來說比較簡單的,但是有狀態的應用則比較復雜。在Helm chart的stable倉庫裏面,很多數據庫的chart其實是單節點的,因為分布式的數據庫做起來會較為麻煩。
?
Operator的理念是希望註入領域知識,用軟件管理復雜的應用。例如對於有狀態應用來說,每一個東西都不一樣,都可能需要你有專業的知識去處理。對於不同的數據庫服務,擴容縮容以及備份等方式各有區別。能不能利用K8S便捷的特性去把這些復雜的東西簡單化呢?這就是Operator想做的事情。
?
以無狀態應用來說,把它做成一個Scale UP的話是比較簡單的:擴充一下它的數量就行了。

技術分享圖片
技術分享圖片

?

接著在deployment或者是說ReplicaSet的controller中,會去判斷它當前的狀態,並向目標狀態進行遷移。對有狀態的應用來說,我們常常需要考慮很多復雜的事情,包括升級、配置更新、備份、災難恢復、Scale調整數量等等,有時相當於將整個配置刷一遍,甚至可能要重啟一些服務。
?
比如像Zookeeper315以前不能實時更新集群狀態,想要擴容非常麻煩,可能需要把整個節點重啟一輪。有些數據庫可能方便一點,到master那裏註冊一下就好。因此每個服務都會有它自己的特點。
?
拿etcd來說,它是K8S裏面主要的存儲。如果對它做一個Scale up的話,需要往集群中添加一些新節點的連接信息,從而獲取到集群的不同Member的配置連接。然後用它的集群信息去啟動一個新的etcd節點。
?
如果有了etcd Operator,會怎麽樣?Operator其實是CoreOS布道的東西。CoreOS給社區出了幾個開源的Operator,包括etcd,那麽如何在這種情況下去擴容一個etcd集群?
?
首先可以以deployment的形式把etcd Operator部署到K8S中。部署完這個Operator之後,想要部署一個etcd的集群,其實很方便。因為不需要再去管理這個集群的配置信息了,你只要告訴我,你需要多少的節點,你需要什麽版本的etcd,然後創建這樣一個自定義的資源,Operator會監聽你的需求,幫你創建出配置信息來。
?
$ kubectl create –f etcd-cluster.yaml
技術分享圖片
?

要擴容的話也很簡單,只要更新數量(比如從3改到5),再apply一下,它同樣會監聽這個自定義資源的變動,去做對應的更新。
?
$ kubectl apply -f upgrade-example.yaml

技術分享圖片

這樣就相當於把以前需要運維人員去處理集群的一些工作全部都交付給Operator去完成了。如何做到的呢?即應用了K8S的一個擴展性的API——CRD(在以前稱為第三方資源)。
?
在部署了一個etcd Operator之後,通過kubernetes API去管理和維護目標的應用狀態。本質上走的就是K8S裏面的Controller的模式。K8S Controller會對它的resource做這樣的一個管理:去監聽或者是說檢查它預期的狀態,然後跟當前的狀態作對比。如果其中它會有一些差異的話,它會去做對應的更新。
?
Kubernetes Controller 模式:

技術分享圖片

?
etcd的做法是在拉起一個etcd Operator的時候,創建一個叫etcd cluster的自定義資源,監聽應用的變化。比如你的聲明你的更新,它都會去產生對應的一個事件,去做對應的更新,將你的etcd集群維護在這樣的狀態。
?
除了etcd以外,社區比如還有普羅米修斯Operator都可以以這種方便的形式,去幫你管理一些有狀態的應用。
?
值得一提的是,Rancher2.0廣泛采用了Kubernetes-native的Controller模式,去管理應用負載乃至K8S集群,調侃地說,是個Kubernetes operator。

三、Helm和Operator的對比

?
這兩個東西講完了,我們來對比一下二者吧。
?
Operator本質上是針對特定的場景去做有狀態服務,或者說針對擁有復雜應用的應用場景去簡化其運維管理的工具。Helm的話,它其實是一個比較普適的工具,想法也很簡單,就是把你的K8S資源模板化,方便共享,然後在不同的配置中重用。
?
其實Operator做的東西Helm大部分也可以做。用Operator去監控更新etcd的集群狀態,也可以用定制的Chart做同樣的事情。只不過你可能需要一些更復雜的處理而已,例如在etcd沒有建立起來時候,你可能需要一些init Container去做配置的更新,去檢查狀態,然後把這個節點用對應的信息給拉起來。刪除的時候,則加一些PostHook去做一些處理。所以說Helm是一個更加普適的工具。兩者甚至可以結合使用,比如stable倉庫裏就有etcd-operator chart。
?
就個人理解來說,在K8S這個龐然大物之上,他們兩者都誕生於簡單但自然的想法,helm是為了配置分離,operator則是針對復雜應用的自動化管理。

基於Helm和Operator的K8S應用管理的分享