深度 | 螞蟻金服自動化運維大規模 Kubernetes 集羣的實踐之路

導讀

此文章分享了螞蟻金服如何自動化運維大規模 Kubernetes 集羣的實踐乾貨。git

"大規模 Kubernetes 集羣"主要體如今幾十個 Kubernetes 集羣,十萬級別的 Kubernetes Worker 節點。github

螞蟻金服使用 Operator 的模式去運維 Kubernetes 集羣,能便捷、自動化的管理 Kubernetes 集羣生命週期,作到 " Kubernetes as a Service " 。docker

此文適合 Kubernetes 愛好者,Kubernetes 架構師,以及 PE/SRE 閱讀。編程

前序知識

Kubernetes 架構介紹

此章節簡單介紹 Kubernetes 集羣的架構。主要是爲了面向剛學習 Kubernetes 的同窗,對於熟悉 Kubernetes 的同窗,此章節能夠跳過。api


如上圖,一個 Kubernetes 集羣由 Master 節點和 Worker 節點組成。安全

在一個高可用 Kubernetes 集羣下面,Master 節點通常爲3臺,在它們上面須要運行Kubernetes Master 組件。Kubernetes Master 組件包括 etcd, Apsierver, Scheduler 和 Controller-Manager。每一個 Master 組件通常都是 3 個實例,以保證它們的高可用。Master 節點使用 Static Pod 方式啓動 Master 組件,即將每一個組件的 Pod 描述文件放入 Master 節點的指定目錄,Kubelet 會在啓動時將他們讀取,並以 Static Pod 方式啓動。bash

Kubernetes Worker 節點爲 Kubernetes 集羣提供調度資源和應用運行環境。即全部的 Pod(能夠理解爲應用的一個個最小化部署單元)都運行在 Worker 節點上。一個Worker 節點須要將 Pod 運行上去,須要一些 on-host 軟件,這些軟件包括: kubelet, Runtime Service(docker, pouch 等實現方案), CNI 插件等。微信

Operator 介紹

咱們在這裏將花不多的篇幅向剛學習 Kubernetes 的同窗介紹 Operator。若是指望得到更詳細的解讀請參考 coreos 上關於 Operator 的介紹。架構

一個 Operator 其實是爲了解決某個複雜應用在 Kubernetes 的自動化部署、恢復。有了Operator,用戶只須要向Kubernetes Apiserver提交一個CRD Resource(yaml或者JSON,一個CRD Resource其實就是對應一個應用實例,CRD Resource用於描述這個應用實例的配置),Operator 就會根據用戶的需求去完成這個應用實例的初始化,在應用某個模塊發生故障時,Operator 也會作出自動恢復功能。Operator 是用代碼運維應用最好的實踐之一。less

好比咱們有一個etcd-operator,咱們只須要用戶根據需求向 Kubernetes Apiserer 提交以下的 CRD Resource,etcd-operator 就能初始化完成一個 etcd 集羣:

apiVersion: etcd.database.coreos.com/v1beta2
kind: EtcdCluster
metadata:
  name: xxx-etcd-cluster
spec:
  size: 5複製代碼

其中,上面的Spec.Size=5 表明了咱們須要一個由 5 個 etcd 節點組成的 etcd 集羣。etcd-operator 會根據上面的配置,初始化完成 etcd 集羣。相應的,若是你又須要另外一個 3 節點的etcd 集羣,你只須要提交新的一個Spec.Size=3的 CRD Resource 便可。

背景

在螞蟻金服,咱們面臨着須要運維幾十個 Kubernetes 集羣,以及十萬級別以上的Kubernetes Worker 節點的難題。

咱們將運維 Kubernetes 的工做拆分兩部分,一部分是運維 Kubernetes 集羣的 Master 組件(etcd, Apiserver, controller-manager, scheduler等),一部分是運維 Kubernetes Worker 節點。咱們總結了這兩部分運維的難點。

難點1:運維 Kubernetes 集羣 Master 角色

  1. 如何快速新建、下線一個 Kubernetes 集羣 (初始化、刪除 Master 角色)。因爲螞蟻業務的快速增加,咱們隨時面臨着須要在新機房新建、下線一個 Kubernetes集羣;CI 和測試也有快速新建、刪除一個 Kubernetes 集羣的需求。

  2. 如何管理幾十個 Kubernetes 集羣 Master 組件版本。好比咱們須要升級某幾個Kubernetes 集羣的 Apiserver,Scheduler 等組件。

  3. 如何自動化處理幾十個 Kubernetes 集羣 Master 組件發生的故障。

  4. 如何能獲取幾十個 Kubernetes 集羣 Master 組件的統一視圖。咱們但願有一個統一的接口,一下就能獲取每一個 Kubernetes 集羣 Master 角色的版本、狀態等信息。

