雲原生應用實現規范 - 初識 Operator


1.png

作者 | 匡大虎、闞俊寶

基於 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-v17

2018 年初,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 項目從開發到開源到被使用的全生命周期流程:

2.png
(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 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的公眾號。”


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM