部署

Deployment 管理一組 Pod 以執行應用程式工作負載,通常是不維護狀態的工作負載。

DeploymentPodReplicaSet 提供宣告式更新。

您在部署 (Deployment) 中描述期望狀態,而部署控制器會以受控速率將實際狀態變更為期望狀態。您可以定義部署以建立新的副本集 (ReplicaSet),或移除現有的部署並採用其所有資源到新的部署。

使用案例

以下是部署的典型使用案例

建立部署

以下是部署的範例。它建立一個副本集以啟動三個 nginx Pod

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

在此範例中

  • 建立名為 nginx-deployment 的部署,由 .metadata.name 欄位指示。此名稱將成為稍後建立的副本集和 Pod 的基礎。請參閱撰寫部署規格以取得更多詳細資訊。

  • 部署建立一個副本集,該副本集建立三個複寫的 Pod,由 .spec.replicas 欄位指示。

  • .spec.selector 欄位定義建立的副本集如何找到要管理的 Pod。在此案例中,您選取在 Pod 範本中定義的標籤 (app: nginx)。但是,更複雜的選取規則也是可能的,只要 Pod 範本本身符合規則即可。

  • template 欄位包含以下子欄位

    • Pod 使用 .metadata.labels 欄位標記為 app: nginx
    • Pod 範本的規格,或 .template.spec 欄位,指示 Pod 執行一個容器,nginx,它執行版本為 1.14.2 的 nginx Docker Hub 映像檔。
    • 建立一個容器並使用 .spec.template.spec.containers[0].name 欄位將其命名為 nginx

在開始之前,請確保您的 Kubernetes 叢集已啟動並執行。依照以下步驟建立上述部署

  1. 執行以下指令來建立部署

    kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
    
  2. 執行 kubectl get deployments 以檢查部署是否已建立。

    如果部署仍在建立中,則輸出類似於以下內容

    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   0/3     0            0           1s
    

    當您檢查叢集中的部署時,會顯示以下欄位

    • NAME 列出命名空間中部署的名稱。
    • READY 顯示可供使用者使用的應用程式副本數。它遵循就緒/期望模式。
    • UP-TO-DATE 顯示已更新以達到期望狀態的副本數。
    • AVAILABLE 顯示可供使用者使用的應用程式副本數。
    • AGE 顯示應用程式已執行的時間。

    請注意,期望的副本數為 3,根據 .spec.replicas 欄位。

  3. 若要查看部署的推出狀態,請執行 kubectl rollout status deployment/nginx-deployment

    輸出類似於

    Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
    deployment "nginx-deployment" successfully rolled out
    
  4. 幾秒鐘後再次執行 kubectl get deployments。輸出類似於此

    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   3/3     3            3           18s
    

    請注意,部署已建立所有三個副本,並且所有副本都是最新的 (它們包含最新的 Pod 範本) 且可用。

  5. 若要查看部署建立的副本集 (rs),請執行 kubectl get rs。輸出類似於此

    NAME                          DESIRED   CURRENT   READY   AGE
    nginx-deployment-75675f5897   3         3         3       18s
    

    副本集輸出顯示以下欄位

    • NAME 列出命名空間中副本集的名稱。
    • DESIRED 顯示應用程式的副本的期望數量,您在建立部署時定義。這是期望狀態
    • CURRENT 顯示目前正在執行的副本數。
    • READY 顯示可供使用者使用的應用程式副本數。
    • AGE 顯示應用程式已執行的時間。

    請注意,副本集的名稱始終格式化為 [DEPLOYMENT-NAME]-[HASH]。此名稱將成為建立的 Pod 的基礎。

    HASH 字串與副本集上的 pod-template-hash 標籤相同。

  6. 若要查看為每個 Pod 自動產生的標籤,請執行 kubectl get pods --show-labels。輸出類似於

    NAME                                READY     STATUS    RESTARTS   AGE       LABELS
    nginx-deployment-75675f5897-7ci7o   1/1       Running   0          18s       app=nginx,pod-template-hash=75675f5897
    nginx-deployment-75675f5897-kzszj   1/1       Running   0          18s       app=nginx,pod-template-hash=75675f5897
    nginx-deployment-75675f5897-qqcnn   1/1       Running   0          18s       app=nginx,pod-template-hash=75675f5897
    

    建立的副本集確保有三個 nginx Pod。

Pod-template-hash 標籤

pod-template-hash 標籤由部署控制器新增至部署建立或採用的每個副本集。

此標籤確保部署的子副本集不會重疊。它透過雜湊副本集的 PodTemplate 並使用產生的雜湊作為標籤值來產生,該標籤值會新增至副本集選取器、Pod 範本標籤,以及副本集可能擁有的任何現有 Pod 中。

更新部署

