聊聊Kubernetes operator

Operator 在2016年就被引入社區了, CoreOS 推出它旨在簡化複雜有狀態應用管理。Operator是一個感知應用狀態的控制器,通過擴展 Kubernetes API 來自動創建、管理和配置應用實例。 Operator 基於 CRD (Custom Resource Definition)擴展資源對象,並通過控制器來保證應用處於預期狀態。
下面舉個例子,比如etcd operator通過下面的三個步驟模擬了管理etcd集羣的行爲:
1、通過 Kubernetes API 觀察集羣的當前狀態;
2、分析當前狀態與期望狀態的差別;
3、調用k8s API消除這些差別。
聊聊Kubernetes operator

下面從不同的角度來聊聊Operator
1、operator與docker
我們先聊一聊docker。docker有非常多的優點,比如隔離、執行效率等等。但是在我看來,docker的核心價值,或者說顛覆性的成果就是設計了鏡像流程,提供標準化的交付方式。就從單個的應用實例來講,標準化、一致性的環境解決了應用的runtime的問題,將應用的部署、應用的依賴進行了統一的封裝。將應用的部署方式從手工作坊的部署方式帶入了標準化的工業時代。當然這也帶來了一定的磁盤額外損耗。但是在硬件飛速發展的今天,這點磁盤損耗幾乎不成問題。而且藉助於聯合文件系統和鏡像優化,磁盤的損耗問題幾乎不用考慮。
時至今日,越來越少的項目採用源碼進行部署。以前一個開源項目往往配上一篇冗長的安裝文檔,教你如何安裝、如何運行。現在,基本上活躍的開源項目都提供了基於容器的部署方式,你只需要拉下鏡像run一下就可以使用。docker大大提升了交付的效率,降低了使用的門檻,有效避免了部署的故障。
operator跟docker是相似的,而其主要的交付對象從單個的應用實例,擴展到了多實例、分佈式的系統上。以往部署一個分佈式系統需要啓動多個容器,然後進行復雜的配置,而現在只要創建一個CRD。operator將自動進行分佈式系統中需要的各個資源的創建和部署。從這個角度上來說,operator的目標是實現分佈式系統的標準化交付。

2、operator與Helm
現在我們一般意義上的編排,也就是orchestration,還有另一種翻譯就是編配。在維基百科的定義爲描述複雜計算機系統、中間件(middleware)和業務的自動化的安排、協調和管理。根據我個人的經驗,總結編排的典型特徵主要包括服務的版本管理、服務的生命週期管理、多個資源多種資源的管理、參數化以及模板化。
最早接觸編排概念,是通過openstack的heat項目。openstack中從計算、存儲到網絡有很多的系統。而如果部署一個完整的應用虛擬機,需要多種資源的協同參與。heat項目就是爲此目標而生。其通過模板和參數對多種資源進行編排,實現了對一個完整服務的創建、部署、修改、刪除等生命週期管理。

在k8s中,也有許多編排項目,目前比較熱門的是包管理工具Helm。如果說docker是奠定的單實例的標準化交付,那麼Helm則是集羣化多實例、多資源的標準化交付。
operator的管理不僅限於容器(pod),也可以是多個資源(比如svc域名等等),從這個角度上來說,operator跟Helm一樣,也是具有編排的能力的。從編排角度來看,在初學者看來,Helm跟operator有非常多的共性,很難對兩者的作用進行區分。Helm也可以完成分佈式系統的部署。那麼operator跟Helm又有什麼樣的區別呢?Helm的側重點在於多種多個的資源管理,而對生命週期的管理主要包括創建更新和刪除。Helm通過命令驅動整個的生命週期。
而operator對於資源的管理則不僅是創建和交付。由於其可以通過watch的方式獲取相關資源的變化事件,因此可以實現高可用、可擴展、故障恢復等運維操作。因此operator對於生命週期的管理不僅包括創建,故障恢復,高可用,升級,擴容縮容,異常處理,以及最終的清理等等。
那你說這些功能能不能用Helm來實現,其實我覺得有一部分功能應該也是可以的。但是這裏面就涉及到一個問題,就是這些功能無法在編排中直接實現,就需要通過腳本或者程序的方式固化到鏡像中。大量的運維代碼被腳本化。會導致維護這些腳本的複雜度提高,可讀性變差。除此之外,還有一個潛在的風險無法解決的就是,當這些容器實例全部掛掉的時候,則完全無法自動恢復了,即使有備份數據。這時候最終還會依賴於人工的介入,仍然無法達到自動化、智能化的目標。
operator則在實現自動化的同時實現了智能化。其主要的工作流程是根據當前的狀態,進行智能分析判斷,並最終進行創建、恢復、升級等操作。而位於容器中的腳本,因爲缺乏很多全局的信息,僅靠自身是無法無法達實現這些全部的功能的。而處於第三方視角的operator,則可以解決這個問題。他可以通過側面的觀察,獲取所有的資源的狀態和信息,並且跟預想/聲明的狀態進行比較。通過預置的分析流程進行判斷,從而進行相應的操作,並最終達到聲明狀態的一個目的。這樣所有的運維邏輯就從鏡像中抽取出來,集中到operator裏去。層次和邏輯也就更加清楚,容易維護,也更容易交付和傳承。
如果把Helm比作rpm,那麼operator就是systemd。rpm負責應用的安裝、刪除,而systemd則負責應用的啓動、重啓等等操作。當然二者並不是互斥的,目前operator一種比較便捷的部署方式就是通過Helm進行部署。

