OpenKruise v0.5.0 版本發佈,支持無損的流式分批發布策略

頭圖.png

做者 | 酒祝  阿里雲技術專家git

導讀OpenKruise 是阿里雲開源的大規模應用自動化管理引擎,在功能上對標了 Kubernetes 原生的 Deployment/StatefulSet 等控制器,但 OpenKruise 提供了更多的加強功能如 優雅原地升級、發佈優先級/打散策略、多可用區 workload 抽象管理、統一 sidecar 容器注入管理等,都是經歷了阿里巴巴超大規模應用場景打磨出的核心能力。這些 feature 幫助咱們應對更加多樣化的部署環境和需求、爲集羣維護者和應用開發者帶來更加靈活的部署發佈組合策略。github

目前在阿里巴巴內部雲原生環境中,絕大部分應用都統一使用 OpenKruise 的能力作 Pod 部署、發佈管理,而很多業界公司和阿里雲上客戶因爲 K8s 原生 Deployment 等負載不能徹底知足需求,也轉而採用 OpenKruise 做爲應用部署載體。web

背景問題

在介紹 OpenKruise 新增能力以前,咱們先來看一下原生 K8s workload 所提供的發佈能力:api

  • Deployment 目前支持 maxUnavailable 和 maxSurge:

1.png

  • StatefulSet 目前支持 partition:

2.png

  • 其他 workload 如 DaemonSet,也只支持了 maxUnavailable。

以上這些策略在測試環境或是小場景下尚且可行,但其實沒法徹底知足大規模的應用場景。比方說:bash

  • 首先,Deployment 不支持灰度分批發布,你想只灰度升級其中 20% 的 Pod 作驗證?抱歉作不到啊,用戶只能設置小一些的 maxUnavailable 等着它所有發完,或者發佈出現問題緊急 pause 暫停;
  • StatefulSet 確實支持灰度分批(partition),但目前是隻能一個一個 Pod 來升級。若是 replicas 總數有個幾百上千的量,那麼一次發佈可能要等到天黑。

v0.5.0 新增功能

這裏咱們只針對 v0.5.0 版本 CloneSet 和 SidecarSet 的兩個主要功能改動來介紹,有興趣的同窗能夠在 Github changelog 上看到版本改動明細:https://github.com/openkruise/kruise/blob/master/CHANGELOG.mdapp

CloneSet 支持 maxSurge 策略

在阿里巴巴內部的雲原生環境下,絕大部分無狀態應用都使用 CloneSet 管理。爲了應對超大規模應用的極致部署需求,咱們在其中支持:less

  • 原地升級(發佈先後 Pod 對象不變、IP 不變、volume 不變,只升級容器的鏡像)
  • 縮小 replicas 指定 Pod 刪除
  • 豐富的發佈策略(流式、灰度分批、優先級、打散等)

而在今年 2 月份的 Kruise v0.4.0 版本中,咱們將 CloneSet 推出到開源。CloneSet 一經發布就廣受關注,目前已經有多家知名互聯網公司在調研使用。ide

最第一版本的 CloneSet 並未支持 maxSurge(先擴後縮發佈),只支持了 maxUnavailable、partition 等策略。這對阿里巴巴內部的大致量應用來講不是問題,可是不少社區用戶的平臺上都有小規模的應用,若是不能配置先擴後縮,那麼在發佈階段可能會影響到應用的可用性。微服務

在收到社區的 issue #250 #260 反饋後,咱們在 CloneSet 中新增了 maxSurge 策略的支持並於 v0.5.0 版本中提供,在此也感謝社區 fatedier shiyan2016 等成員的參與貢獻和寶貴建議。至此,CloneSet 已經覆蓋了 K8s 原生 workload 的全部發布策略,下圖構建了 CloneSet 目前提供的發佈功能:性能

3.png