依照以下步驟更新您的部署

  1. 讓我們更新 nginx Pod 以使用 nginx:1.16.1 映像檔,而不是 nginx:1.14.2 映像檔。

    kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1
    

    或使用以下指令

    kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
    

    其中 deployment/nginx-deployment 指示部署,nginx 指示將發生更新的容器,而 nginx:1.16.1 指示新的映像檔及其標籤。

    輸出類似於

    deployment.apps/nginx-deployment image updated
    

    或者,您可以 edit 部署並將 .spec.template.spec.containers[0].imagenginx:1.14.2 變更為 nginx:1.16.1

    kubectl edit deployment/nginx-deployment
    

    輸出類似於

    deployment.apps/nginx-deployment edited
    
  2. 若要查看推出狀態,請執行

    kubectl rollout status deployment/nginx-deployment
    

    輸出類似於此

    Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
    

    deployment "nginx-deployment" successfully rolled out
    

取得有關已更新部署的更多詳細資訊

  • 在推出成功後,您可以執行 kubectl get deployments 來檢視部署。輸出類似於此

    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   3/3     3            3           36s
    
  • 執行 kubectl get rs 以查看部署如何透過建立新的副本集並將其擴展到 3 個副本,以及將舊的副本集縮減到 0 個副本來更新 Pod。

    kubectl get rs
    

    輸出類似於此

    NAME                          DESIRED   CURRENT   READY   AGE
    nginx-deployment-1564180365   3         3         3       6s
    nginx-deployment-2035384211   0         0         0       36s
    
  • 執行 get pods 現在應該只顯示新的 Pod

    kubectl get pods
    

    輸出類似於此

    NAME                                READY     STATUS    RESTARTS   AGE
    nginx-deployment-1564180365-khku8   1/1       Running   0          14s
    nginx-deployment-1564180365-nacti   1/1       Running   0          14s
    nginx-deployment-1564180365-z9gth   1/1       Running   0          14s
    

    下次您想要更新這些 Pod 時,您只需要再次更新部署的 Pod 範本即可。

    部署確保在更新 Pod 時,只有一定數量的 Pod 處於關閉狀態。預設情況下,它確保至少 75% 的期望 Pod 數量處於啟動狀態 (最多 25% 不可用)。

    部署也確保僅在期望 Pod 數量之上建立一定數量的 Pod。預設情況下,它確保最多 125% 的期望 Pod 數量處於啟動狀態 (最多 25% 突增)。

    例如,如果您仔細查看上述部署,您會看到它首先建立一個新的 Pod,然後刪除一個舊的 Pod,然後再建立另一個新的 Pod。在足夠數量的新 Pod 啟動之前,它不會終止舊的 Pod,並且在足夠數量的舊 Pod 已終止之前,它不會建立新的 Pod。它確保至少有 3 個 Pod 可用,並且總共最多有 4 個 Pod 可用。在具有 4 個副本的部署案例中,Pod 數量將介於 3 到 5 之間。

  • 取得部署的詳細資訊

    kubectl describe deployments
    

    輸出類似於此

    Name:                   nginx-deployment
    Namespace:              default
    CreationTimestamp:      Thu, 30 Nov 2017 10:56:25 +0000
    Labels:                 app=nginx
    Annotations:            deployment.kubernetes.io/revision=2
    Selector:               app=nginx
    Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
    StrategyType:           RollingUpdate
    MinReadySeconds:        0
    RollingUpdateStrategy:  25% max unavailable, 25% max surge
    Pod Template:
      Labels:  app=nginx
       Containers:
        nginx:
          Image:        nginx:1.16.1
          Port:         80/TCP
          Environment:  <none>
          Mounts:       <none>
        Volumes:        <none>
      Conditions:
        Type           Status  Reason
        ----           ------  ------
        Available      True    MinimumReplicasAvailable
        Progressing    True    NewReplicaSetAvailable
      OldReplicaSets:  <none>
      NewReplicaSet:   nginx-deployment-1564180365 (3/3 replicas created)
      Events:
        Type    Reason             Age   From                   Message
        ----    ------             ----  ----                   -------
        Normal  ScalingReplicaSet  2m    deployment-controller  Scaled up replica set nginx-deployment-2035384211 to 3
        Normal  ScalingReplicaSet  24s   deployment-controller  Scaled up replica set nginx-deployment-1564180365 to 1
        Normal  ScalingReplicaSet  22s   deployment-controller  Scaled down replica set nginx-deployment-2035384211 to 2
        Normal  ScalingReplicaSet  22s   deployment-controller  Scaled up replica set nginx-deployment-1564180365 to 2
        Normal  ScalingReplicaSet  19s   deployment-controller  Scaled down replica set nginx-deployment-2035384211 to 1
        Normal  ScalingReplicaSet  19s   deployment-controller  Scaled up replica set nginx-deployment-1564180365 to 3
        Normal  ScalingReplicaSet  14s   deployment-controller  Scaled down replica set nginx-deployment-2035384211 to 0
    

    在這裡您可以看到,當您第一次建立部署時,它建立了一個副本集 (nginx-deployment-2035384211) 並直接將其擴展到 3 個副本。當您更新部署時,它建立了一個新的副本集 (nginx-deployment-1564180365) 並將其擴展到 1 個,並等待其啟動。然後,它將舊的副本集縮減到 2 個,並將新的副本集擴展到 2 個,以便始終至少有 3 個 Pod 可用,並且最多建立 4 個 Pod。然後,它繼續使用相同的滾動更新策略來擴展和縮減新的和舊的副本集。最後,您將在新的副本集中擁有 3 個可用的副本,而舊的副本集將縮減為 0。

