Kubernetes應用編排與管理 —— Deployment升級策略

2023-06-27 21:00:56

1、Deployment概述

  Deployment 是 Kubernetes 控制器的一種高階別實現,它構建於 ReplicaSet 控制器之上,它可用於為 Pod 和 ReplicaSet 資源提供宣告式更新,並能夠以自動方式實現跨多個 ReplicaSet 物件的捲動更新功能。相比較來說,Pod 和 ReplicaSet 是較低階別的資源,以至於很少被直接使用。

  Deployment 控制器資源的主要職責同樣是為了保證 Pod 資源健康執行,其大部分功能通過呼叫 ReplicaSet 控制器實現,並增添了部分特性。

  • 版本記錄:將 Deployment 物件的更新操作予以儲存,以便後續可能執行的回滾操作使用。
  • 回滾:更新操作啟動後的任一時刻(包括完成後)發現問題,都可以通過回滾機制將應用返回到前一個或由使用者指定的歷史記錄中的版本。
  • 暫停和啟動:更新過程中能夠隨時暫停和繼續完成後面的步驟。
  • 事件和狀態檢視:必要時可以檢視 Deployment 物件的更新進度和狀態。
  • 多種升級策略:一是 Recreate,即重建更新機制,單批次更新所有 Pod 物件;另一個是 RollingUpdate,即捲動更新機制,多批次逐步替換舊有的 Pod 至新的版本。

  通過以上內容可以知道Deployment提供了很多核心功能,在本文主要關注Deployment多種升級策略功能。通過深入研究Deployment升級策略,我們將獲得更好的理解和掌握如何在Kubernetes環境中進行應用程式的升級。我們將學習如何選擇合適的升級策略,並瞭解如何正確設定和管理升級過程中的各種引數。最終,我們將能夠實現無縫、可控的應用程式升級,提高應用的穩定性和可用性。

      在接下來的篇章中,讓我們一起深入探索Deployment升級策略的精髓,並學習如何在實際應用中應用這些策略,為應用程式的持續演進提供支援。

注意 1:Deployment只負責管理不同版本的ReplicaSet, 由ReplicaSet管理Pod副本數。每個ReplicaSet對應了Deployment template的一個版本,一個ReplicaSet下的Pod都是相同的版本。

 2、Deployment升級策略 

  Deployment控制器支援兩種更新策略: 捲動更新(RollingUpdate)和刪除式更新(Recreate)也稱為單批次更新,預設使用捲動更新策略。 

  • 捲動更新(Rolling Update),捲動更新是預設的更新策略,一次僅更新一批Pod,當更新的Pod就緒後再更新另一批,直到全部更新完成為止;該策略實現了不間斷服務的目標,但是在更新過程中,不同使用者端得到的響應內容可能會來自不同版本的應用,會出現新老版本共存狀態。
  • 刪除式更新(Recreate),當更新策略設定為Recreate,在更新映象時,它會先刪除現在正在執行的Pod,等徹底殺死後,重新建立新的RS(ReplicaSet),然後啟動對應的Pod,在整個更新過程中,會造成服務一段時間無法提供服務。也稱之為單批次更新。

  Deployment 控制器的捲動更新操作並非在同一個 ReplicaSet 控制器物件下刪除並建立 Pod 資源,而是將它們分置於兩個不同的控制器之下,當前 ReplicaSet 物件的 Pod 副本數量不斷減少的同時,新 ReplicaSet 物件的 Pod 物件數量不斷增加,直到現有 ReplicaSet 物件的 Pod 副本數為 0,而新控制器的副本數量變得完全符合期望值,新舊版本之間區別彼此 Pod 物件的關鍵標籤為 pod-template-hash。

2.1  捲動更新(Rolling Update)策略實戰