這裏暫時不對 CloneSet 的發佈策略作詳細說明,咱們後續會有專項文章來介紹。咱們只看一下新增的 maxSurge 是如何配合流式、分批發布來實現的呢?接下來咱們用幾個簡單的例子來看一下:

  1. 設置 maxSurge + maxUnavailable + partition 發佈
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
# ...
spec:
    replicas: 5          # Pod 總數爲 5
  updateStrategy:
    maxSurge: 20%      # 多擴出來 5 * 20% = 1 個 Pod (rounding up)
    maxUnavailable: 0  # 保證發佈過程 5 - 0 = 5 個 Pod 可用
    partition: 3       # 保留 3 箇舊版本 Pod (只發布 5 - 3 = 2 個 Pod)

當開始發佈時,CloneSet 會先根據 maxSurge 多擴出來一個 Pod,此時 Pod 總數爲 6(5 箇舊版,1 個新版):

$ kubectl get clone demo
NAME    DESIRED   UPDATED   UPDATED_READY   READY   TOTAL   AGE
demo    5         1         0               5       6       17m

隨後,CloneSet 會在保證 maxUnavailable 的前提下逐漸把 Pod 刪除、新建的方式更新,直到知足 partition=3 即剩餘 3 箇舊版本 Pod。此時,由於已經達到了指望的終態,CloneSet 會把新版本 Pod 刪除一個,此時 Pod 總數爲 5(3 箇舊版,2 個新版):

$ kubectl get clone demo
NAME    DESIRED   UPDATED   UPDATED_READY   READY   TOTAL   AGE
demo    5         2         2               5       5       17m

這裏能夠觀察一段時間,當須要繼續往下發布時,再次修改 partition 爲 0。而後,CloneSet 會再次根據 maxSurge 多擴出來一個 Pod,此時 Pod 總數爲 6(3 箇舊版,3 個新版):

$ kubectl get clone demo
NAME    DESIRED   UPDATED   UPDATED_READY   READY   TOTAL   AGE
demo    5         3         2               5       6       17m

隨後,CloneSet 會在保證 maxUnavailable 的前提下逐漸把 Pod 刪除、新建的方式更新,直到知足 partition=0 即全部 Pod 都升級到新版本。最後,CloneSet 會把新版本 Pod 刪除一個,此時 Pod 總數爲 5(5 個新版):

$ kubectl get clone demo
NAME    DESIRED   UPDATED   UPDATED_READY   READY   TOTAL   AGE
demo    5         5         5               5       5       17m
  1. maxSurge 配合原地升級

CloneSet 提供了 Pod 原地升級和重建升級兩種升級方式,均可以配合 maxSurge / maxUnavailable / partition 等策略來發布。

apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
# ...
spec:
  updateStrategy:
    type: InPlaceIfPossible
    maxSurge: 20%

若是在原地升級方式下配置了 maxSurge,CloneSet 會先擴出來 maxSurge 數量的 Pod,而後對舊版本 Pod 採用 in-place 的方式來升級(更新 Pod spec 中的 image 鏡像),最後在知足 partition 終態以後再清理刪掉 maxSurge 數量的 Pod。

經過這種方式,既保證了發佈過程的業務可用性,也儘可能使 Pod 發佈過程當中 IP、volume 等信息不變。

SidecarSet 支持 volume 注入合併

SidecarSet 是 Kruise 提供的另外一個重磅功能,不一樣於 CloneSet/StatefulSet 這些管理業務 Pod 的 workload,SidecarSet 是負責統一管理集羣中的 sidecar 容器版本和注入。

而 v0.5.0 版本中新增的功能,就是在 sidecar 容器注入的時候,解決了 SidecarSet 和 Pod 中 volume 重複定義的衝突問題。這也是來自於一個社區 issue #254 反饋,他們使用 SidecarSet 作日誌採集 sidecar 的管理,並指望以旁路的方式注入到全部 Pod 中。

舉個例子,咱們須要往集羣中每一個 Pod 都注入一個日誌採集 sidecar 容器。可是一來咱們沒法讓每一個應用開發者都在本身的 CloneSet/Deployment 中增長這個容器的定義,二來即便在全部應用的 workload 中都加了,若是咱們想要升級這個日誌採集容器的鏡像版本,還得更新全部應用的 workload,這樣作的成本實在過高了!