覆蓋 (又名多個進行中的更新)

每次部署控制器觀察到新的部署時,都會建立一個副本集以啟動期望的 Pod。如果部署已更新,則會縮減控制 Pod 的現有副本集,這些 Pod 的標籤符合 .spec.selector,但其範本不符合 .spec.template。最終,新的副本集會擴展到 .spec.replicas,而所有舊的副本集都會縮減到 0。

如果您在現有部署推出正在進行時更新部署,則部署會根據更新建立新的副本集並開始擴展該副本集,並覆蓋先前正在擴展的副本集 -- 它會將其新增至舊副本集清單並開始縮減它。

例如,假設您建立一個部署以建立 5 個 nginx:1.14.2 的副本,但隨後在僅建立 3 個 nginx:1.14.2 副本時,將部署更新為建立 5 個 nginx:1.16.1 副本。在這種情況下,部署會立即開始終止已建立的 3 個 nginx:1.14.2 Pod,並開始建立 nginx:1.16.1 Pod。它不會等待建立 5 個 nginx:1.14.2 副本後再變更方向。

標籤選取器更新

通常不建議進行標籤選取器更新,建議預先規劃您的選取器。在任何情況下,如果您需要執行標籤選取器更新,請格外小心並確保您已掌握所有含義。

  • 新增選取器需要使用新的標籤更新部署規格中的 Pod 範本標籤,否則會傳回驗證錯誤。此變更是非重疊的變更,表示新的選取器不會選取使用舊選取器建立的副本集和 Pod,導致孤立所有舊的副本集並建立新的副本集。
  • 選取器更新會變更選取器金鑰中的現有值 -- 導致與新增相同的行為。
  • 移除選取器會從部署選取器中移除現有的金鑰 -- 不需要變更 Pod 範本標籤。現有的副本集不會孤立,也不會建立新的副本集,但請注意,移除的標籤仍然存在於任何現有的 Pod 和副本集中。

回滾部署

有時,您可能想要回滾部署;例如,當部署不穩定時,例如崩潰迴圈。預設情況下,部署的所有部署歷史記錄都保留在系統中,以便您可以隨時回滾 (您可以透過修改修訂歷史記錄限制來變更此設定)。

  • 假設您在更新部署時輸入錯誤,將映像檔名稱輸入為 nginx:1.161 而不是 nginx:1.16.1

    kubectl set image deployment/nginx-deployment nginx=nginx:1.161
    

    輸出類似於此

    deployment.apps/nginx-deployment image updated
    
  • 部署推出會停滯。您可以透過檢查推出狀態來驗證它

    kubectl rollout status deployment/nginx-deployment
    

    輸出類似於此

    Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
    
  • 按下 Ctrl-C 以停止上述推出狀態監看。如需有關停滯部署推出的更多資訊,請在此處閱讀更多內容

  • 您會看到舊副本的數量 (從 nginx-deployment-1564180365nginx-deployment-2035384211 新增副本計數) 為 3,而新副本的數量 (從 nginx-deployment-3066724191) 為 1。

    kubectl get rs
    

    輸出類似於此

    NAME                          DESIRED   CURRENT   READY   AGE
    nginx-deployment-1564180365   3         3         3       25s
    nginx-deployment-2035384211   0         0         0       36s
    nginx-deployment-3066724191   1         1         0       6s
    
  • 查看建立的 Pod,您會看到由新副本集建立的 1 個 Pod 卡在映像檔提取迴圈中。

    kubectl get pods
    

    輸出類似於此

    NAME                                READY     STATUS             RESTARTS   AGE
    nginx-deployment-1564180365-70iae   1/1       Running            0          25s
    nginx-deployment-1564180365-jbqqo   1/1       Running            0          25s
    nginx-deployment-1564180365-hysrc   1/1       Running            0          25s
    nginx-deployment-3066724191-08mng   0/1       ImagePullBackOff   0          6s
    
  • 取得部署的描述

    kubectl describe deployment
    

    輸出類似於此

    Name:           nginx-deployment
    Namespace:      default
    CreationTimestamp:  Tue, 15 Mar 2016 14:48:04 -0700
    Labels:         app=nginx
    Selector:       app=nginx
    Replicas:       3 desired | 1 updated | 4 total | 3 available | 1 unavailable
    StrategyType:       RollingUpdate
    MinReadySeconds:    0
    RollingUpdateStrategy:  25% max unavailable, 25% max surge
    Pod Template:
      Labels:  app=nginx
      Containers:
       nginx:
        Image:        nginx:1.161
        Port:         80/TCP
        Host Port:    0/TCP
        Environment:  <none>
        Mounts:       <none>
      Volumes:        <none>
    Conditions:
      Type           Status  Reason
      ----           ------  ------
      Available      True    MinimumReplicasAvailable
      Progressing    True    ReplicaSetUpdated
    OldReplicaSets:     nginx-deployment-1564180365 (3/3 replicas created)
    NewReplicaSet:      nginx-deployment-3066724191 (1/1 replicas created)
    Events:
      FirstSeen LastSeen    Count   From                    SubObjectPath   Type        Reason              Message
      --------- --------    -----   ----                    -------------   --------    ------              -------
      1m        1m          1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-2035384211 to 3
      22s       22s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-1564180365 to 1
      22s       22s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled down replica set nginx-deployment-2035384211 to 2
      22s       22s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-1564180365 to 2
      21s       21s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled down replica set nginx-deployment-2035384211 to 1
      21s       21s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-1564180365 to 3
      13s       13s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled down replica set nginx-deployment-2035384211 to 0
      13s       13s         1       {deployment-controller }                Normal      ScalingReplicaSet   Scaled up replica set nginx-deployment-3066724191 to 1
    

    若要修正此問題,您需要回滾到先前的部署修訂版本,該版本是穩定的。