2.1.1 捲動更新(Rolling Update)策略升級步驟

  捲動更新(RollingUpdate)一次僅更新一批Pod,當更新的Pod就緒(可用)後,再更新另一批,直到全部更新完成為止,該策略實現了不間斷服務的目標,在更新過程中可能會出現不同的應用版本且並存,同時提供服務的情況,Rolling Update升級策略分為三個步驟:

  • 建立新的RS,然後根據新的映象執行新的Pod。
  • 刪除舊的Pod,啟動新的Pod,當新Pod就緒後,繼續刪除舊Pod,啟動新Pod。
  • 持續第二步過程,直到所有Pod都被更新成功。

注意 1:注意捲動升級步驟第2步,存在先增新後減舊、先減舊後增新、同時增減(少減多增)多種情況,具體與捲動升級策略屬性spec.strategy.rollingUpdate.maxSurge和spec.strategy.rollingUpdate.maxUnavailable設定相關,此部分會在下文進行詳細解釋。

注意 2:在Deployment的捲動升級期間,可以通過以下方式判斷Pod是否處於可用狀態:Pod設定就緒探針(Readiness Probe)的情況下:如果就緒探針的探測結果為成功,則表示容器已經準備好接收流量,該Pod被認為是就緒狀態。Pod沒有就緒探針的情況下:判斷Pod是否就緒的依據主要是基於Pod的執行狀態,一般Pod的狀態為Running則認為Pod是就緒狀態。

注意 3:修改 Deployment 控制器的 minReadySeconds、replicas 和 strategy 等欄位的值並不會觸發 Pod 資源的更新操作,因為它們不屬於 template 的內嵌欄位,對現存的 Pod 物件不產生任何影響。

2.1.2 捲動更新(Rolling Update)策略實戰

(1)應用設定範例

#  type欄位須設定為RollingUpdate
#  spec:
#     strategy:
#        type: RollingUpdate
# 應用組態檔,現版本Nginx是1.16版本,要捲動到1.21.5;
root@kubernetes-master01:~# cat nginx-deployment-test.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx-test
  namespace: deployment-test
spec:
  strategy:
    type: RollingUpdate
  replicas: 2
  selector:
    matchLabels:
      app: nginx-deployment
  template:
    metadata:
      labels:
        app: nginx-deployment
    spec:
      containers:
      - name: nginx
        image: nginx:1.16
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80

在叢集建立Deployment工作負載物件deployment-nginx-test。

[root@node1 deploy]# kubectl create ns deployment-test
namespace/deployment-test created
[root@node1 deploy]# kubectl apply -f nginx-deployment-test.yaml 
deployment.apps/deployment-nginx-test created

檢視Deployment工作負載物件deployment-nginx-test狀態,可以看到其捲動升級策略型別為RollingUpdate,這裡提前注意下捲動升級策略預設屬性值25% max unavailable, 25% max surge,此部分會在下文進行詳細解釋。

[root@node1 deploy]# kubectl describe deployments.apps -n=deployment-test deployment-nginx-test 
Name:                   deployment-nginx-test
Namespace:              deployment-test
CreationTimestamp:      Tue, 27 Jun 2023 09:29:42 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=nginx-deployment
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=nginx-deployment
  Containers:
   nginx:
    Image:        nginx:1.16
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   deployment-nginx-test-65b5c9746c (2/2 replicas created)
Events:          <none>

檢視Deployment工作負載物件deployment-nginx-test關聯Pod狀態。

[root@node1 deploy]# kubectl get pods -n=deployment-test 
NAME                                     READY   STATUS    RESTARTS   AGE
deployment-nginx-test-65b5c9746c-nc875   1/1     Running   0          6m43s
deployment-nginx-test-65b5c9746c-rbzsx   1/1     Running   0          6m43s  

(2)測試卷動更新升級策略

修改Deployment工作負載物件deployment-nginx-test映象版本,測試卷動更新升級策略。

[root@node1 deploy]# kubectl set image -n=deployment-test deployment/deployment-nginx-test nginx=nginx:latest
deployment.apps/deployment-nginx-test image updated

 在測試卷動更新升級策略的同時,開一個新的shell視窗,監視Deployment工作負載物件deployment-nginx-test關聯Pod的實時狀態變化。

