kube-on-kube-operator 開發(一)

  • 2019 年 12 月 20 日
  • 筆記

kubernetes 已經成為容器時代的分散式作業系統內核,目前也是所有公有雲提供商的標配,在中國,阿里雲、騰訊雲、華為雲這樣的公有雲大廠商都支援一鍵部署 kubernetes 集群,而 kubernetes 集群自動化管理則是迫切需要解決的問題。對於大部分不熟悉 kubernetes 而要上雲的小白用戶就強烈需要一個被託管及能自動化運維的集群,他們平時只是進行業務的部署與變更,只需要對 kubernetes 中部分概念了解即可。同樣在私有雲場景下,筆者所待過的幾個大小公司一般都會維護多套集群,集群的運維工作就是一個很大的挑戰,反觀各大廠同樣要有效可靠的管理大規模集群,kube-on-kube-operator 是一個很好的解決方案。

所謂 kube-on-kube-operator,就是將 kubernetes 運行在 kubernetes 上,用 kubernetes 託管 kubernetes 方式來自動化管理集群。和所有 operator 的功能類似,系統會定時檢測集群當前狀態,判斷是否與目標狀態一致,出現不一致時,operator 會發起一系列操作,驅動集群達到目標狀態。今年 kubeCon 上,雅虎日本也分享了其管理大規模 kubernetes 集群的方法,4000 節點構建了 400 個 kubernetes 集群,同樣採用的是 kube-on-kube-operator 架構,以 kubernetes as a service 的形式使用。

kubernetes-operator 設計參考

記得 kube-on-kube-operator 的概念最初是在去年的 kubeCon China 上螞蟻金服提出來的,先看看螞蟻金服以及騰訊雲 kube-on-kube-operator 的設計思路,其實騰訊雲的架構和螞蟻金服的是類似的。以下是螞蟻金服的架構設計圖:

首先部署一套 kubernetes 元集群,通過元集群部署業務集群,業務集群的 master 組件都分布在一台宿主上,該宿主以 node 節點的方式掛載在元集群中。在私有雲場景下,這樣的部署方式有一個很明顯的問題就是元集群節點跨機房,雖然業務集群的 master 與 node 都是在同一個機房,但是元集群中的 node 節點大部分是分布在不同的機房,有些公司在不同機房之間會有網路上的限制,有可能網路不通或者只能使用專線連接。在公有雲場景下,元集群自己有一套獨立的 vpc 網路,它要怎麼和用戶的 vpc 結點進行通訊呢?騰訊雲的做法是利用 vpc 提供的彈性網卡能力,將這個彈性網卡直接綁定到運行 apiserver 的 pod 中,運行 master 的這個pod 既加入了元集群的 vpc,又加入了用戶的 vpc,也就是一個 pod 同時在兩個網路中,這樣就可以很好的去實現和用戶 node 相關的互通。這種方式都是通過 kubernetes API 去管理 master 組件的,master 組件的升級以及故障自愈都可以通過 kubernetes 提供的方式實現。

kubernetes-operator 設計

kubernetes-operator 項目地址:https://github.com/gosoon/kubernetes-operator

目前該項目的主要目標是實現以下三種場景中的集群管理:

  • kube-on-kube
  • kube-to-kube
  • kube-to-cloud-kube

kubernetes-operator 不僅是要實現 kube-on-kube 架構,還有 kube-to-kube,kube-to-cloud-kube,kube-to-kube 即 kubernetes 集群管理業務獨立的 kubernetes 集群,兩個集群相互獨立。kube-to-cloud-kube 即 kubernetes 集群管理多雲環境上的 kubernetes 集群。

上面是項目的架構圖,紅色的線段表示對集群生命周期管理的一個操作,涉及集群的創建、刪除、擴縮容、升級等,藍色線段是對集群應用的操作,集群中應用的創建、刪除、發布更新等,kubernetes-proxy 是一個 API 代理,所有涉及 API 的調用都要通過 kubernetes-proxy。左邊部署有 kubernetes-operator 的是元集群,kubernetes-operator 使用 etcd 僅存儲部分配置資訊,其管理業務集群的生命周期,支援三種集群的創建方式,第一種方式就是可以創建出類似螞蟻金服這種直接將業務集群 master 運行在元集群,node 節點在業務集群,第二種是以二進位方式創建業務集群,其中業務集群的 master 以及 node 都是在業務集群所在的機房,第三種方式就是在各種公有雲廠商創建集群,以一種統一的方式管理公有雲上的集群,也可以稱作融合雲。

項目結構

總體來說,項目暫時分為三大塊:

  • kubernetes proxy:支援 API 透傳、訪問控制等功能;
  • 控制器:也就是 kubernetes-operator,管理業務集群的生命周期;
  • 集群部署模組:用來部署業務集群,目前主要在開發第二種方式使用二進位部署業務集群;
  • kubernetes 應用安裝模組:在新建完成的集群中部署監控、日誌採集、鏡像倉庫、helm 等組件;

控制器

控制器也就是 Operator + CR,目前開發 operator 的方式已知的有三種:

  • 自定義 controller 的方式:kube-controller-manager 中所有的 controller 就是以自定義 controller 的方式,這種方式是最原生的方式,需要開發者了解 kubernetes 中的程式碼生成,informer 的使用等。
  • operator-sdk 的方式:一個開發 Operator 的框架,對於一些不熟悉 kubernetes 的可以使用 operator-sdk 的方式,這種方式讓開發者更注重業務的實現,但是不夠靈活。
  • kubebuilder 的方式:kubebuilder 是開發 controller manager 的框架,controller manager 會管理一個或者多個 operator。