檢查部署的推出歷史記錄

依照以下步驟檢查部署的推出歷史記錄

  1. 首先,檢查此部署的修訂版本

    kubectl rollout history deployment/nginx-deployment
    

    輸出類似於此

    deployments "nginx-deployment"
    REVISION    CHANGE-CAUSE
    1           kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml
    2           kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
    3           kubectl set image deployment/nginx-deployment nginx=nginx:1.161
    

    CHANGE-CAUSE 會在建立時從部署註解 kubernetes.io/change-cause 複製到其修訂版本。您可以透過以下方式指定 CHANGE-CAUSE 訊息

    • 使用 kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="image updated to 1.16.1" 註解部署
    • 手動編輯資源的 manifest。
  2. 若要查看每個修訂版本的詳細資訊,請執行

    kubectl rollout history deployment/nginx-deployment --revision=2
    

    輸出類似於此

    deployments "nginx-deployment" revision 2
      Labels:       app=nginx
              pod-template-hash=1159050644
      Annotations:  kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
      Containers:
       nginx:
        Image:      nginx:1.16.1
        Port:       80/TCP
         QoS Tier:
            cpu:      BestEffort
            memory:   BestEffort
        Environment Variables:      <none>
      No volumes.
    

回滾到先前的修訂版本

依照以下步驟將部署從目前版本回滾到先前的版本,即版本 2。

  1. 現在您已決定取消目前的部署推出並回滾到先前的修訂版本

    kubectl rollout undo deployment/nginx-deployment
    

    輸出類似於此

    deployment.apps/nginx-deployment rolled back
    

    或者,您可以透過使用 --to-revision 指定特定修訂版本來回滾

    kubectl rollout undo deployment/nginx-deployment --to-revision=2
    

    輸出類似於此

    deployment.apps/nginx-deployment rolled back
    

    如需有關部署推出相關指令的更多詳細資訊,請閱讀 kubectl rollout

    部署現在已回滾到先前的穩定修訂版本。如您所見,從部署控制器產生了用於回滾到修訂版本 2 的 DeploymentRollback 事件。

  2. 檢查回滾是否成功且部署是否如預期執行,請執行

    kubectl get deployment nginx-deployment
    

    輸出類似於此

    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   3/3     3            3           30m
    
  3. 取得部署的描述

    kubectl describe deployment nginx-deployment
    

    輸出類似於此

    Name:                   nginx-deployment
    Namespace:              default
    CreationTimestamp:      Sun, 02 Sep 2018 18:17:55 -0500
    Labels:                 app=nginx
    Annotations:            deployment.kubernetes.io/revision=4
                            kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
    Selector:               app=nginx
    Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
    StrategyType:           RollingUpdate
    MinReadySeconds:        0
    RollingUpdateStrategy:  25% max unavailable, 25% max surge
    Pod Template:
      Labels:  app=nginx
      Containers:
       nginx:
        Image:        nginx:1.16.1
        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:   nginx-deployment-c4747d96c (3/3 replicas created)
    Events:
      Type    Reason              Age   From                   Message
      ----    ------              ----  ----                   -------
      Normal  ScalingReplicaSet   12m   deployment-controller  Scaled up replica set nginx-deployment-75675f5897 to 3
      Normal  ScalingReplicaSet   11m   deployment-controller  Scaled up replica set nginx-deployment-c4747d96c to 1
      Normal  ScalingReplicaSet   11m   deployment-controller  Scaled down replica set nginx-deployment-75675f5897 to 2
      Normal  ScalingReplicaSet   11m   deployment-controller  Scaled up replica set nginx-deployment-c4747d96c to 2
      Normal  ScalingReplicaSet   11m   deployment-controller  Scaled down replica set nginx-deployment-75675f5897 to 1
      Normal  ScalingReplicaSet   11m   deployment-controller  Scaled up replica set nginx-deployment-c4747d96c to 3
      Normal  ScalingReplicaSet   11m   deployment-controller  Scaled down replica set nginx-deployment-75675f5897 to 0
      Normal  ScalingReplicaSet   11m   deployment-controller  Scaled up replica set nginx-deployment-595696685f to 1
      Normal  DeploymentRollback  15s   deployment-controller  Rolled back deployment "nginx-deployment" to revision 2
      Normal  ScalingReplicaSet   15s   deployment-controller  Scaled down replica set nginx-deployment-595696685f to 0
    

擴展部署

您可以使用以下指令來擴展部署

kubectl scale deployment/nginx-deployment --replicas=10

輸出類似於此

deployment.apps/nginx-deployment scaled

假設您的叢集中已啟用水平 Pod 自動擴展,您可以為您的部署設定自動擴展器,並根據現有 Pod 的 CPU 使用率選擇您想要執行的最小和最大 Pod 數量。

kubectl autoscale deployment/nginx-deployment --min=10 --max=15 --cpu-percent=80

輸出類似於此

deployment.apps/nginx-deployment scaled

比例擴展

RollingUpdate 部署支援同時執行應用程式的多個版本。當您或自動擴展器擴展處於部署推出中間 (無論是進行中還是已暫停) 的 RollingUpdate 部署時,部署控制器會平衡現有作用中副本集 (具有 Pod 的副本集) 中的其他副本,以降低風險。這稱為比例擴展

例如,您正在執行具有 10 個副本、maxSurge=3 和 maxUnavailable=2 的部署。

  • 確保部署中的 10 個副本正在執行。

    kubectl get deploy
    

    輸出類似於此

    NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment     10        10        10           10          50s
    
  • 您更新到新的映像檔,該映像檔恰好無法從叢集內部解析。

    kubectl set image deployment/nginx-deployment nginx=nginx:sometag
    

    輸出類似於此

    deployment.apps/nginx-deployment image updated
    
  • 映像檔更新啟動了新的部署推出,副本集為 nginx-deployment-1989198191,但由於您在上面提及的 maxUnavailable 需求而被封鎖。檢查部署推出狀態

    kubectl get rs
    

    輸出類似於此

    NAME                          DESIRED   CURRENT   READY     AGE
    nginx-deployment-1989198191   5         5         0         9s
    nginx-deployment-618515232    8         8         8         1m
    
  • 然後出現針對部署的新擴展請求。自動擴展器將部署副本數增加到 15。部署控制器需要決定將這 5 個新的副本新增到哪裡。如果您未使用比例擴展,則所有 5 個副本都將新增到新的副本集中。透過比例擴展,您可以將其他副本分散到所有副本集。較大的比例會分配給具有最多副本的副本集,而較小的比例會分配給具有較少副本的副本集。任何剩餘的副本都會新增到具有最多副本的副本集中。副本數為零的副本集不會擴展。

在我們上面的範例中,3 個副本新增到舊的副本集,2 個副本新增到新的副本集。部署推出程序最終應將所有副本移至新的副本集,前提是新的副本變得健全。若要確認這一點,請執行

kubectl get deploy

輸出類似於此

NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment     15        18        7            8           7m

部署推出狀態確認了副本如何新增到每個副本集。

kubectl get rs

輸出類似於此

NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-1989198191   7         7         0         7m
nginx-deployment-618515232    11        11        11        7m

暫停和恢復部署的部署推出

當您更新部署或計劃更新部署時,您可以在觸發一個或多個更新之前暫停該部署的部署推出。當您準備好套用這些變更時,您可以恢復部署的部署推出。這種方法可讓您在暫停和恢復之間套用多個修正程式,而不會觸發不必要的部署推出。

  • 例如,對於已建立的部署

    取得部署詳細資訊

    kubectl get deploy
    

    輸出類似於此

    NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    nginx     3         3         3            3           1m
    

    取得部署推出狀態

    kubectl get rs
    

    輸出類似於此

    NAME               DESIRED   CURRENT   READY     AGE
    nginx-2142116321   3         3         3         1m
    
  • 執行以下指令來暫停

    kubectl rollout pause deployment/nginx-deployment
    

    輸出類似於此

    deployment.apps/nginx-deployment paused
    
  • 然後更新部署的映像檔

    kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
    

    輸出類似於此

    deployment.apps/nginx-deployment image updated
    
  • 請注意,沒有啟動新的部署推出

    kubectl rollout history deployment/nginx-deployment
    

    輸出類似於此

    deployments "nginx"
    REVISION  CHANGE-CAUSE
    1   <none>
    
  • 取得部署推出狀態以驗證現有的副本集是否未變更

    kubectl get rs
    

    輸出類似於此

    NAME               DESIRED   CURRENT   READY     AGE
    nginx-2142116321   3         3         3         2m
    
  • 您可以進行任意數量的更新,例如,更新將使用的資源

    kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
    

    輸出類似於此

    deployment.apps/nginx-deployment resource requirements updated
    

    暫停部署推出之前的部署初始狀態將繼續其功能,但只要部署部署推出處於暫停狀態,對部署的新更新將不會產生任何影響。

  • 最終,恢復部署部署推出並觀察新的副本集啟動並包含所有新更新

    kubectl rollout resume deployment/nginx-deployment
    

    輸出類似於此

    deployment.apps/nginx-deployment resumed
    
  • 監看部署推出的狀態,直到完成。

    kubectl get rs --watch
    

    輸出類似於此

    NAME               DESIRED   CURRENT   READY     AGE
    nginx-2142116321   2         2         2         2m
    nginx-3926361531   2         2         0         6s
    nginx-3926361531   2         2         1         18s
    nginx-2142116321   1         2         2         2m
    nginx-2142116321   1         2         2         2m
    nginx-3926361531   3         2         1         18s
    nginx-3926361531   3         2         1         18s
    nginx-2142116321   1         1         1         2m
    nginx-3926361531   3         3         1         18s
    nginx-3926361531   3         3         2         19s
    nginx-2142116321   0         1         1         2m
    nginx-2142116321   0         1         1         2m
    nginx-2142116321   0         0         0         2m
    nginx-3926361531   3         3         3         20s
    
  • 取得最新部署推出的狀態

    kubectl get rs
    

    輸出類似於此

    NAME               DESIRED   CURRENT   READY     AGE
    nginx-2142116321   0         0         0         2m
    nginx-3926361531   3         3         3         28s
    