3、operator與controller
operator可以說是另外一種controller。目前的controller manager集合的主要是基礎的、通用的資源概念,比如rs/deployment,而對於特定的應用或者服務(如etcdcluster,都可以認爲是一種資源),則放權給了第三方,也就是CRD。用戶可以通過自定義的資源描述,以及自研的controller/operator進行接入。因此controller和operator的關係有點類似於標準庫和第三方庫的關係。
一般來說,對於不同的應用一般來說需要不同的operator進行處理。這時我們再來想下,以replicaset controller爲例。rs的主要功能是保持副本數。當有pod因某種原因掛掉/刪除,對於無狀態的應用來說,恢復的方式就是再增加對應的pod數量。那麼從這個角度來說,對於無狀態的應用來說,rs controller其實就是無狀態應用的operator。

operator的核心價值
我們原先常常講devops,就是運維和開發的結合,提升開發交付的效率和質量。這也帶來了一個趨勢,就是運維和開發一體化。比如原來開發應用的人,通過docker鏡像的製作,將應用的部署啓動等固化在了dockerfile/鏡像中,分擔了運維的許多部署工作。但是實際上運維的工作內容和範圍其實非常廣,特別是現在的分佈式的系統,包括集羣化部署、高可用、故障恢復、系統升級等等工作。而這些是無法僅用dockerfile/鏡像進行固化的。
operator提供了一種可能,或者說是提供了一個很好的框架,就是把運維的經驗沉澱爲代碼,實現運維的代碼化、自動化、智能化。以往的高可用、擴展收縮,以及故障恢復等等運維操作,都通過operator進行沉澱下來。從長期來看,將會推進dev、ops、devops的深度一體化。將運維經驗、應用的各種方案和功能通過代碼的方式進行固化和傳承,減少人爲故障的概率,提升整個運維的效率。
operator的許多理念並不是現在纔有的。在yarn中的application manager,mesos中的framework,都可以尋找到operator的一些蛛絲馬跡。而之所以說operator將可能成爲docker之後的又一項重大變革,其另外一個重要的因素就是operator是站在kubernetes的巨人肩膀上。
kubernetes強化了基礎資源的封裝,並保持了靈活性和可定製性。kubernetes從傳統的資源(cpu/mem)的交付,轉爲了pod/svc/pv/pvc等資源的交付,擴展了資源的概念,將域名、負載均衡、存儲等等必要或相關的概念也都進行了封裝。而operator這些公共的資源基礎上,將應用集羣也視爲了一種資源,可以向用戶提供。並且藉助於k8s已有的工作機制和框架,從而更爲便捷靈活的實現。
operator的變革雖然重大,但是由於分佈式應用主要限於工業生產領域,因此對一般的開發而言可能最終使用場景有限。因此我判斷從全局看,operator的最終影響力有限,但在許多分佈式應用的垂直領域,會產生巨大的影響。

最後使用operator的前提就是可以實現容器化。即應用可以使用容器來進行應用的自動化的部署。operator化不僅僅是開發一個operator的程序,還需要結合鏡像的製作、交付、封裝等工作。仍然是需要大量的開發工作的。但是一旦成熟穩定,也會帶來巨大的運維收益和長期的效果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章