探祕金融級雲原生髮布工作負載 CafeDeployment

SOFAStack發表於2019-06-20

image.png

本文作者:螞蟻金服 昊天,楓晟

本文簡單介紹了螞蟻金服 SOFAStack 的 Kubernetes 自定義資源 CafeDeployment 的開發背景和功能特性,我們將會在6月25日的 KubeConf 上對其做詳細的介紹和演示,歡迎大家來交流。

背景介紹


Kubernetes 原生社群 Deployment 和 StatefulSet 解決了“服務節點版本一致性”的問題,並且通過 Rolling Update 實現了滾動升級,提供了基本的回滾策略。對於高可用建設要求不高的“年輕”業務,是一個不錯的選擇。


但是,在金融場景下,要解決的場景複雜得多。因此我們在金融分散式架構-雲應用引擎(SOFAStack-CAFE,參見金融級雲原生探索實踐系列 - 開篇)中提出了 CafeDeployment 的雲原生模型,致力於解決以下問題:

1、IP 不可變

對於很多運維體系建設較為早期的使用者,使用的服務框架、監控、安全策略,大量依賴 IP 作為唯一標識而被廣泛使用。遷移到 Kubernetes 最大的改變就是 IP 會飄,而這對於他們來說,無異於運維、服務框架的推倒重來。

2、金融體系下的高可用

Deployment/StatefulSet 無法根據特定屬性進行差異化部署。而在以同城雙活為建設基礎的金融領域,為了強管控  Pod 的部署結構(即保證每個機房/部署單元都有副本執行),若通過原生元件進行部署,我們不得不維護多個幾乎一模一樣的 Deployment/StatefulSet,來保證 Pod 一定會飄到指定機房/部署單元的 node 上。在規模上到一定程度後,這無疑加大了運維管控的複雜度和成本。

3、靈活的部署策略

Deployment 無法控制釋出步長,StatefulSet 雖然可以控制步長,但是每次都需要人工計算最新版本需要的副本數並修改 Partition,在多機房/部署單元的情況下,光想想釋出要做的操作都腦袋炸裂。


在面對以上這些問題的時候,我們思考:能不能有一個類似 Deployment 的東西,不僅可以實現副本保持,並且能協助使用者管控應用節點部署結構、做 Beta 驗證、分批發布,減少使用者干預流程,實現最大限度減少釋出風險的目標,做到快速止損,並進行修正干預。這就是我們為什麼選擇定義了自己的資源——CafeDeployment

模型定義

image.png

CafeDeployment 主要提供跨部署單元的管理功能,其下管理多個 InPlaceSet。每個 InPlaceSet 對應一個部署單元。部署單元是邏輯概念,他通過 Node 上的 label 來劃分叢集中的節點,而 InPlaceSet 則通過 NodeAffinity 能力,將其下的 Pod 部署到同一個部署單元的機器上。由此實現 CafeDeployment 跨部署單元的管理。

CafeDeployment 作為多個部署單元的上層,除了提供副本保持,歷史版本維護等基本功能,還提供了跨部署單元的分組擴容,分組釋出,Pod 排程等功能。模型定義如下:

apiVersion: apps.cafe.cloud.alipay.com/v1alpha1
kind: CafeDeployment
metadata:
  ......
spec:
  historyLimit: 20
  podSetType: InPlaceSet    # 目前支援底層PodSet:InPlaceSet,ReplicaSet,StatefulSet
  replicas: 10
  selector:
  matchLabels:
    instance: productpage
    name: bookinfo
  strategy:
    batchSize: 4    # 分組釋出時,每組更新的Pod數目
    minReadySeconds: 30
    needWaitingForConfirm: true    # 分組釋出中,每組結束時是否需要等待確認
    upgradeType: Beta    # 目前支援釋出策略:Beta釋出,分組釋出
    pause: false
  template:
    ......
  volumeClaimTemplates:    # 用於支援statefulSet
  serviceName:        # 用於支援statefulSet
  topology:
    autoReschedule:
      enable: true    # 是否啟動Pod自動重排程
      initialDelaySeconds: 10
    unitType: Cell    # 部署單元型別:Cell,Zone,None
    unitReplicas:
      CellA: 4        # 固定某部署單元的Pod數目
    values:        # 部署單元
      - CellA
      - CellB