部署狀態

部署在其生命週期中會進入各種狀態。它可以是進行中,同時推出新的副本集,它可以是完成,或者它可以無法進行

進行中部署

當執行以下其中一項工作時,Kubernetes 會將部署標記為進行中

  • 部署建立新的副本集。
  • 部署正在擴展其最新的副本集。
  • 部署正在縮減其較舊的副本集。
  • 新的 Pod 變得就緒或可用 (就緒至少 MinReadySeconds)。

當部署推出變成「進行中」時,部署控制器會將具有以下屬性的條件新增至部署的 .status.conditions

  • type: Progressing
  • status: "True"
  • reason: NewReplicaSetCreated | reason: FoundNewReplicaSet | reason: ReplicaSetUpdated

您可以使用 kubectl rollout status 來監控部署的進度。

已完成部署

當 Kubernetes 部署具有以下特徵時,Kubernetes 會將其標記為已完成

  • 與部署關聯的所有副本都已更新為您指定的最新版本,表示您要求的所有更新都已完成。
  • 與部署關聯的所有副本都可用。
  • 沒有部署的舊副本正在執行。

當部署推出變成「已完成」時,部署控制器會將具有以下屬性的條件設定為部署的 .status.conditions

  • type: Progressing
  • status: "True"
  • reason: NewReplicaSetAvailable

Progressing 條件將保留 "True" 的狀態值,直到啟動新的部署推出。即使副本的可用性發生變更 (這確實會影響 Available 條件),該條件仍然成立。

您可以使用 kubectl rollout status 來檢查部署是否已完成。如果部署推出成功完成,kubectl rollout status 會傳回零退出代碼。

kubectl rollout status deployment/nginx-deployment

輸出類似於此

Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment "nginx-deployment" successfully rolled out

且來自 kubectl rollout 的退出狀態為 0 (成功)

echo $?
0

失敗的部署

您的部署可能會在嘗試部署其最新的副本集時停滯,而永遠無法完成。這可能是由於以下某些因素造成的

  • 配額不足
  • 就緒探測失敗
  • 映像檔提取錯誤
  • 權限不足
  • 限制範圍
  • 應用程式執行階段設定錯誤

您可以偵測到此狀況的一種方法是在部署規格中指定截止期限參數:(.spec.progressDeadlineSeconds)。.spec.progressDeadlineSeconds 表示部署控制器等待的秒數,然後 (在部署狀態中) 指示部署進度已停滯。

以下 kubectl 指令將規格設定為 progressDeadlineSeconds,以使控制器在 10 分鐘後報告部署的部署推出缺乏進度

kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'

輸出類似於此

deployment.apps/nginx-deployment patched

一旦超過截止期限,部署控制器會將具有以下屬性的 DeploymentCondition 新增至部署的 .status.conditions

  • type: Progressing
  • status: "False"
  • reason: ProgressDeadlineExceeded

此條件也可能提前失敗,然後由於 ReplicaSetCreateError 等原因而設定為 "False" 的狀態值。此外,一旦部署部署推出完成,就不再考慮截止期限。

請參閱Kubernetes API 慣例以取得有關狀態條件的更多資訊。

您的部署可能會遇到暫時性錯誤,可能是因為您設定的逾時時間過短,或是由於任何其他類型的可以視為暫時性的錯誤。例如,假設您的配額不足。如果您描述部署,您會注意到以下章節

kubectl describe deployment nginx-deployment

輸出類似於此

<...>
Conditions:
  Type            Status  Reason
  ----            ------  ------
  Available       True    MinimumReplicasAvailable
  Progressing     True    ReplicaSetUpdated
  ReplicaFailure  True    FailedCreate
<...>

如果您執行 kubectl get deployment nginx-deployment -o yaml,部署狀態類似於此

status:
  availableReplicas: 2
  conditions:
  - lastTransitionTime: 2016-10-04T12:25:39Z
    lastUpdateTime: 2016-10-04T12:25:39Z
    message: Replica set "nginx-deployment-4262182780" is progressing.
    reason: ReplicaSetUpdated
    status: "True"
    type: Progressing
  - lastTransitionTime: 2016-10-04T12:25:42Z
    lastUpdateTime: 2016-10-04T12:25:42Z
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: 2016-10-04T12:25:39Z
    lastUpdateTime: 2016-10-04T12:25:39Z
    message: 'Error creating: pods "nginx-deployment-4262182780-" is forbidden: exceeded quota:
      object-counts, requested: pods=1, used: pods=3, limited: pods=2'
    reason: FailedCreate
    status: "True"
    type: ReplicaFailure
  observedGeneration: 3
  replicas: 2
  unavailableReplicas: 2