而 OpenKruise 提供的 SidcarSet 正是爲了解決上述這個問題。咱們只須要將 sidecar 定義寫到一個全局的 SidcarSet 中,無論用戶用 CloneSet、Deployment、StatefulSet 等任何方式部署,擴出來的 Pod 中都會注入咱們定義好的 sidecar 容器。

4.png

以日誌採集爲例,咱們能夠先定義一個 SidecarSet:

apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
  name: log-sidecar
spec:
  selector:
    matchLabels:
      app-type: long-term  # 往全部帶 long-term 標籤的 Pod 中注入
  containers:
  - name: log-collector
    image: xxx:latest
    volumeMounts:
    - name: log-volume
      mountPath: /var/log  #  將 log-volume 的卷掛到 /var/log 目錄,採集這個目錄下的日誌
  volumes:
  - name: log-volume   # 定義一個名爲 log-volume 的卷
    emptyDir: {}

這裏你們可能會問,若是每一個應用打出日誌的目錄路徑不一樣,怎麼辦?不要急,這就是本次 volume merge 的功能所在。

這個時候,好比有一個應用 A 擴容的原始 Pod 以下:

apiVersion: v1
kind: Pod
metadata:
  labels:
    app-type: long-term
spec:
  containers:
  - name: app
    image: xxx:latest
    volumeMounts:
    - name: log-volume
      mountPath: /app/logs  # 應用本身的日誌目錄
  volumes:
  - name: log-volume   # 定義一個名爲 log-volume 的卷
    persistentVolumeClaim:
        claimName: pvc-xxx

那麼 kruise webhook 就會將 SidecarSet 中定義的 log sidecar 容器注入到 Pod 中:

apiVersion: v1
kind: Pod
metadata:
  labels:
    app-type: long-term
spec:
  containers:
  - name: app
    image: xxx:latest
    volumeMounts:
    - name: log-volume
      mountPath: /app/logs  # 應用本身的日誌目錄
  - name: log-collector
    image: xxx:latest
    volumeMounts:
    - name: log-volume
      mountPath: /var/log
  volumes:
  - name: log-volume   # 定義一個名爲 log-volume 的卷
    persistentVolumeClaim:
        claimName: pvc-xxx

能夠看到,由於 SidecarSet 和 Pod 中定義的日誌 volume 名字都叫 log-volume,那麼在注入的時候就會以 Pod 中定義的 volume 爲準。好比這裏 Pod 中的 volume 採用了 pvc 的方式來掛載 pv,那麼注入 sidecar 後,一樣會把這個卷掛到 sidecar 容器中的 /var/log 目錄下,而後執行日誌採集便可。

這樣以 SidecarSet 的方式管理 sidecar 容器,既和應用部署發佈作了解耦,也一樣能夠和應用容器共享 volume 卷,來實現日誌採集、監控等相關 sidecar 功能。

總結

本次 v0.5.0 版本的升級,主要帶來了應用無損發佈和 sidecar 容器管理上更加便捷的能力。

後續 OpenKruise 還會持續在應用部署/發佈能力上作出更深的優化,咱們也歡迎更多的同窗參與到 OpenKruise 社區來,共同建設一個場景更加豐富、完善的 K8s 應用管理、交付擴展能力,可以面向更加規模化、複雜化、極致性能的場景。

課程推薦

爲了更多開發者可以享受到 Serverless 帶來的紅利,這一次,咱們集結了 10+ 位阿里巴巴 Serverless 領域技術專家,打造出最適合開發者入門的 Serverless 公開課,讓你即學即用,輕鬆擁抱雲計算的新範式——Serverless。

點擊便可免費觀看課程:https://developer.aliyun.com/learning/roadmap/serverless

阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,作最懂雲原生開發者的公衆號。」

相關文章
相關標籤/搜索