Kubernetes 設計模式筆記 —— 聲明式部署

聲明式部署(Declarative Deployment)模式主要體現在 Kubernetes 對其 Deployment 對象的應用上。

升級某個服務意味着,需要平滑地關閉舊版本的 Pod,啓動新版本的 Pod,然後等待和確認其部署成功,有時候在部署失敗時還需要執行回滾操作。
這些步驟或者需要一定的 downtime,同時不會有多個版本的服務在並行地運行(舊版本完全停止後再啓動新版本);或者不允許有 downtime,但在升級過程中,新舊版本的服務同時在線會造成資源消耗的增長(舊版本開始停止的時候就添加新版本的實例)。

手動執行上述操作難免會有錯誤發生,寫腳本來自動化處理又需要付出較大的時間成本。好在 Kubernetes 通過 Deployment 概念自動化了這些升級、回滾流程,可以在 Deployment 中定義替換的策略(如 RollingUpdateRecreate)以及其他升級過程中的細節。

Rolling Deployment

下面是一個採用滾動升級(rolling update)策略的 Deployment 示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: random-generator
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    selector:
      matchLabels:
        app: random-generator
    template:
      metadata:
        labels:
          app: random-generator
      spec:
        containers:
        - image: k8spatterns/random-generator:1.0
          name: random-generator
          readinessProbe:
            exec:
              command: [ "stat", "/random-generator-ready"]

其中 replicas: 3 表示副本的總數量是 3,在執行 rolling update 時,聲明的副本數量必須大於 1。
maxSurge: 1 表示在升級過程中,允許臨時添加的 Pod 的最大數量。滾動升級有一個切換的過程,必然導致某個時間段內新舊版本的應用同時運行,從而實際運行的 Pod 數量大於聲明的副本數量。此處的配置最多允許 4 個副本同時運行。
maxUnavailable: 1 表示升級過程中可能無法訪問的 Pods 數量。此處的配置有可能導致在升級的某個階段,只有兩個 Pods 可用。
readinessProbe 配置對於執行無 downtime 的滾動升級非常關鍵,它用來判斷某個 Pod 副本是否已經在線

RollingUpdate 策略會確保升級過程中沒有 downtime。Deployment 負責創建新的 ReplicaSet 並用新的容器替換掉舊容器,用戶則可以通過配置 maxSurgemaxUnavailable 字段來控制切換的速率。

Deployment 的優勢
  • Deployment 是完全被 Kubernetes 內部管理的資源對象,整個的升級過程由 Server 端執行,無需客戶端介入
  • Deployment 的聲明式性質,使得用戶更加關注期望達到的狀態而不是達到該狀態需要執行的操作步驟
  • 整個升級過程會以版本的方式進行記錄,還提供了 pause、continue 和 rollback 等選項

Fixed Deployment

RollingUpdate 策略在需要確保無 downtime 時非常有用,但該方式也有一些負面影響。比如在升級過程中,會有兩個版本的容器同時運行,這有可能導致接收服務的客戶端出現一些 issue,尤其當更新引入了沒有向後兼容的特性時。
在此類場景下,可以使用 Recreate 策略。

Recreate 策略的效果類似於 RollingUpdatemaxUnavailable 的值設置成了副本的數量。這意味着所有當前版本的容器都會先被終止掉,在舊容器被全部清理乾淨之後纔開始同步啓動所有的新容器。
結果就是升級過程中會存在一定的 downtime。

Blue-Green Release

Blue-Green deployment 發佈策略致力於在生產環境中最小化部署時的 downtime。藉助 Kubernetes 對於發佈行爲的抽象(Deployment),用戶可以自行定義和實現將不可變的容器從一個版本轉換到另一個版本的具體方式,比如 Blue-Green 部署方式。
如果 Kubernetes 集羣中並未安裝 Service Mesh 或者 Knative 等擴展組件,Blue-Green deployment 就需要手動實現。
其原理就是創建一個新的 Deployment,包含最新版本的容器(green),但是並不向外提供任何服務。舊的 Pod 副本(blue)依然在運行和處理請求。
一旦用戶確認新版本的 Pod 是健康的,可以提供服務,就將入站流量從舊的 Pod 副本切換到新版本的副本。在 Kubernetes 中可以通過修改 Service selector 來完成切換動作。當新版本的容器運行穩定後,舊版本即可被刪除。

Blue-Green 方案的優勢在於,同一時間只會有一個特定版本的應用對外提供服務,不需要接收服務的客戶端處理多個並行的服務版本;其劣勢則在於需要雙倍的資源去運行 blue 和 green 容器。此外,有些時候切換的過程會非常複雜。

Canary Release

Canary release 是一種軟部署方式,一開始只會將舊版本實例的一個較小的子集替換爲新版本。先只允許一小部分用戶能夠訪問更新後的服務,從而降低新版本向生產環境引入的風險。
當能夠確認新版本的服務對一小部分用戶沒有產生負面影響,再用新版全面替換掉舊版。

在 Kubernetes 中,上述部署方式可以通過創建一個包含新版本容器的 ReplicaSet 來實現,只不過副本的數量可以設置得很小,作爲 Canary 實例。同時 Service 對象負責將一部分用戶的請求轉發給 Canary 容器。當我們確信新版本應用可以正常提供服務,則橫向擴展新的 ReplicaSet 到期望的副本數量,同時收縮舊 ReplicaSet 的副本數量至 0。

總結

Deployment 很好地向我們展示了,Kubernetes 將複雜的手動升級應用的流程,轉化爲可以重複執行、支持自動化編排的聲明式部署。

上述四種部署方式的總結:

參考資料

Kubernetes Patterns

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