kubebuilder, operator-sdk 都是對controller-runtime做了封裝, controller runtime又是對client-go shardInfromer 做的封裝,本質上其實都一樣的。kubernetes-operator 使用的是自定義 controller 的方式,如果想要更深入的學習 kubernetes,非自定義 controller 方式莫屬了,kube-controller-manager 組件中的各種 controller 都是使用這種方式開發的,完全可以按照官方這種套路來開發。在 kubernetes 中,目前有兩種方式可以定義一個新對象,一是 CustomResourceDefinition(CRD)、二是 Aggregation ApiServer(AA),其中 CRD 是相對簡單也是目前應用比較廣的方法。kubernetes-operator 採用 CRD 的方式。

集群部署

其實項目中最難的是集群部署這一部分,部署集群目前有兩種方式,二進位部署和容器化部署,但是都有一些開源工具的支援。手動部署一個二進位集群需要熟悉 docker 的部署、etcd 的部署、角色證書的創建、RBAC 授權、網路配置、yaml 文件編寫、kubernetes 集群運維等等,總之手動部署一個二進位集群是非常麻煩的,但是要真正會用 kubernetes 是逃不了部署這一步的。第二種方式就是以容器化的方式部署,這種部署方式相對來說比較簡單,有現成的工具直接傻瓜式操作就能部署成功。但是我目前選擇的是使用二進位的部署方式,由於自己運維過二進位的 kubernetes 集群,對於私有雲場景一般都是直接將集群部署在物理機上,作為生產環境,自己認為容器化的方式部署還不是非常成熟的,目前工作過的大小公司中,生產環境暫時沒有以容器化的方式運行集群。所以 kubernetes-operator 中目前主要支援的就是使用二進位部署集群。

目前比較成熟的用於生產環境的 kubernetes 集群部署工具有:kubeadm、kubespary、kops、rancher、kubeasz 等。kubeadm、kubespary、kops 都是官方開源的產品,kubeadm 使用容器化的方式部署,需要手動執行一些部署命令,暫時無法完全自動化部署。kubespary 是對 kubeadm 的一層封裝,使用 ansible + kubeadm 的方式自動化進行部署,據說阿里雲就是使用 kubespary 部署集群的。在公有雲的環境(GCP、AWS)通常使用 kops 部署起來更方便些。kubeasz 是使用 ansible 自動化的方式部署二進位集群,目前也已經比較成熟了。

應用安裝

  • 監控:當然是使用 promethus;
  • 日誌採集:使用 filebeat 或者基於 filebeat 封裝的一些組件如 logpilot,其他的還有 logkit 等都可以嘗試使用;
  • 鏡像倉庫:當然是使用 harbor;
  • HPA:組件以及應用的自動擴縮容;

應用安裝使用 helm 的方式進行安裝。

集群升級

若以二進位部署最好是替換二進位文件的方式進行升級,若使用容器化部署,master 部署在元集群中可以使用 kubernetes 的滾動方式升級否則要以修改 manifest 文件的方式。

集群升級包括配置和版本的升級,集群部署完成後,master 的配置改動不會很頻繁,由於要進行性能上的優化以及業務的支援,對於 node 組件上的配置升級還是比較多的。對於集群的版本升級,升級的難度係數隨著版本的跨度增大而增大,若按照官方的升級流程,一般不會出現異常。升級操作一般都是先升 master 再升 node,在工作中經歷的幾次版本升級中,每次升級完 master 後理論上不會再回退了,除非升級過程中有問題,否則升級完成後已經很難回退了,master 升級完成後 APIServer 的一些 API 還有 pod 的欄位都有可能改變,master 版本回退後一些已存在的應用可能會異常,或者還可以參考 openshift 的藍綠升級方式。二進位部署的集群盡量以替換二進位文件的方式進行升級,對於容器化部署的集群,可以直接使用 kubernetes 的滾動方式升級或者是修改 manifest 文件的方式。

目前螞蟻金服 kube-on-kube-operator 架構中在業務集群中會部署一個 node-operator,node-operator 會記錄 master 組件的鏡像、默認啟動參數等資訊,其作用就是節點配置管理、集群組件升級以及節點故障自愈,未來在項目中也會實現基於此的方式。

後期計劃

  • 支援部署 k3s、kubeedge:5G 時代,邊緣計算將是非常火的,目前各大廠商也都在此布局,所以支援部署 k3s、kubeedge 這些專門支援邊緣計算的產品還是非常有必要的。
  • 支援使用 kops 部署
  • 支援部署多版本 k8s
  • node-operator 開發,支援集群的配置管理、自動化升級、故障自愈等功能
  • 用戶及許可權管理:操作集群用戶的許可權和 kubernetes 中 RBAC 規則綁定
  • Kubernetes-operator 一些功能的擴展和完善

參考:

騰訊雲容器服務TKE:一鍵部署實踐

一年時間打造全球最大規模之一的Kubernetes集群,螞蟻金服怎麼做到的?

https://github.com/gosoon/kubernetes-operator