
作者 | 匡大虎、阚俊寶
基于 Kubernetes 平台,我們可以輕松的搭建一些簡單的無狀态應用,比如對于一些常見的 web apps 或是移動端背景程式,開發者甚至不用十分了解 Kubernetes 就可以利用 Deployment,Service 這些基本單元模型建構出自己的應用拓撲并暴露相應的服務。由于無狀态應用的特性支援其在任意時刻進行部署、遷移、更新等操作,Kubernetes 現有的 ReplicaSets,ReplicationControllers,Services 等元素已經足夠支撐起無狀态應用對于自動擴縮容、執行個體間負載均衡等基本需求。
在管理簡單的有狀态應用時,我們可以利用社群原生的 StatefulSet 和 PV 模型來建構基礎的應用拓撲,幫助實作相應的持久化存儲,按順序部署、順序擴容、順序滾動更新等特性。
而随着 Kubernetes 的蓬勃發展,在資料分析,機器學習等領域相繼出現了一些場景更為複雜的分布式應用系統,也給社群和相關應用的開發運維人員提出了新的挑戰:
- 不同場景下的分布式系統中通常維護了一套自身的模型定義規範,如何在 Kubernetes 平台中表達或相容出應用原先的模型定義?
- 當應用系統發生擴縮容或更新時,如何保證目前已有執行個體服務的可用性?如何保證它們之間的可連通性?
- 如何去重新配置或定義複雜的分布式應用?是否需要大量的專業模闆定義和複雜的指令操作?是否可以向無狀态應用那樣用一條 kubectl 指令就完成應用的更新?
- 如何備份和管理系統狀态和應用資料?如何協調系統叢集各成員間在不同生命周期的應用狀态?
而所有的這些正是 Operator 希望解決的問題,本文我們将首先了解到 Operator 是什麼,之後逐漸了解到 Operator 的生态建設,Operator 的關鍵元件及其基本的工作原理,下面讓我們來一探究竟吧。
初識 Operator
首先讓我們一起來看下什麼是 Operator 以及它的誕生和發展曆程。
1. 什麼是 Operator
CoreOS 在 2016 年底提出了 Operator 的概念,當時的一段官方定義如下:
“An Operator represents human operational knowledge in software, to reliably manage an application.”
對于普通的應用開發者或是大多數的應用 SRE 人員,在他們的日常開發運維工作中,都需要基于自身的應用背景和領域知識建構出相應的自動化任務滿足業務應用的管理、監控、運維等需求。在這個過程中,Kubernetes 自身的基礎模型元素已經無法支撐不同業務領域下複雜的自動化場景。
與此同時,在雲原生的大背景下,生态系統是衡量一個平台成功與否的重要标準,而廣大的應用開發者作為 Kubernetes 的最直接使用者和服務推廣者,他們的業務需求更是 Kubernetes 的生命線。于是,谷歌率先提出了 Third Party Resource 的概念,允許開發者根據業務需求以插件化形式擴充出相應的 K8s API 對象模型,同時提出了自定義 controller 的概念用于編寫面向領域知識的業務控制邏輯,基于 Third Party Resource,Kubernetes 社群在 1.7 版本中提出了
custom resources and controllers的概念,這正是 Operator 的核心概念。
基于 custom resources 和相應的自定義資源控制器,我們可以自定義擴充 Kubernetes 原生的模型元素,這樣的自定義模型可以如同原生模型一樣被 Kubernetes API 管理,支援 kubectl 指令行;同時 Operator 開發者可以像使用原生 API 進行應用管理一樣,通過聲明式的方式定義一組業務應用的期望終态,并且根據業務應用的自身特點進行相應控制器邏輯編寫,以此完成對應用運作時刻生命周期的管理并持續維護與期望終态的一緻性。這樣的設計範式使得應用部署者隻需要專注于配置自身應用的期望運作狀态,而無需再投入大量的精力在手工部署或是業務在運作時刻的繁瑣運維操作中。
簡單來看,Operator 定義了一組在 Kubernetes 叢集中打包和部署複雜業務應用的方法,它可以友善地在不同叢集中部署并在不同的客戶間傳播共享;同時 Operator 還提供了一套應用在運作時刻的監控管理方法,應用領域專家通過将業務關聯的運維邏輯編寫融入到 operator 自身控制器中,而一個運作中的 Operator 就像一個 7*24 不間斷工作的優秀運維團隊,它可以時刻監控應用自身狀态和該應用在 Kubernetes 叢集中的關注事件,并在毫秒級别基于期望終态做出對監聽事件的處理,比如對應用的自動化容災響應或是滾動更新等進階運維操作。
進一步講,Operator 的設計和實作并不是千篇一律的,開發者可以根據自身業務需求,不斷演進應用的自定義模型,同時面向具體的自動化場景在控制器中擴充相應的業務邏輯。很多 Operator 的出現都是起源于一些相對簡單的部署和配置需求,并在後續演進中不斷完善補充對複雜運維需求的自動化處理。
2. Operator 的發展
時至今日,Kubernetes 已經确立了自己在雲原生領域平台層開源軟體中的絕對地位,我們可以說 Kubernetes 就是當今容器編排的事實标準;而在 Kubernetes 項目強大的影響力下,越來越多的企業級分布式應用選擇擁抱雲原生并開始了自己的容器化道路,而 Operator 的出現無疑極大的加速了這些傳統的複雜分布式應用的上雲過程。無論在生态還是生産領域,Operator 都是容器應用部署上雲過程中廣受歡迎的實作規範,本小節就讓我們來一起回顧下 Operator 的誕生和發展曆史。
2014 到 2015 年,Docker 無疑是容器領域的絕對霸主,容器技術自身靈活、彈性和可移植性等優勢使其迅速成為了當時炙手可熱的焦點。在這個過程中,雖然市場上湧現了大量應用鏡像和技術分享,我們卻很難在企業生産級别的分布式系統中尋找到容器應用的成功案例。容器技術的本質是提供了主機虛拟層之上的隔離,這樣的隔離雖然帶來了靈活和彈性的優勢,但同時也給容器和外部世界的互動帶來了多一層的障礙;尤其是面向複雜分布式系統中,在處理自身以及不同容器間狀态的依賴和維護問題上,往往需要大量的額外工作和依賴元件。這也成為了容器技術在雲原生應用生産化道路上的一個瓶頸。
與此同時,谷歌于 2014 年基于其内部的分布式底層架構 Borg 推出了 Kubernetes 并完成了
第一次代碼送出。
2015 年,Kubernetes v1.0 版本正式釋出,同時雲原生計算基金會 Cloud Native Computing Foundation,簡稱 CNCF)正式成立,基于雲原生這個大背景,CNCF 緻力于維護和內建優秀開源技術以支撐編排容器化微服務架構應用。
2016 年是 Kubernetes 進入主幹道,開始蓬勃發展的一年。這一年的社群,開發者們從最初的種種疑慮轉為對 Kubernetes 的大力追捧,無論從 commit 數量到個人貢獻者數量都有了顯著增長;同時越來越多的企業選擇 Kubernetes 作為生産系統容器叢集的編排引擎,而以 Kubernetes 為核心建構企業内部的容器生态已經開始逐漸成為雲原生大背景下業界的共識。也正是在這一年,CoreOS 正式推出了 Operator,旨在通過擴充 Kubernetes 原生 API 的方式為 Kubernetes 應用提供建立、配置以及運作時刻生命周期管理能力,與此同時使用者可以利用 Operator 友善的對應用模型進行更新、備份、擴縮容及監控等多種複雜運維操作。
在 Kubernetes 實作容器編排的核心思想中,會使用控制器(Controller)模式對 etcd 裡的 API 模型對象變化保持不斷的監聽(Watch),并在控制器中對指定事件進行響應處理,針對不同的 API 模型可以在對應的控制器中添加相應的業務邏輯,通過這種方式完成應用編排中各階段的事件處理。而 Operator 正是基于控制器模式,允許應用開發者通過擴充 Kubernetes API 對象的方式,将複雜的分布式應用叢集抽象為一個自定義的 API 對象,通過對自定義 API 模型的請求可以實作基本的運維操作,而在 Controller 中開發者可以專注實作應用在運作時刻管理中遇到的相關複雜邏輯。
在當時,率先提出這種擴充原生 API 對象進行應用叢集定義架構的并不是 CoreOS,而是當時還在谷歌的 Kubernetes 創始人 Brendan Burns;正是 Brendan 早在 1.0 版本釋出前就意識到了 Kubernetes API 可擴充性對 Kubernetes 生态系統及其平台自身的重要性,并建構了相應的 API 擴充架構,谷歌将其命名為 Third Party Resource,簡稱“TPR”。
CoreOS 是最早的一批基于 Kubernetes 平台提供企業級容器服務解決方案的廠商之一,他們很敏銳地捕捉到了 TPR 和控制器模式對企業級應用開發者的重要價值;并很快由鄧洪超等人基于 TPR 實作了曆史上第一個 Operator:etcd-operator。它可以讓使用者通過短短的幾條指令就快速的部署一個 etcd 叢集,并且基于 kubectl 指令行一個普通的開發者就可以實作 etcd 叢集滾動更新、災備、備份恢複等複雜的運維操作,極大的降低了 etcd 叢集的使用門檻,在很短的時間就成為當時 K8s 社群關注的焦點項目。
與此同時,Operator 以其插件化、自由化的模式特性,迅速吸引了大批的應用開發者,一時間很多市場上主流的分布式應用均出現了對應的 Operator 開源項目;而很多雲廠商也迅速跟進,紛紛提出基于 Operator 進行應用上雲的解決方案。Operator 在 Kubernetes 應用開發者中的熱度大有星火燎原之勢。
雖然 Operator 的出現受到了大量應用開發者的熱捧,但是它的發展之路并不是一帆風順的。對于谷歌團隊而言,Controller 和控制器模式一直以來是作為其 API 體系内部實作的核心,從未暴露給終端應用開發者,Kubernetes 社群關注的焦點也更多的是集中在 PaaS 平台層面的核心能力。而 Operator 的出現打破了社群傳統意義上的格局,對于谷歌團隊而言,Controller 作為 Kubernetes 原生 API 的核心機制,應該交由系統内部的 Controller Manager 元件進行管理,并且遵從統一的設計開發模式,而不是像 Operator 那樣交由應用開發者自由地進行 Controller 代碼的編寫。
另外 Operator 作為 Kubernetes 生态系統中與終端使用者建立連接配接的橋梁,作為 Kubernetes 項目的設計和捐贈者,谷歌當然也不希望錯失其中的主導權。同時 Brendan Burns 突然宣布加盟微軟的消息,也進一步加劇了谷歌團隊與 Operator 項目之間的沖突。
于是,2017 年開始谷歌和 RedHat 開始在社群推廣 Aggregated apiserver,應用開發者需要按照标準的社群規範編寫一個自定義的 apiserver,同時定義自身應用的 API 模型;通過原生 apiserver 的配置修改,擴充 apiserver 會随着原生元件一同部署,并且限制自定義 API 在系統管理元件下進行統一管理。之後,谷歌和 RedHat 開始在社群大力推廣使用聚合層擴充 Kubernetes API,同時建議廢棄 TPR 相關功能。
然而,巨大的壓力并沒有讓 Operator 昙花一現,就此消失。相反,社群大量的 Operator 開發和使用者仍舊擁護着 Operator 清晰自由的設計理念,繼續維護演進着自己的應用項目;同時很多雲服務提供商也并沒有放棄 Operator,Operator 簡潔的部署方式和易複制,自由開放的代碼實作方式使其維護住了大量忠實粉絲。在使用者的選擇面前,強如谷歌,紅帽這樣的巨頭也不得不做出退讓。最終,TPR 并沒有被徹底廢棄,而是由 Custom Resource Definition(簡稱 CRD)這個如今已經廣為人知的資源模型範式代替。
CoreOS 官方部落格也第一時間發出了回應文章指導使用者盡快從 TPR 遷移到 CRD:
https://coreos.com/blog/custom-resource-kubernetes-v172018 年初,RedHat 完成了對 CoreOS 的收購,并在幾個月後釋出了 Operator Framework,通過提供 SDK 等管理工具的方式進一步降低了應用開發與 Kubernetes 底層 API 知識體系之間的依賴。至此,Operator 進一步鞏固了其在 Kubernetes 應用開發領域的重要地位。
3. Operator 的社群與生态
Operator 開放式的設計模式使開發者可以根據自身業務自由的定義服務模型和相應的控制邏輯,可以說一經推出就在社群引起了巨大的反響。
一時間,基于不同種類的業務應用湧現了一大批優秀的開源 Operator 項目,我們可以在
這裡找到其中很多的典型案例,例如對于運維要求較高的資料庫叢集,我們可以找到像 etcd、Mysql、PostgreSQL、Redis、Cassandra 等很多主流資料庫應用對應的 Operator 項目,這些 Operator 的推出有效的簡化了資料庫應用在 Kubernetes 叢集上的部署和運維工作;在監控方向,CoreOS 開發的 prometheus-operator 早日成為社群裡的明星項目,Jaeger、FluentD、Grafana 等主流監控應用也或由官方或由開發者迅速推出相應的 Operator 并持續演進;在安全領域,Aqua、Twistlock、Sisdig 等各大容器安全廠商也不甘落後,通過 Operator 的形式簡化了相對門檻較高的容器安全應用配置,另外社群中像 cert-manager、vault-operator 這些熱門項目也在很多生産環境上得到了廣泛應用。
可以說 operator 在很短的時間就成為了分布式應用在 Kubernetes 叢集中部署的事實标準,同時 Operator 應用如此廣泛的覆寫面也使它超過了分布式應用這個原始的範疇,成為了整個 Kubernetes 雲原生應用下一個重要存在。
随着 Operator 的持續發展,已有的社群共享模式已經漸漸不能滿足廣大開發者和 K8s 叢集管理者的需求,如何快速尋找到業務需要的可用 Operator?如何給生态中大量的 Operator 定義一個統一的品質标準?這些都成為了剛剛完成收購的 RedHat 大佬們眼中亟需解決的問題。
于是我們看到 RedHat 在年初聯合 AWS、谷歌、微軟等大廠推出了
OperatorHub.io,希望其作為 Kubernetes 社群的延伸,向廣大 operator 使用者提供一個集中式的公共倉庫,使用者可以在倉庫網站上輕松的搜尋到自己業務應用對應的 Operator 并在向導頁的指導下完成執行個體安裝;同時,開發者還可以基于 Operator Framework 開發自己的 Operator 并上傳分享至倉庫中。
下圖為一個 Operator 項目從開發到開源到被使用的全生命周期流程:
(Operator 開源生命周期流程圖)
主要流程包括:
- 開發者首先使用 Operator SDK 建立一個 Operator 項目;
- 利用 SDK 我們可以生成 Operator 對應的腳手架代碼,然後擴充相應業務模型和 API,最後實作業務邏輯完成一個 Operator 的代碼編寫;
- 參考社群 測試指南 進行業務邏輯的本地測試以及打包和釋出格式的本地校驗;
- 在完成測試後可以根據 規定格式 向社群送出 PR ,會有專人進行 review;
- 待社群稽核通過完成 merge 後,終端使用者就可以在 OperatorHub.io 頁面上找到業務對應的 Operator;
- 使用者可以在 OperatorHub.io 上找到業務 Operator 對應的說明文檔和安裝指南,通過簡單的指令行操作即可在目标叢集上完成 Operator 執行個體的安裝;
- Operator 執行個體會根據配置建立所需的業務應用,OLM 和 Operator Metering 等元件可以幫助使用者完成業務應用對應的運維和監控采集等管理操作。
小結
本文主要介紹了 Operator 的基本概念,讓您了解 Operator 的應用場景和發展曆程。
Operator 已經成為 Kubernetes 生态的一個重要設計模式,Kubernetes 從 PaaS 層面提供整套叢集、應用編排的架構,而使用者通過 Operator 的方式擴充自己的應用,并實作與 Kubernetes 的融合。文章同時也介紹了使用 Operator 的生命周期流程,您可以結合自己的業務場景實作自己的 Operator 元件。
作者簡介
匡大虎 阿裡雲進階技術專家,從事 Kubernetes 和容器相關産品的開發。尤其關注雲原生安全,是阿裡雲容器服務雲原生安全核心成員。
阚俊寶 阿裡雲容器服務技術專家,專注 Kubernetes、Docker、雲存儲領域,是阿裡雲 CSI 項目的核心維護者。
“ 阿裡巴巴雲原生 關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的公衆号。”