因為我們將大部分的控制邏輯都抽取到上層 CafeDeployment 中,因此我們重新設計了 InPlaceSet,將它做得足夠簡單,只關注於“InPlace”相關的功能,即副本保持和原地升級,保持 IP 不變的能力,模型定義如下:

spec:
  minReadySeconds: 30
  replicas: 6
  selector:
    matchLabels:
      instance: productpage
      name: bookinfo
      deployUnit: CellB
  strategy:
    partition: 6        # 控制釋出時更新Pod的進度
  template:
    ......

功能特性

靈活的分組定義

CafeDeployment 支援跨部署單元的分組擴容,Pod 排程,分組釋出。分組策略主要分為兩種,Beta 分組和 Batch 分組:

  • Batch 分組

即根據 BatchSize 將 Pod 分為多個批次,每批中的 Pod 會同時釋出。待使用者確認(needWaitingForConfirm=true時)無誤時,或當前批次所有 Pod 都 ready 後(needWaitingForConfirm=false 時),則會開始進行下一組的釋出。

在分組暫停時,CafeDeployment 會被打上 Annotation: cafe.sofastack.io/upgrade-confirmed=false,使用者可通過將 Annotation 的值改為 true,確認當前分組。

  • Beta 分組

相比 Batch 釋出,會在第一組釋出之前多一步 Beta 分組。此組會在每個部署單元內選擇一個 Pod 進行釋出,以減小錯誤配置帶來的影響。若使用者確認無誤,可以確認繼續,以進入正常的 Batch 釋出流程。

安全的分組擴容和釋出能力

分組擴容

為預防不正確的配置造成大量錯誤 Pod 同時建立,佔用大量資源等意外情況出現,CafeDeployment 支援分組擴容,以降低風險。

在如下配置時,CafeDeployment 會建立兩個 InPlaceSet 例項,並開始分組建立(擴容)Pod。

spec:
    ......
  replicas: 10                                # 副本數為10
  strategy:
    upgradeType: Beta                        # Beta釋出
    batchSize: 4                                # 每組Pod數為4
    needWaitingForConfirm: true    # 分組暫停
  topology:
    ......
    values:        # 兩個部署單元,CellA和CellB
      - CellA
      - CellB

初始時,InPlaceSet 的 replicas 和 partition 都為 0,CafeDeployment 會在之後預設將 10 個 Pod 均分到兩個部署單元中,並參考 Beta 釋出和 BatchSize 配置,分成 3 組進行,如下圖所示。

image.png

第一組,為 Beta 分組,會在兩個部署單元中各建立一個 Pod。待 Pod 都 ready 後,會要求使用者進行確認,方可繼續第二組。

第二組,為普通釋出,因為 BatchSize=4,所以會在兩個部署單元中各建立 2 個 Pod。之後同樣需要經過用確認才會繼續進入第三組。若 CafeDeployment 中的配置 needWaitingForConfirm=false,則在當前批次的所有 Pod 都 ready 後,會自動進入下一組的釋出。

第三組,為最後一組釋出,當所有 Pod 都 ready 後,則會結束當前釋出。

釋出過程中若出現問題,可通過修改 CafeDeployment 的 replicas 值等方式結束當前釋出。

分組釋出

當修改 CafeDeployment 中的 PodTemplate 裡的相關配置後,就會觸發釋出流程。目前同樣支援 Beta 釋出和 Batch 釋出兩種型別。當 CafeDeployment 有如下配置時,CafeDeployment 的 10 個 Pod 會被分到三組中進行釋出。

spec:
    ......
  replicas: 10                                # 副本數為10
  strategy:
    upgradeType: Beta                        # Beta釋出
    batchSize: 4                                # 每組Pod數為4
    needWaitingForConfirm: true    # 分組暫停
  topology:
    ......
    values:        # 兩個部署單元,CellA和CellB
      - CellA
      - CellB

第一組為 Beta 分組,每個部署單元會選擇一個 Pod 進行釋出。

第二組和第三組各有 4 個 Pod。

若當前 Pod 在部署單元的分配不均勻,如下圖所示,CafeDeploymentController 也會負責計算並分配對應的配額給兩個部署單元,來對釋出進度進行統一的排程。