難點2:運維 Kubernetes Worker 節點

  1. 如何快速上線、下線 Kubernetes Worker 節點。上線時,咱們須要保證 Kubernetes Worker 節點所須要的on-host軟件版本、配置正確。

  2. 如何升級十萬級別的 Kubernetes Worker 節點上的 on-host 軟件。如咱們須要將全部Work節點的 docker、cni 版本升級到某個版本。

  3. 如何優雅的執行灰度發佈 Kubernetes Worker 節點上的軟件包。在 on-host 軟件新版本上線前,咱們須要對它作小範圍的灰度發佈,即挑選 N 臺 Worker 節點發布新版本軟件包,執行驗證,最後根據驗證結果決定是否全規模的發佈新版本,或者回滾這個灰度發佈。

  4. 若是自動化處理十萬級別的 Kubernetes Worker 節點可能出現的 on-host 軟件故障。好比 docker\kubelet 發生 panic,咱們是否能自動化得處理。

實現方案

在螞蟻,咱們使用 Kube-on-Kube-Operator 和 Node-Operator 組合使用解決上述的難題。

  1. 首先,咱們須要藉助工具,使用Kubernetes官方提供的方案( Static Pod 方式)部署「 Kubernetes 元集羣」(後面簡稱元集羣)到 「元集羣」的 Master 節點上。

  2. 而後,咱們將 Kube-on-Kube-Operator 部署到 「 Kubernetes 元集羣」。咱們將一個 Kubernetes 集羣所需的一系列 Master 組件當成一個複雜的應用。當咱們須要一個「 Kubernetes 業務集羣」(後面簡稱業務集羣),咱們只須要向元集羣 Apiserver 提交用於描述「 Kubernetes 業務集羣」的 Cluster CRD Resource (下文會介紹咱們如何設計 CRD 結構),Kube-on-Kube-Operator 就爲咱們準備好了一個能夠工做的「Kubernetes 業務集羣」("業務集羣" Master 組件都已經Ready,須要擴容 Worker 節點)。

  3. 以後咱們在「 Kubernetes 業務集羣」上,部署上 Node-Operator。Node-Operator 負責 Worker 節點的生命週期。當咱們須要擴容一個 Worker 節點,咱們只須要提交描述 Worker 節點的元數據( IP, Hostname, 機器運維登陸方式等)的 Machine CRD Resource (下文會介紹咱們如何設計 CRD 結構),Node-Operator 就會將 Worker 節點初始化完成,併成功加入到 「 Kubernetes 業務集羣」 中。


「元集羣」 只用於管理全部「業務集羣」所需的 Master 組件。「業務集羣」是真正提供給業務方運行 Pod 的 Kubernetes 集羣。也就說,在螞蟻金服,咱們只有一個 「元集羣」, 在這個 「元集羣」中,咱們使用 Kube-on-Kube-Operator 自動化管理了螞蟻金服全部的 「 Kubernetes 業務集羣」 的 Master 組件。

固然,「元集羣」也會部署 Node-Operator,用於「元集羣」 Worker 節點的上下線,「元集羣」的 Worker 節點也是各個 「業務集羣」 的 Master 節點。

Kube-on-Kube-Operator

Kube-on-Kube-Operator 用於 Watch Cluster CRD Resource的變動,將"Cluster"所描述表示的 Kubernetes 業務集羣的全部 Master 組件 達到最終狀態。以下圖,是「元集羣」和它所管理的兩個「Kubernetes 業務集羣」的最終狀態:

Cluster CRD 的定義包含以下一些信息:

  1. 業務集羣名。

  2. 業務集羣部署模式: 分爲標準生產和最小化。標準生產提供Master組件都是3副本的部署,最小化則都是1個副本的部署。

  3. 業務集羣 Master 節點 NodeSelector,即表示如何在元集羣內如何選擇業務集羣Master 節點。

  4. 業務集羣各 Master 組件版本,自定義參數等

  5. 業務集羣所使用的 etcd 啓動配置,主要涉及 etcd data volume 的設置。有ClaimTemplate 和 VolumeSource 兩種模式,即便用 ClaimTemplate 模式就使用PVC 來初始化 etcd volume,而使用 VolumeSource 模式,即便用 VolumeSource 所表示的 volume 來掛載 etcd volume。

  6. 業務集羣 Master 組件證書過時時間: Master 組件所使用 kubeconfig 中的證書都有過時時間,以保證安全性。而 Kube-on-Kube-Operator 會在證書過時時自動完成滾動證書、Master 組件從新加載證書等操做。

  7. 業務集羣額外用戶 kubeconfig:即爲 「額外用戶」提供的用戶名和組名,簽出證書,並生成 kubeconfig 保存在元集羣 Secret 中供讀取。

  8. 業務集羣狀態: 這部分信息不須要用戶提交,而是由 Kube-on-Kube-Operator 自動生成,用戶反饋這個業務集羣的狀態,參考 Pod.Status 。

