部署

部署管理一组 Pod 来运行应用程序工作负载,通常是那些不维护状态的应用程序工作负载。

部署PodReplicaSets提供声明式更新。

您在部署中描述一个期望状态,然后部署控制器以受控速率将实际状态更改为期望状态。您可以定义部署来创建新的 ReplicaSets,或者删除现有部署并使用新的部署采用其所有资源。

用例

以下是部署的典型用例

创建部署

以下是一个部署的示例。它创建了一个 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字段指示。此名称将成为稍后创建的 ReplicaSets 和 Pods 的基础。有关更多详细信息,请参阅编写部署规范

  • 部署创建了一个 ReplicaSet,它创建三个复制的 Pod,由.spec.replicas字段指示。

  • .spec.selector字段定义了创建的 ReplicaSet 如何查找要管理的 Pod。在本例中,您选择在 Pod 模板(app: nginx)中定义的标签。但是,只要 Pod 模板本身满足规则,就可以使用更复杂的选择规则。

  • template字段包含以下子字段

    • Pod 使用.metadata.labels字段标记为app: nginx
    • Pod 模板的规范或.template.spec字段表明 Pod 运行一个容器nginx,它运行nginxDocker Hub 镜像版本 1.14.2。
    • 使用.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显示应用程序有多少个副本可供用户使用。它遵循以下模式:ready/desired。
    • UP-TO-DATE显示已更新以实现期望状态的副本数量。
    • AVAILABLE显示应用程序有多少个副本可供用户使用。
    • AGE显示应用程序运行的时间量。

    请注意,根据.spec.replicas字段,期望的副本数为 3。

  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. 要查看部署创建的 ReplicaSet(rs),请运行kubectl get rs。输出类似于以下内容

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

    ReplicaSet 输出显示以下字段

    • NAME列出命名空间中的 ReplicaSet 名称。
    • DESIRED显示应用程序的期望副本数,您在创建部署时定义了该数字。这是期望状态
    • CURRENT显示当前正在运行的副本数量。
    • READY显示应用程序有多少个副本可供用户使用。
    • AGE显示应用程序运行的时间量。

    请注意,ReplicaSet 的名称始终格式化为[DEPLOYMENT-NAME]-[HASH]。此名称将成为创建的 Pod 的基础。

    HASH字符串与 ReplicaSet 上的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
    

    创建的 ReplicaSet 确保有三个nginx Pod。

pod-template-hash 标签

pod-template-hash标签由部署控制器添加到部署创建或采用的每个 ReplicaSet。

此标签可确保部署的子 ReplicaSet 不重叠。它是通过对 ReplicaSet 的PodTemplate进行哈希处理并使用生成的哈希值作为添加到 ReplicaSet 选择器、Pod 模板标签以及 ReplicaSet 可能拥有的任何现有 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以查看部署通过创建新的 ReplicaSet 并将其扩展到 3 个副本,以及将旧 ReplicaSet 缩减到 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。如果部署被更新,则控制与 .spec.selector 匹配的标签但模板不匹配 .spec.template 的 Pod 的现有副本集将被缩减。最终,新的副本集将扩展到 .spec.replicas,所有旧的副本集都将缩减到 0。

如果您在现有的部署正在进行时更新部署,则部署会根据更新创建一个新的副本集,并开始将其扩展,然后将之前正在扩展的副本集回滚 - 它会将该副本集添加到其旧副本集列表中,并开始将其缩减。

例如,假设您创建了一个部署来创建 5 个 nginx:1.14.2 的副本,但随后更新了部署来创建 5 个 nginx:1.16.1 的副本,而当时只创建了 3 个 nginx:1.14.2 的副本。在这种情况下,部署会立即开始终止它已创建的 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" 为部署添加注释
    • 手动编辑资源的清单。
  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

    部署现在已回滚到先前的稳定修订版。如您所见,从部署控制器生成了一个 DeploymentRollback 事件,用于回滚到修订版 2。

  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

比例扩展