如果配置了分組暫停,則每組結束後都會需要使用者進行確認。

image.png

Pod 釋出與外部的通訊機制


使用 Readiness Gate 作為 Pod 是否可以承載外部流量的標識。在釋出前,通過將 Readiness Gate 設定為 False,使得當前 Pod IP 在 Endpoint 上從 addresses 列表轉移到 notReadyAddresses 列表;在釋出完成後,將 Readiness Gate 設定為 True,Pod IP 在 Endpoint 上又會從 notReadyAddresses 轉移到 addresses。相關流量元件通過 Watch Endpoint 上地址變化完成切流和引流,並通過 finalizer 對 Pod 進行打標保護。


pod-graceful-shutdown.jpg

自適應的 Pod 重排程

在建立 Pod 的過程中,可能會遇到某個部署單元資源不足的情況,新的 Pod 會一直 Pending。這時如果開啟自動重排程功能(如下所示),則 CafeDeploymentController 會嘗試將 Pod 分配到其他未出現資源緊張的部署單元上。

spec:
  topology:
    autoReschedule:
      enable: true                        # 是否啟動Pod自動重排程
      initialDelaySeconds: 10    # Pod由於資源不足,10秒後會被嘗試重排程

在 Pod 部署過程中,如下圖所示,
image.png

如果在最後一批分組釋出的時候,出現 Pod 因資源不足而無法啟動的情況,則 CafeDeploymentController 會自動將此 Pod 的配額排程到其他的資源充足的部署單元中。

當然,CafeDeployment 也支援手動指定 Pod 的分配方案,通過修改如下相關配置可以進行精確的指定:

spec:
  topology:
    ......
    unitReplicas:
      CellA: 4        # 固定某部署單元的Pod數目
      CellB: 10%    # 通過百分比指定
    values:
      - CellA
      - CellB
      - CellC

這時,CafeDeploymentController 會優先根據指定方案進行 Pod 分配。

可適配多種社群工作負載

CafeDeploymentController 本身只提供了釋出策略和跨部署單元管理的一個抽象實現,它對底層的 Pod 集合是通過 PodSetControlInterface 介面來控制。因此,通過對此介面的不同實現,可以保證對接多種 workload。目前已經實現了與 InPlaceSet 和 ReplicaSet 的對接,對 StatefulSet 的對接也在進行中。

image.png

因為 CafeDeployment 只負責各種策略的實現,所以並不會對 Kubernetes 原生的功能有任何入侵。ReplicaSetController,StatefulSetController 會繼續履行他們之前的職責,保證各自的特性。

總結

CafeDeployment 的設計與實現,並非一日之功,我們走過彎路,也受到過質疑。但我們仍然堅信,在金融場景下需要這樣的一種工作負載,因為無論是 Deployment、StatefulSet 還是 InPlaceSet,為了實現高可用和無損釋出,都無疑需要付出比 apply yaml 更多的精力,而這些往往都不是一個業務開發所關心的。

目前,CafeDeployment所提供的各種釋出策略,靈活的分組釋出,高可用和無損升級的能力已成為了金融雲應用釋出的重要一環,為產品層提供容器雲原生的部署能力,並給我們使用者的生產力和效率帶來極大提升。後續我們將會繼續增強 CafeDeployment 的能力,比如提供更靈活的自定義拓撲結構、機房/部署單元內更靈活的部署策略以滿足更多的高可用釋出場景的需求等。

KubeCon + CloudNativeCon | Open Source Summit 2019 中國論壇

分享主題:《為網際網路金融關鍵任務場景擴充套件部署》-螞蟻金服
分享嘉賓:
Mengyi Zhou:Mengyi Zhou is a software engineer at PaaS cloud service team of Ant Financial, where she focuses on building large-scale deployment platform for both vm and container services on cloud. She indulges herself into devops workflow and experience. She is one of the core developer of AntCloud kubernetes service.
Ke Wu:Ke Wu is a Senior Engineer from Ant Financial. Ke works in Ant Financial PaaS cloud service team, with a focus on AntCloud Kubernetes Service development including extending Kubernetes for financial scenario. Ke has worked on PaaS and Big Data for years. He is also a contributor of Kubernetes.
活動時間:2019.6.25
詳情請戳“這裡”。

相關文章