一個業務集羣的 Master組件 部署 實際是元集羣中的一系列 Resource 組成,即包括Deployment,Secret,Pod,PVC 等組合使用。各 Master 組件 所須要的部署 Resource 以下:

  1. Apiserver: 一個 Deployment 便可,由於 Apiserver 是無狀態應用,副本數和Cluster CRD 描述的一致便可。除此以外,須要爲Apiserver建立兩個 Service:

    1. 向同個業務集羣的其它 Master 組件提供服務的 Service: 建議使用元集羣內的 Headless Service。

    2. 向 Kubelet、外部組件提供服務的 Service: 建議使用機房 DNS RR Service (須要本身實現 Service Controller )。

  2. etcd: 每一個 etcd 實例(標準化部署是 3 個實例,最小化是 1 個實例)都建議單獨使用 Pod + PV + PVC + Headless Service 部署。每一個etcd 實例的 peer id 爲對應的Headless Service 域名。當某個 etcd 實例發生故障時,須要手動刪除掉故障對應實例的 Pod,Kube-on-Kube-Operator watch 到 etcd Pod 的減小,會從新創建 Pod,並執行 Remove old member (被刪除的 Pod ), Add new member(新建的Pod)操做,可是他們的peer id仍是保持一致的。

  3. Controller-Manager: 一個 Deployment 便可,由於 Controller-Manager 是無狀態應用。副本數和 Cluster CRD 描述的一致便可。

  4. Scheduler: 一個 Deployment 便可,由於 Scheduler 是無狀態應用。副本數和Cluster CRD 描述的一致便可。

Kube-on-Kube-Operator 除了可以部署上述的 Master 組件以外,還能維護任何擴展組件,如 kube-proxy,kube-dns 等。只須要用戶提供 擴展組件部署模板 和 擴展插件版本,Kube-on-Kube-Operator 能渲染出部署 Resource,並保持這些部署 Resource 到最終態。因爲篇幅緣由,咱們這裏再也不贅述。

Node-Operator

Node-Operator 用於 Watch Machine CRD Resource 的變動,將"Machine"所描述表示的 Worker 節點上的 on-host 軟件(docker, kubelet, cni)達到最終態,最終能讓 "Machine"所對應的"Node" 在 Kubernetes 集羣中達到"Ready"狀態。架構圖以下:

Machine CRD 的定義包含以下一些信息:

  1. 機器元數據: IP, Hostname, IDC 等

  2. 機器運維 ssh 登陸方式和登陸祕鑰: 如最多見的 SSH Key;若是 Machine 是阿里雲的 ECS, 那麼登陸方式和登陸祕鑰是阿里雲提供的 SSH 接口和對應的鑑權信息等。

  3. 各個on-host 軟件版本和自定義參數

  4. Machine 狀態: 這部分信息不須要用戶提交,而是由 Node-Operator 生成,表示這個機器的當前狀態,參考 Pod.Status 。

Node-Operator 還用 Watch Machine 對應 Node 的狀態,當發生一些能處理的 Condition(好比 kubelet 運行中進程消失了)時,Node-Operator 會作出恢復處理。

Node-Operator 還會 Watch ClusterPackageVersion CRD 的變動,這個 CRD 表示整個Kubernetes 集羣 kubelet、docker 等組件的默認版本,Node-Operator 會根據 ClusterPackageVersion 描述的信息,控制各個節點的 kubelet、docker 等組件的版本。

Node-Operator 還支持控制某些組件灰度發佈到某些節點中。用戶只要提交描述這個灰度發佈的 CRD 到 Apiserver,Node-Operator 會有序的執行灰度發佈,並將發佈狀態反饋到 CRD 中。因爲篇幅緣由,咱們再也不贅述。

結束語

螞蟻金服在運維大規模 Kubernetes 集羣實踐中,咱們擯棄了傳統的模式,使用了Operator 模式和麪向 Apiserver 編程。

Kubernetes 集羣的上下線、升級實現了 "Kubernetes as a Service" ,就像向雲廠商買一個服務同樣簡單。而 Worker 節點的運維,使用 Operator 模式可以讓咱們統一管理元數據,自動化初始化、恢復 Worker 節點所需的組件。

此文做者是供職於 「螞蟻金服-資源調度」 部門的陳俊,微信聯繫方式: answer1991chen 。「螞蟻金服-資源調度」 部門求賢若渴,有意的同窗請發送簡歷到 chenjun.cj@alibaba-inc.com

長按關注,獲取最新分佈式架構乾貨

歡迎你們共同打造 SOFAStack https://github.com/alipay

相關文章
相關標籤/搜索