[root@node1 ~]# kubectl get pods -n=deployment-test --watch
NAME                                     READY   STATUS    RESTARTS   AGE
deployment-nginx-test-65b5c9746c-2f599   1/1     Running   0          23s
deployment-nginx-test-65b5c9746c-m9lrs   1/1     Running   0          23s
deployment-nginx-test-74859ff6d8-lhphh   0/1     Pending   0          0s
deployment-nginx-test-74859ff6d8-lhphh   0/1     Pending   0          0s
deployment-nginx-test-74859ff6d8-lhphh   0/1     ContainerCreating   0          0s
deployment-nginx-test-74859ff6d8-lhphh   1/1     Running             0          2s
deployment-nginx-test-65b5c9746c-2f599   1/1     Terminating         0          78s
deployment-nginx-test-74859ff6d8-kjcgf   0/1     Pending             0          0s
deployment-nginx-test-74859ff6d8-kjcgf   0/1     Pending             0          0s
deployment-nginx-test-74859ff6d8-kjcgf   0/1     ContainerCreating   0          0s
deployment-nginx-test-65b5c9746c-2f599   0/1     Terminating         0          79s
deployment-nginx-test-74859ff6d8-kjcgf   1/1     Running             0          2s
deployment-nginx-test-65b5c9746c-m9lrs   1/1     Terminating         0          80s
deployment-nginx-test-65b5c9746c-m9lrs   0/1     Terminating         0          81s
deployment-nginx-test-65b5c9746c-m9lrs   0/1     Terminating         0          88s
deployment-nginx-test-65b5c9746c-m9lrs   0/1     Terminating         0          88s
deployment-nginx-test-65b5c9746c-2f599   0/1     Terminating         0          88s
deployment-nginx-test-65b5c9746c-2f599   0/1     Terminating         0          88s

  通過監視Deployment工作負載物件deployment-nginx-test關聯Pod的實時狀態變化可知,當工作負載更新策略設定為Rolling Update,在更新映象時,它會啟動新的Pod,刪除舊的Pod,當新的Pod就緒後,繼續啟動新的Pod,刪除舊的Pod,周而復始,直到所有Pod都被更新成功。

注意 1:注意捲動升級步驟第2步,存在先增新後減舊、先減舊後增新、同時增減(少減多增)多種情況,具體與捲動升級策略屬性spec.strategy.rollingUpdate.maxSurge和spec.strategy.rollingUpdate.maxUnavailable設定相關,此部分會在下文進行詳細解釋。

2.1.3 控制捲動更新(Rolling Update)速率

  捲動升級策略屬性

  • spec.strategy.rollingUpdate.maxSurge決定了 Deployment 設定中期望的副本數之外,最多允許超出的 Pod 範例的數量,其值可以是 0 或正整數,也可以是相對於期望值的一個百分比。預設值為 25% 當把百分數轉換成絕對值時,會將數位四捨五入。比如,如果期望副本數被設定為 4,maxSurge 屬性值為 25%,則表示 Pod 物件總數至多不能超過 5個;如果期望值為 10,maxSurge 屬性值為 2,則表示 Pod 物件總數至多不能超過 12 個。
  • spec.strategy.rollingUpdate.maxUnavailable決定了在捲動升級期間 ,相對於期望副本數能夠允許有多少 Pod 範例處於不可用狀態。預設值也是 25% ,所以可用 Pod 範例的數量(包括新舊版本)不能低於期望副本數的 75% 。百分數轉換成絕對值時這個數位也會四捨五入。比如,如果期望副本數設定為4 ,並且maxUnavailable屬性值為 25%,那麼只能有一個 Pod 處於不可用狀態,在整個釋出過程中 ,總是保持至少有三個 Pod 範例處於可用狀態來提供服務。與 maxSurge 一樣,也可以指定絕對值而不是百分比。比如,如果期望值是 10,maxUnavailable屬性值為1,則升級期間至少要有 9 個 Pod 物件處於正常提供服務的狀態。

  可組合定義出 3 種不同的策略完成多批次的應用更新:

  • 先增新,後減舊:將 maxSurge 設定為小於等於期望值的正整數或相對於期望值的一個百分比,而 maxUnavailable 的值為 0。
  • 先減舊,後增新:將 maxUnavailable 設定為小於等於期望值的正整數或相對於期望值的一個百分比,而 maxSurge 的值為 0。
  • 同時增減(少減多增):將 maxSurge 和 maxUnavailabe 欄位的值同時設定為小於等於期望值的正整數或相對於期望值的一個百分比,二者可以使用不同值。