最終,一旦超過部署進度截止期限,Kubernetes 會更新狀態和 Progressing 條件的原因

Conditions:
  Type            Status  Reason
  ----            ------  ------
  Available       True    MinimumReplicasAvailable
  Progressing     False   ProgressDeadlineExceeded
  ReplicaFailure  True    FailedCreate

您可以透過縮減部署、縮減您可能正在執行的其他控制器或增加命名空間中的配額來解決配額不足的問題。如果您滿足配額條件,並且部署控制器隨後完成部署部署推出,您將看到部署的狀態更新為成功條件 (status: "True"reason: NewReplicaSetAvailable)。

Conditions:
  Type          Status  Reason
  ----          ------  ------
  Available     True    MinimumReplicasAvailable
  Progressing   True    NewReplicaSetAvailable

type: Availablestatus: "True" 表示您的部署具有最低可用性。最低可用性由部署策略中指定的參數決定。type: Progressingstatus: "True" 表示您的部署處於部署推出中間並且正在進行中,或者它已成功完成其進度並且最低要求的新副本可用 (請參閱條件的原因以了解詳細資訊 - 在我們的案例中,reason: NewReplicaSetAvailable 表示部署已完成)。

您可以使用 kubectl rollout status 來檢查部署是否未能進行。如果部署已超過進度期限,kubectl rollout status 會傳回非零退出代碼。

kubectl rollout status deployment/nginx-deployment

輸出類似於此

Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
error: deployment "nginx" exceeded its progress deadline

且來自 kubectl rollout 的退出狀態為 1 (表示錯誤)

echo $?
1

對失敗的部署進行操作

適用於已完成部署的所有動作也適用於失敗的部署。您可以將其擴展/縮減、回滾到先前的修訂版本,甚至在您需要在部署 Pod 範本中套用多個調整時暫停它。

清除策略

您可以在部署中設定 .spec.revisionHistoryLimit 欄位,以指定您要為此部署保留多少個舊的副本集。其餘的將在背景中進行垃圾收集。預設情況下,它是 10。

金絲雀部署

如果您想要使用部署將版本發佈到使用者或伺服器的子集,您可以建立多個部署,每個版本一個部署,遵循管理資源中描述的金絲雀模式。

撰寫部署規格

與所有其他 Kubernetes 設定一樣,部署需要 .apiVersion.kind.metadata 欄位。如需有關使用設定檔的一般資訊,請參閱部署應用程式、設定容器和使用 kubectl 管理資源文件。

當控制平面為部署建立新的 Pod 時,部署的 .metadata.name 是命名這些 Pod 的基礎的一部分。部署的名稱必須是有效的 DNS 子網域 值,但這可能會為 Pod 主機名稱產生非預期的結果。為了獲得最佳相容性,名稱應遵循更嚴格的 DNS 標籤 規則。

部署也需要 .spec 區段

Pod 範本

.spec.template.spec.selector.spec 的唯一必要欄位。

.spec.templatePod 範本。它與 Pod 具有完全相同的架構,只是它是巢狀的,並且沒有 apiVersionkind

除了 Pod 的必要欄位外,部署中的 Pod 範本還必須指定適當的標籤和適當的重新啟動策略。對於標籤,請確保不要與其他控制器重疊。請參閱選取器

僅允許 .spec.template.spec.restartPolicy 等於 Always,如果未指定,則為預設值。

副本數

.spec.replicas 是一個選用欄位,用於指定期望的 Pod 數量。預設值為 1。

如果您手動擴展部署,例如透過 kubectl scale deployment deployment --replicas=X,然後您根據 manifest 更新該部署 (例如:透過執行 kubectl apply -f deployment.yaml),則套用該 manifest 會覆寫您先前執行的手動擴展。

如果 HorizontalPodAutoscaler (或任何類似的水平擴展 API) 正在管理部署的擴展,請勿設定 .spec.replicas

相反地,允許 Kubernetes 控制平面自動管理 .spec.replicas 欄位。

選取器

.spec.selector 是一個必要欄位,用於指定此部署目標 Pod 的標籤選取器

.spec.selector 必須與 .spec.template.metadata.labels 相符,否則 API 將會拒絕它。

在 API 版本 apps/v1 中,如果未設定 .spec.selector.metadata.labels,則它們不會預設為 .spec.template.metadata.labels。因此它們必須明確設定。另請注意,在 apps/v1 中建立部署後,.spec.selector 是不可變的。

如果 Pod 的範本與 .spec.template 不同,或者如果此類 Pod 的總數超過 .spec.replicas,則部署可能會終止標籤與選取器相符的 Pod。如果 Pod 的數量少於期望的數量,它會啟動具有 .spec.template 的新 Pod。

如果您有多個控制器具有重疊的選取器,則控制器將會彼此衝突並且無法正常運作。

策略

.spec.strategy 指定用於將舊 Pod 替換為新 Pod 的策略。.spec.strategy.type 可以是 "Recreate" 或 "RollingUpdate"。"RollingUpdate" 是預設值。

重新建立部署

.spec.strategy.type==Recreate 時,所有現有的 Pod 都會在建立新的 Pod 之前終止。

滾動更新部署