滚动更新部署支持同时运行应用程序的多个版本。当您或自动扩展器扩展正在进行回滚(正在进行中或已暂停)的滚动更新部署时,部署控制器会在现有活动副本集(具有 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 -w
    

    输出类似于以下内容

    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 会将部署标记为“完成”

  • 与部署相关的所有副本都已更新到您指定的最新版本,这意味着您请求的任何更新都已完成。
  • 与部署相关的所有副本都可用。
  • 部署的任何旧副本都不在运行。

当回滚变为“完成”时,部署控制器会向部署的 .status.conditions 中设置一个具有以下属性的条件

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

Progressing 条件将保留 "True" 的状态值,直到启动新的 rollout。即使副本的可用性发生变化,该条件也会保持不变(但这会影响 Available 条件)。

可以使用 kubectl rollout status 检查 Deployment 是否已完成。如果 rollout 成功完成,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

Deployment 失败

您的 Deployment 可能会卡在尝试部署最新的 ReplicaSet 上,而无法完成。这可能是由以下一些因素造成的:

  • 配额不足
  • 就绪探测失败
  • 镜像拉取错误
  • 权限不足
  • 资源限制
  • 应用程序运行时配置错误

您可以通过在 Deployment spec 中指定截止日期参数来检测此条件:(.spec.progressDeadlineSeconds)。.spec.progressDeadlineSeconds 表示 Deployment 控制器在指示 (在 Deployment 状态中) Deployment 进度已停滞之前等待的秒数。

以下 kubectl 命令将使用 progressDeadlineSeconds 设置 spec,以便控制器在 Deployment 的 rollout 10 分钟后报告缺乏进度。

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

输出类似于以下内容

deployment.apps/nginx-deployment patched

一旦超过截止日期,Deployment 控制器就会在 Deployment 的 .status.conditions 中添加一个 DeploymentCondition,该条件具有以下属性:

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

此条件也可能过早失败,然后由于 ReplicaSetCreateError 等原因而设置为状态值为 "False"。此外,一旦 Deployment rollout 完成,就不再考虑截止日期。

有关状态条件的更多信息,请参阅 Kubernetes API 约定

您可能会遇到 Deployment 的瞬时错误,这可能是由于您设置的超时时间过短,或者由于任何其他类型的错误,这些错误可以被视为瞬时错误。例如,假设您配额不足。如果描述 Deployment,您会注意到以下部分:

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,Deployment 状态类似于以下内容:

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

最终,一旦超过 Deployment 进度截止日期,Kubernetes 就会更新状态和 Progressing 条件的原因。

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

您可以通过缩减 Deployment、缩减您可能正在运行的其他控制器,或者增加命名空间中的配额来解决配额不足的问题。如果您满足配额条件,然后 Deployment 控制器完成了 Deployment rollout,您将看到 Deployment 的状态更新为成功条件 (status: "True"reason: NewReplicaSetAvailable)。

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

type: Availablestatus: "True" 表示您的 Deployment 具有最低可用性。最低可用性由部署策略中指定的参数决定。type: Progressingstatus: "True" 表示您的 Deployment 正在进行 rollout 过程中,或者它已成功完成其进度,并且所需的最小新副本可用(有关详细信息,请参阅条件的原因 - 在我们的例子中,reason: NewReplicaSetAvailable 表示 Deployment 已完成)。

可以使用 kubectl rollout status 检查 Deployment 是否未能进行。如果 Deployment 超过了进度截止日期,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

操作失败的 deployment

所有适用于已完成 Deployment 的操作也适用于失败的 Deployment。您可以对其进行扩展/缩减、回滚到之前的修订版本,甚至可以暂停它,如果您需要在 Deployment Pod 模板中应用多个调整。

清理策略

您可以在 Deployment 中设置 .spec.revisionHistoryLimit 字段,以指定要保留的此 Deployment 的旧 ReplicaSet 的数量。其余的将在后台被垃圾回收。默认情况下,该值为 10。

金丝雀部署

如果您希望使用 Deployment 将版本发布到用户或服务器的子集,则可以创建多个 Deployment,每个版本一个,遵循 管理资源 中描述的金丝雀模式。

编写 Deployment Spec

与所有其他 Kubernetes 配置一样,Deployment 需要 .apiVersion.kind.metadata 字段。有关使用配置文件的常规信息,请参阅 部署应用程序、配置容器和 使用 kubectl 管理资源 文档。

当控制平面为 Deployment 创建新的 Pod 时,Deployment 的 .metadata.name 是为这些 Pod 命名的一部分。Deployment 的名称必须是有效的 DNS 子域 值,但这会导致 Pod 主机名的意外结果。为了获得最佳兼容性,名称应遵循更严格的 DNS 标签 规则。

Deployment 还需要一个 .spec 部分

Pod 模板

.spec.template.spec.selector.spec 的唯一必填字段。

.spec.template 是一个 Pod 模板。它与 Pod 具有完全相同的架构,只是它嵌套在内部,没有 apiVersionkind

除了 Pod 的必填字段之外,Deployment 中的 Pod 模板还必须指定适当的标签和适当的重启策略。对于标签,请确保不要与其他控制器重叠。请参阅 selector

仅允许 .spec.template.spec.restartPolicy 等于 Always,如果未指定,则为默认值。

副本

.spec.replicas 是一个可选字段,它指定所需 Pod 的数量。默认值为 1。

如果您手动扩展 Deployment,例如通过 kubectl scale deployment deployment --replicas=X,然后您根据清单更新该 Deployment(例如:通过运行 kubectl apply -f deployment.yaml),那么应用该清单将覆盖您之前进行的手动扩展。

如果 HorizontalPodAutoscaler(或任何类似的水平扩展 API)正在管理 Deployment 的扩展,则不要设置 .spec.replicas

相反,请允许 Kubernetes 控制平面 自动管理 .spec.replicas 字段。

选择器

.spec.selector 是一个必填字段,它指定此 Deployment 目标的 Pod 的 标签选择器

.spec.selector 必须与 .spec.template.metadata.labels 匹配,否则 API 将拒绝它。

在 API 版本 apps/v1 中,如果未设置 .spec.selector.metadata.labels,则它们不会默认设置为 .spec.template.metadata.labels。因此,必须显式设置它们。还要注意,在 apps/v1 中创建 Deployment 后,.spec.selector 是不可变的。

如果 Deployment 的模板与 .spec.template 不同,或者此类 Pod 的总数超过 .spec.replicas,则 Deployment 可能会终止其标签与选择器匹配的 Pod。如果 Pod 的数量少于所需数量,它将使用 .spec.template 启动新的 Pod。

如果您有多个具有重叠选择器的控制器,这些控制器将相互争斗,并且不会正常运行。

策略

.spec.strategy 指定用于用新 Pod 替换旧 Pod 的策略。.spec.strategy.type 可以是 "Recreate" 或 "RollingUpdate"。"RollingUpdate" 是默认值。

重新创建 Deployment

.spec.strategy.type==Recreate 时,在创建新的 Pod 之前,所有现有的 Pod 都会被杀死。

滚动更新 Deployment

.spec.strategy.type==RollingUpdate 时,Deployment 会以滚动更新的方式更新 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%。

最大激增

.spec.strategy.rollingUpdate.maxSurge 是一个可选字段,指定可以创建的 Pod 数量超过所需 Pod 数量的最大值。该值可以是绝对值(例如,5)或所需 Pod 的百分比(例如,10%)。如果 MaxUnavailable 为 0,则该值不能为 0。绝对值是通过向上取整从百分比计算得出的。默认值为 25%。

例如,当此值设置为 30% 时,在滚动更新开始时,新 ReplicaSet 可以立即扩展,这样旧 Pod 和新 Pod 的总数不会超过所需 Pod 的 130%。一旦旧的 Pod 被杀死,新的 ReplicaSet 可以进一步扩展,确保在更新期间任何时候运行的 Pod 的总数最多为所需 Pod 的 130%。

以下是一些使用 maxUnavailablemaxSurge 的滚动更新部署示例

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

进度截止时间(秒)

.spec.progressDeadlineSeconds 是一个可选字段,指定您希望等待 Deployment 进度的时间(以秒为单位),然后系统报告 Deployment 进度已 失败 - 在资源状态中以 type: Progressingstatus: "False"reason: ProgressDeadlineExceeded 的条件形式显示。Deployment 控制器将继续重试 Deployment。默认值为 600。将来,一旦实现自动回滚,Deployment 控制器将在观察到此类条件后立即回滚 Deployment。

如果指定,此字段需要大于 .spec.minReadySeconds

最小就绪秒数

.spec.minReadySeconds 是一个可选字段,指定新创建的 Pod 应该在没有其任何容器崩溃的情况下就绪的最短时间(以秒为单位),以便它被认为是可用的。默认值为 0(Pod 只要就绪就会被认为是可用的)。要了解有关何时将 Pod 视为就绪的更多信息,请参阅 容器探针

修订历史记录限制

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 年 3 月 14 日下午 2:28 PST:Add metadata to use mechanism for API reference links (c889d9b251)