注意 1:maxSurge 和 maxUnavailable 屬性的值不可同時為 0,否則 Pod 物件的副本數量在符合使用者期望的數量後無法做出合理變動以進行卷動更新操作。

注意 2:有個特例,如果期望副本數被設定為 1,使用 Deployment 預設捲動升級策略,捲動升級策略屬性值也都是預設值(maxSurge: 25%、maxUnavailable: 25%),由於期望範例數 1*maxSurge 四捨五入=0,期望範例數 1*maxUnavailable 四捨五入=0,那麼在捲動升級期間,Pod 物件總數至多為1,至少有1個 Pod 處於正常提供服務的狀態,按照公式計算,則此工作負載無法做出合理變動以進行卷動更新操作。實際情況是先增新,後減舊。

範例,建立Deploymnet工作負載物件,其範例數為1,使用預設捲動升級策略,捲動升級策略屬性值也都是預設值(maxSurge: 25%、maxUnavailable: 25%),組態檔和2.1.2除了工作負載範例數外一致。

[root@node1 deploy]# kubectl apply -f nginx-deployment-test.yaml 
deployment.apps/deployment-nginx-test created
[root@node1 deploy]# kubectl get pods -n=deployment-test 
NAME                                     READY   STATUS              RESTARTS   AGE
deployment-nginx-test-65b5c9746c-cwbhr   0/1     ContainerCreating   0          5s
[root@node1 deploy]# kubectl get pods -n=deployment-test 
NAME                                     READY   STATUS    RESTARTS   AGE
deployment-nginx-test-65b5c9746c-cwbhr   1/1     Running   0          8s

修改Deployment工作負載物件deployment-nginx-test映象版本,測試卷動更新升級策略。

[root@node1 deploy]# kubectl set image -n=deployment-test deployment/deployment-nginx-test nginx=nginx:latest
deployment.apps/deployment-nginx-test image updated

 在測試卷動更新升級策略的同時,開一個新的shell視窗,監視Deployment工作負載物件deployment-nginx-test關聯Pod的實時狀態變化。

[root@node1 ~]# kubectl get pods -n=deployment-test --watch
NAME                                     READY   STATUS    RESTARTS   AGE
deployment-nginx-test-65b5c9746c-cwbhr   1/1     Running   0          4m12s
deployment-nginx-test-74859ff6d8-kj2dw   0/1     Pending   0          0s
deployment-nginx-test-74859ff6d8-kj2dw   0/1     Pending   0          0s
deployment-nginx-test-74859ff6d8-kj2dw   0/1     ContainerCreating   0          0s
deployment-nginx-test-74859ff6d8-kj2dw   1/1     Running             0          2s
deployment-nginx-test-65b5c9746c-cwbhr   1/1     Terminating         0          4m26s
deployment-nginx-test-65b5c9746c-cwbhr   0/1     Terminating         0          4m27s

  通過監視Deployment工作負載物件deployment-nginx-test關聯Pod的實時狀態變化可知,如果期望副本數被設定為 1,使用 Deployment 預設捲動升級策略,捲動升級策略屬性值也都是預設值(maxSurge: 25%、maxUnavailable: 25%),在更新映象時,它會啟動新的Pod,然後再刪除舊的Pod。

2.1.4 減慢捲動更新(Rolling Update)速率