.spec.strategy.type==RollingUpdate 時,部署會以滾動更新方式更新 Pod。您可以指定 maxUnavailablemaxSurge 來控制滾動更新程序。

最大不可用數

.spec.strategy.rollingUpdate.maxUnavailable 是一個選填欄位,用於指定在更新過程中,最多可以有多少個 Pod 無法使用。值可以是絕對數字(例如:5)或是期望 Pod 數量的百分比(例如:10%)。絕對數字是從百分比向下取整數計算而得。如果 .spec.strategy.rollingUpdate.maxSurge 為 0,則此值不能為 0。預設值為 25%。

例如,當此值設定為 30% 時,當滾動式更新開始時,舊的 ReplicaSet 可以立即縮減到期望 Pod 數量的 70%。一旦新的 Pod 準備就緒,舊的 ReplicaSet 可以進一步縮減,然後擴增新的 ReplicaSet,以確保在更新期間任何時間可用的 Pod 總數至少為期望 Pod 數量的 70%。

Max Surge(最大突增)

.spec.strategy.rollingUpdate.maxSurge 是一個選填欄位,用於指定可以超出期望 Pod 數量而建立的最大 Pod 數量。值可以是絕對數字(例如:5)或是期望 Pod 數量的百分比(例如:10%)。如果 MaxUnavailable 為 0,則此值不能為 0。絕對數字是從百分比向上取整數計算而得。預設值為 25%。

例如,當此值設定為 30% 時,當滾動式更新開始時,新的 ReplicaSet 可以立即擴增,使得新舊 Pod 的總數不超過期望 Pod 數量的 130%。一旦舊的 Pod 被終止,新的 ReplicaSet 可以進一步擴增,以確保在更新期間任何時間運行的 Pod 總數最多為期望 Pod 數量的 130%。

以下是一些使用 maxUnavailablemaxSurge 的滾動式更新 Deployment 範例:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
 labels:
   app: nginx
spec:
 replicas: 3
 selector:
   matchLabels:
     app: nginx
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
     - name: nginx
       image: nginx:1.14.2
       ports:
       - containerPort: 80
 strategy:
   type: RollingUpdate
   rollingUpdate:
     maxUnavailable: 1

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
 labels:
   app: nginx
spec:
 replicas: 3
 selector:
   matchLabels:
     app: nginx
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
     - name: nginx
       image: nginx:1.14.2
       ports:
       - containerPort: 80
 strategy:
   type: RollingUpdate
   rollingUpdate:
     maxSurge: 1

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
 labels:
   app: nginx
spec:
 replicas: 3
 selector:
   matchLabels:
     app: nginx
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
     - name: nginx
       image: nginx:1.14.2
       ports:
       - containerPort: 80
 strategy:
   type: RollingUpdate
   rollingUpdate:
     maxSurge: 1
     maxUnavailable: 1

Progress Deadline Seconds(進度截止期限秒數)

.spec.progressDeadlineSeconds 是一個選填欄位,用於指定您希望等待 Deployment 進度的秒數,然後系統回報 Deployment 進度失敗 - 在資源狀態中以 type: Progressingstatus: "False"reason: ProgressDeadlineExceeded 的條件呈現。Deployment 控制器將持續重試 Deployment。預設值為 600。未來,一旦實作自動回滾,Deployment 控制器將在觀察到此類條件時立即回滾 Deployment。

如果指定,則此欄位需要大於 .spec.minReadySeconds

Min Ready Seconds(最少就緒秒數)

.spec.minReadySeconds 是一個選填欄位,用於指定新建立的 Pod 應處於就緒狀態的最小秒數,且其任何容器皆未發生 crash,才會被視為可用。預設值為 0(Pod 一旦就緒就會被視為可用)。若要進一步瞭解 Pod 何時被視為就緒,請參閱容器探針

Revision History Limit(修訂歷史限制)

Deployment 的修訂歷史記錄儲存在其控制的 ReplicaSet 中。

.spec.revisionHistoryLimit 是一個選填欄位,用於指定要保留多少舊的 ReplicaSet 以允許回滾。這些舊的 ReplicaSet 會消耗 etcd 中的資源,並使 kubectl get rs 的輸出變得雜亂。每個 Deployment 修訂版本的組態都儲存在其 ReplicaSet 中;因此,一旦刪除舊的 ReplicaSet,您將失去回滾到該 Deployment 修訂版本的能力。預設情況下,將保留 10 個舊的 ReplicaSet,但其理想值取決於新 Deployment 的頻率和穩定性。

更具體來說,將此欄位設定為零表示所有具有 0 個副本的舊 ReplicaSet 都將被清除。在這種情況下,新的 Deployment 推出將無法還原,因為其修訂歷史記錄已被清除。

已暫停

.spec.paused 是一個選填的布林值欄位,用於暫停和恢復 Deployment。暫停的 Deployment 與未暫停的 Deployment 之間唯一的區別在於,只要 Deployment 處於暫停狀態,對暫停的 Deployment 的 PodTemplateSpec 進行任何變更都不會觸發新的推出。Deployment 在建立時預設為未暫停。

接下來

上次修改時間:2024 年 9 月 13 日上午 9:33 PST:修正 markdown 檔案中的一些超連結 (e6855623c7)