Deployment 還支援使用 spec.minReadySeconds 欄位來減慢捲動更新的速度,其預設值為 0,表示新建的 Pod 物件一旦「就緒」將立即被視作可用,隨後即可開始下一輪更新過程。而為該欄位指定一個正整數值能夠定義新建的 Pod 物件至少要成功執行多久才會被視作可用,即就緒之後還要等待 minReadySeconds 指定的時長才能開始下一批次的更新。在此期間,更新操作會被阻塞,因此,它可用用來讓kubernetes在每次建立出 Pod 資源後都要等上一部分時間再開始下一輪的替換;因此為minReadySeconds設定一個合理的值,不僅僅能夠減慢更新速度,還能夠讓Deployment發現一部分程式因為BUG而導致的升級故障。

minReadySeconds屬性配合就緒探針的設定,可以確保容器真正就緒後才會接收流量,避免將流量傳送到尚未完全啟動或初始化的容器上。這樣可以提高應用程式的可用性和穩定性。

2.1.5 RevisionHistoryLimit

Deployment控制器保留了一部分更新歷史中舊版本的ReplicaSet物件,當我們執行回滾操作時,就直接使用舊版本的ReplicaSet,在Deployment資源儲存歷史版本數量有spec.revisionHistoryLimit屬性進行定義,預設值為10。

2.1.6 progressDeadlineSeconds

捲動更新故障超時時長,預設為600秒,k8s在升級過程中有可能由於各種原因升級卡住(這個時候還沒有明確的升級失敗)比如在拉取被牆的映象,許可權不夠等錯誤,如果設定progressDeadlineSeconds當達到了時間如果還卡著,則會上報這個異常情況,這個時候Deployment的狀態就會被標記為false,並且註明原因,但是它不會阻止Deployment繼續進行卡住後面的升級操作。 

2.1.7 捲動更新(Rolling Update)應用場景

  Deployment的Rolling Update升級策略適用於以下場景:

  1. 無縫升級:捲動更新策略可以確保應用在升級過程中保持可用性。它逐步替換舊版本的Pod,新版本的Pod會逐漸接收流量,從而實現無縫的應用升級,減少對使用者的影響。
  2. 資源平滑過渡:捲動更新策略允許在升級期間逐漸引入新版本的Pod,同時逐漸停止舊版本的Pod。這樣可以避免在短時間內突然增加或減少應用範例的數量,有助於平滑地過渡和分配資源。
  3. 故障恢復:當舊版本的Pod出現故障或不可用時,捲動更新策略可以自動替換這些故障的Pod,保證應用的可用性和穩定性。
  4. 流量控制和負載均衡:捲動更新策略可以通過逐步替換Pod的方式來控制應用接收的流量。這對於在應用程式層面進行負載均衡或測試新版本效能非常有用。
  5. 灰度釋出和A/B測試:捲動更新策略可以實現灰度釋出和A/B測試的需求。通過逐漸引入新版本的Pod,可以將一部分流量導向新版本,以便在生產環境中進行測試和評估新功能或變化。

  捲動更新策略在實現應用的平滑升級、故障恢復、資源過渡和流量控制方面具有優勢,適用於大多數應用部署場景。它能夠減少對使用者的影響,提供可靠的應用更新和管理機制。

2.2 刪除式更新(Recreate)策略實戰

2.2.1 刪除式更新(Recreate)策略升級步驟

  Recreate策略在更新映象時,它會先刪除現在正在執行的Pod,等徹底殺死後,重新建立新的RS(ReplicaSet),然後啟動對應的Pod,在整個更新過程中,會造成服務一段時間無法提供服務。也稱之為單批次更新。Recreate升級策略分為三個步驟: 

  1. 殺死所有舊版本的Pod,此時Pod無法正常對外提供服務;
  2. 建立新的RS,啟動新的Pod;
  3. 等待Pod就緒,對外提供服務;

2.2.2 刪除式更新(Recreate)策略實戰

(1)應用設定範例

# 必須在Spec欄位中明確定義strategy捲動更新策略和type型別
[root@node1 deploy]# cat nginx-deployment-test.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx-test
  namespace: deployment-test
spec:
  strategy:         # 捲動更新策略
    type: Recreate  # Recreate表示的是刪除式更新,也稱為單批次更新;
  replicas: 2
  selector:
    matchLabels:
      app: nginx-deployment
  template:
    metadata:
      labels:
        app: nginx-deployment
    spec:
      containers:
      - name: nginx
        image: nginx:1.16
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80

在叢集建立Deployment工作負載物件deployment-nginx-test。

[root@node1 deploy]# kubectl create ns deployment-test
namespace/deployment-test created
[root@node1 deploy]# kubectl apply -f nginx-deployment-test.yaml 
deployment.apps/deployment-nginx-test created

檢視Deployment工作負載物件deployment-nginx-test狀態,可以看到其捲動升級策略型別為Recreate。

[root@node1 deploy]# kubectl describe deployments.apps -n=deployment-test deployment-nginx-test 
Name:               deployment-nginx-test
Namespace:          deployment-test
CreationTimestamp:  Tue, 27 Jun 2023 07:53:37 +0800
Labels:             <none>
Annotations:        deployment.kubernetes.io/revision: 1
Selector:           app=nginx-deployment
Replicas:           2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:       Recreate
MinReadySeconds:    0
Pod Template:
  Labels:  app=nginx-deployment
  Containers:
   nginx:
    Image:        nginx:1.16
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   deployment-nginx-test-65b5c9746c (2/2 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  2m21s  deployment-controller  Scaled up replica set deployment-nginx-test-65b5c9746c to 2

檢視Deployment工作負載物件deployment-nginx-test關聯Pod狀態。

[root@node1 deploy]# kubectl get pods -n=deployment-test 
NAME                                     READY   STATUS    RESTARTS   AGE
deployment-nginx-test-65b5c9746c-nc875   1/1     Running   0          6m43s
deployment-nginx-test-65b5c9746c-rbzsx   1/1     Running   0          6m43s  

(2)測試刪除式更新升級策略

修改Deployment工作負載物件deployment-nginx-test映象版本,測試刪除式更新升級策略。

[root@node1 deploy]# kubectl set image -n=deployment-test deployment/deployment-nginx-test nginx=nginx:latest
deployment.apps/deployment-nginx-test image updated

 在測試刪除式更新升級策略的同時,開一個新的shell視窗,監視Deployment工作負載物件deployment-nginx-test關聯Pod的實時狀態變化。

[root@node1 ~]# kubectl get pods -n=deployment-test --watch
NAME                                     READY   STATUS    RESTARTS   AGE
deployment-nginx-test-65b5c9746c-927r9   1/1     Running   0          73s
deployment-nginx-test-65b5c9746c-vxztk   1/1     Running   0          73s
deployment-nginx-test-65b5c9746c-vxztk   1/1     Terminating   0          80s
deployment-nginx-test-65b5c9746c-927r9   1/1     Terminating   0          80s
deployment-nginx-test-65b5c9746c-927r9   0/1     Terminating   0          83s
deployment-nginx-test-65b5c9746c-vxztk   0/1     Terminating   0          84s
deployment-nginx-test-65b5c9746c-vxztk   0/1     Terminating   0          92s
deployment-nginx-test-65b5c9746c-vxztk   0/1     Terminating   0          92s
deployment-nginx-test-65b5c9746c-927r9   0/1     Terminating   0          92s
deployment-nginx-test-65b5c9746c-927r9   0/1     Terminating   0          92s
deployment-nginx-test-74859ff6d8-zcmz4   0/1     Pending       0          0s
deployment-nginx-test-74859ff6d8-zcmz4   0/1     Pending       0          0s
deployment-nginx-test-74859ff6d8-h4889   0/1     Pending       0          0s
deployment-nginx-test-74859ff6d8-h4889   0/1     Pending       0          0s
deployment-nginx-test-74859ff6d8-h4889   0/1     ContainerCreating   0          0s
deployment-nginx-test-74859ff6d8-zcmz4   0/1     ContainerCreating   0          0s
deployment-nginx-test-74859ff6d8-zcmz4   1/1     Running             0          8s

  通過監視Deployment工作負載物件deployment-nginx-test關聯Pod的實時狀態變化可知,當工作負載更新策略設定為Recreate,在更新映象時,它會先刪除現在正在執行的Pod,等徹底殺死後,重新建立新的RS(ReplicaSet),然後啟動對應的Pod,在整個更新過程中,會造成服務一段時間無法提供服務。也稱之為單批次更新。

2.2.3 Recreate策略應用場景:

  Deployment的Recreate升級策略適用於以下場景:

  1. 快速回滾:當需要迅速回滾到先前的應用版本時,Recreate策略可以很方便地實現。通過將新版本的Pod全部替換為舊版本的Pod,可以快速恢復到先前穩定的應用狀態。

  2. 環境重建:當需要重新建立整個應用環境時,Recreate策略是一個合適的選擇。例如,在測試環境或開發環境中,需要定期清理和重新建立應用範例,以確保環境的一致性和穩定性。

  3. 應用初始化:在部署新的應用時,Recreate策略可以用來確保所有的Pod都從頭開始初始化。這對於一些需要重置狀態或執行初始設定的應用非常有用。

  4. 其他: 對於傳統企業大部分業務系統,升級前通常會發升級公告,一般是週五晚上12點左右進行新版本的升級,這個時候使用Recreate策略可以迅速的升級新版本;另外對於一些測試環境,或者說資源比較缺乏的一些環境,使用Recreate策略升級應用可以臨時節約叢集資源,使用預設Rolling Update升級策略時,如果不對Deployment升級策略做特殊設定,使用其預設捲動升級策略的話,在升級過程中會最多存在「期望範例數+maxSurge」個Pod範例數,尤其對於先增新,後減舊的情況,如果叢集資源很缺乏並且Pod資源需求很大,由於舊Pod還佔用著資源,叢集可能就會沒法排程新Pod,就會導致捲動升級失敗,現象是使用者端存取的還是舊的程式。

注意 1:使用Recreate策略進行卷動升級時,會在更新期間出現應用不可用的瞬間。因為在替換舊版本Pod之前,新版本Pod需要先全部啟動完成。因此,在選擇使用Recreate策略時,需要確保應用對短暫的停機時間或不可用性可以容忍。

 3、總結

Deployment升級策略是在Kubernetes中用於管理應用程式更新的重要機制。它允許在保證服務的可用性的同時,逐步將舊版本的Pod替換為新版本的Pod。Deployment提供了兩種主要的升級策略:Recreate(重建)和RollingUpdate(捲動更新)。

  1. 重建(Recreate)策略:

    • 適用情況:適用於無狀態應用或不需要保持持久連線的有狀態應用;測試環境或者說資源比較缺乏的一些環境,使用Recreate策略升級應用可以臨時節約叢集資源。
    • 工作原理:在升級過程中,會先刪除所有舊的Pod,然後建立新的Pod來替換它們。
    • 優點:升級速度快,對資源的需求較少。
    • 缺點:在升級過程中可能會出現服務中斷,因為所有的Pod都會同時停止。
  2. 捲動更新(RollingUpdate)策略:

    • 適用情況:適用於需要保持持久連線、有狀態應用或對服務中斷敏感的應用。
    • 工作原理:通過逐步替換舊版本的Pod來進行升級,保證服務的連續性。
    • 優點:避免了服務中斷,可以逐步將新版本的Pod引入流量,保證應用的可用性。
    • 缺點:升級過程相對較慢,可能會佔用更多的資源。
    • 建議:為了確保服務不中斷,建議結合使用Pod就緒探針和MinReadySeconds。就緒探針檢測Pod內容器是否就緒,MinReadySeconds設定等待時間,確保Pod穩定後再進行下一步升級,提高服務可用性。

 參考:30 K8S 之 Deployment 控制器