一个 Deployment 控制器为 Pods和 ReplicaSets提供描述性的更新方式。
描述 Deployment 中的 _desired state_,并且 Deployment 控制器以受控速率更改实际状态,以达到期望状态。可以定义 Deployments 以创建新的 ReplicaSets ,或删除现有 Deployments ,并通过新的 Deployments 使用其所有资源。
注意:不要管理 Deployment 拥有的 ReplicaSets 。如果存在下面未介绍的用例,请考虑在主 Kubernetes 仓库中提出 issue。
以下是典型的 Deployments 用例:
下面是 Deployment 示例。创建一个 ReplicaSet 展开三个 nginx Pods:
                
                    controllers/nginx-deployment.yaml
                
                 | 
        
|---|
 | 
        
在该例中:
nginx-deployment 的 Deployment ,由 .metadata.name 字段指示。replicas 字段指示。selector 字段定义 Deployment 如何查找要管理的 Pods。
在这种情况下,只需选择在 Pod 模板(app: nginx)中定义的标签。但是,更复杂的选择规则是可能的,只要 Pod 模板本身满足规则。注意:`matchLabels` 字段是 {key,value} 的映射。单个 {key,value}在 `matchLabels` 映射中的值等效于 `matchExpressions` 的元素,其键字段是“key”,运算符为“In”,值数组仅包含“value”。所有要求,从 `matchLabels` 和 `matchExpressions`,必须满足才能匹配。
template 字段包含以下子字段:app: nginx,使用labels字段。.template.spec 字段指示 Pods 运行一个容器, nginx,运行 nginx Docker Hub版本1.7.9的镜像 。name字段将其命名为 nginx。按照以下步骤创建上述 Deployment :
开始之前,请确保的 Kubernetes 集群已启动并运行。
注意:可以指定 `--record` 标志来写入在资源注释`kubernetes.io/change-cause`中执行的命令。它对以后的检查是有用的。例如,查看在每个 Deployment 修改中执行的命令。
```shell
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
```
运行 kubectl get deployments 以检查 Deployment 是否已创建。如果仍在创建 Deployment ,则输出以下内容:
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         0         0            0           1s检查集群中的 Deployments 时,将显示以下字段:
  * `NAME` 列出了集群中 Deployments 的名称。
  * `DESIRED` 显示应用程序的所需 _副本_ 数,在创建 Deployment 时定义这些副本。这是 _期望状态_。
  * `CURRENT`显示当前正在运行的副本数。
  * `UP-TO-DATE`显示已更新以实现期望状态的副本数。
  * `AVAILABLE`显示应用程序可供用户使用的副本数。
  * `AGE` 显示应用程序运行的时间量。
请注意,根据`.spec.replicas`副本字段,所需副本的数量为 3。
要查看 Deployment 展开状态,运行 kubectl rollout status deployment.v1.apps/nginx-deployment。输出:
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment.apps/nginx-deployment successfully rolled out几秒钟后再次运行 kubectl get deployments。输出:
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            3           18s请注意, Deployment 已创建所有三个副本,并且所有副本都是最新的(它们包含最新的 Pod 模板)并且可用。
要查看 Deployment 创建的 ReplicaSet  (rs),运行 kubectl get rs。输出:
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-75675f5897   3         3         3       18s请注意, ReplicaSet 的名称始终被格式化为`[DEPLOYMENT-NAME]-[RANDOM-STRING]`。随机字符串是随机生成并使用 pod-template-hash 作为种子。
要查看每个 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=3123191453
nginx-deployment-75675f5897-kzszj   1/1       Running   0          18s       app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-qqcnn   1/1       Running   0          18s       app=nginx,pod-template-hash=3123191453创建的复制集可确保有三个 `nginx` Pods。
注意:必须在 Deployment 中指定适当的选择器和 Pod 模板标签(在本例中为
app: nginx)。不要与其他控制器(包括其他 Deployments 和状态设置)重叠标签或选择器。Kubernetes 不会阻止重叠,如果多个控制器具有重叠的选择器,这些控制器可能会冲突并运行意外。
注意:不要更改此标签。
Deployment 控制器将 pod-template-hash 标签添加到 Deployment 创建或使用的每个 ReplicaSet 。
此标签可确保 Deployment 的子 ReplicaSets 不重叠。它通过对 ReplicaSet 的 PodTemplate 进行哈希处理,并使用生成的哈希值添加到 ReplicaSet 选择器、Pod 模板标签,并在 ReplicaSet 可能具有的任何现有 Pod 中。
注意:仅当 Deployment Pod 模板(即
.spec.template)时,才会触发 Deployment 展开,例如,如果模板的标签或容器镜像已更新,其他更新(如扩展 Deployment )不会触发展开。
按照以下步骤更新 Deployment :
让我们更新 nginx Pods,以使用 nginx:1.9.1 镜像 ,而不是 nginx:1.7.9 镜像 。
kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1输出:
```shell
deployment.apps/nginx-deployment image updated
```
或者,可以 `edit`  Deployment 并将 `.spec.template.spec.containers[0].image` 从 `nginx:1.7.9` 更改至 `nginx:1.9.1`。
```shell
kubectl edit deployment.v1.apps/nginx-deployment
```
输出:
```shell
deployment.apps/nginx-deployment edited
```
要查看展开状态,运行:
kubectl rollout status deployment.v1.apps/nginx-deployment输出:
```shell
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
```
或者
```shell
deployment.apps/nginx-deployment successfully rolled out
```
在更新后的 Deployment 上获取更多信息
在展开成功后,可以通过运行 kubectl get deployments来查看 Deployment 。
输出:
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            3           36s运行 kubectl get rs 以查看 Deployment 通过创建新的 ReplicaSet 并缩放它更新了 Pods 最多 3 个副本,以及将旧 ReplicaSet 缩放到 0 个副本。
kubectl get rs输出:
```shell
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-1564180365   3         3         3       6s
nginx-deployment-2035384211   0         0         0       36s
```
运行 get pods 现在应仅显示新的 Pods:
kubectl get pods输出:
```shell
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
```
下次要更新这些 Pods 时,只需再次更新 Deployment  Pod 模板。
 Deployment 可确保在更新时仅关闭一定数量的 Pods。默认情况下,它确保至少 75%所需 Pods 运行(25%最大不可用)。
 Deployment 还确保仅创建一定数量的 Pods 高于期望的 Pods 数。默认情况下,它可确保最多增加 25% 期望 Pods 数(25%最大增量)。
例如,如果仔细查看上述 Deployment ,将看到它首先创建了一个新的 Pod,然后删除了一些旧的 Pods,并创建了新的 Pods。它不会杀死老 Pods,直到有足够的数量新的 Pods 已经出现,并没有创造新的 Pods,直到足够数量的旧 Pods 被杀死。它确保至少 2 个 Pods 可用,并且总共最多 4 个 Pods 可用。
获取 Deployment 的更多信息
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.9.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可以看到,当第一次创建 Deployment 时,它创建了一个 ReplicaSet  (nginx-deployment-2035384211)并将其直接扩展至 3 个副本。更新 Deployment 时,它创建了一个新的 ReplicaSet (nginx-deployment-1564180365),并将其扩展为 1,然后将旧 ReplicaSet 缩小到 2,以便至少有 2 个 Pod 可用,并且最多创建 4 个 Pod。然后,它继续向上和向下扩展新的和旧的 ReplicaSet ,具有相同的滚动更新策略。最后,将有 3 个可用的副本在新的 ReplicaSet 中,旧 ReplicaSet 将缩小到 0。
每次 Deployment 控制器观察新 Deployment 时,都会创建一个 ReplicaSet 以启动所需的 Pods。如果更新了 Deployment ,则控制其标签的 Pods 的现有 ReplicaSet 匹配 .spec.selector,但其模板不匹配 .spec.template 被缩小。最终,新的 ReplicaSet 缩放为 .spec.replicas,所有旧 ReplicaSets 缩放为 0。
当 Deployment 正在展开时进行更新, Deployment 会为每个更新创建一个新的 ReplicaSet 并开始向上扩展,之前的 ReplicaSet 会被添加到旧 ReplicaSets 队列并开始向下扩展。
例如,假设创建一个 Deployment 以创建 nginx:1.7.9 的 5 个副本,然后更新 Deployment 以创建 5 个 nginx:1.9.1 的副本,而此时只有 3 个nginx:1.7.9 的副本已创建。在这种情况下, Deployment 会立即开始杀死3个 nginx:1.7.9 Pods,并开始创建 nginx:1.9.1 Pods。它不等待 nginx:1.7.9 的 5 个副本在改变任务之前完成创建。
通常不鼓励更新标签选择器,建议提前规划选择器。在任何情况下,如果需要执行标签选择器更新,请格外小心,并确保已掌握所有的含义。
注意:在 API 版本
apps/v1中, Deployment 标签选择器在创建后是不可变的。
有时,可能需要回滚 Deployment ;例如,当 Deployment 不稳定时,例如循环崩溃。默认情况下,所有 Deployment 历史记录都保留在系统中,以便可以随时回滚(可以通过修改修改历史记录限制来更改该限制)。
注意:触发 Deployment 展开时,将创建 Deployment 修改版。这意味着仅当 Deployment Pod 模板 (
.spec.template) 发生更改时,才会创建新修改版本,例如,如果更新模板的标签或容器镜像 。其他更新,如扩展 Deployment 、不要创建 Deployment 修改版,以便方便同时手动或自动缩放。这意味着,当回滚到较早的修改版时,只有 Deployment Pod 模板部分回滚。
假设在更新 Deployment 时犯了一个拼写错误,将镜像名称命名为 nginx:1.91 而不是 nginx:1.9.1:
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true输出:
```shell
deployment.apps/nginx-deployment image updated
```
展开遇到问题。可以通过检查展开状态来验证它:
kubectl rollout status deployment.v1.apps/nginx-deployment输出:
```shell
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
```
查看旧 ReplicaSets :
kubectl get rs输出:
```shell
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,看到由新 ReplicaSet 创建的 1 个 Pod 卡在镜像拉取循环中。
kubectl get pods输出:
```shell
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
```
注意:Deployment 控制器自动停止不良展开,并停止向上扩展新的 ReplicaSet 。这取决于指定的滚动更新参数(具体为 `maxUnavailable`)。默认情况下,Kubernetes 将值设置为 25%。
获取 Deployment 描述信息:
kubectl describe deployment输出:
```shell
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.91
    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
```
要解决此问题,需要回滚到以前稳定的 Deployment 版本。
按照如下步骤检查回滚历史:
首先,检查 Deployment 修改历史:
kubectl rollout history deployment.v1.apps/nginx-deployment输出:
```shell
deployments "nginx-deployment"
REVISION    CHANGE-CAUSE
1           kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true
2           kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
3           kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true
```
`CHANGE-CAUSE` 从 Deployment 注释 `kubernetes.io/change-cause` 创建时复制到其修改版。可以通过以下条件指定 `CHANGE-CAUSE` 消息:
* 使用 `kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.9.1"`  Deployment 对 Deployment 进行分号。
* 追加 `--record` 以保存正在更改资源的 `kubectl` 命令。
* 手动编辑资源的清单。
查看修改历史的详细信息,运行:
kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2输出:
```shell
deployments "nginx-deployment" revision 2
  Labels:       app=nginx
          pod-template-hash=1159050644
  Annotations:  kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
  Containers:
   nginx:
    Image:      nginx:1.9.1
    Port:       80/TCP
     QoS Tier:
        cpu:      BestEffort
        memory:   BestEffort
    Environment Variables:      <none>
  No volumes.
```
按照下面给出的步骤将 Deployment 从当前版本回滚到以前的版本(即版本 2)。
现在已决定撤消当前展开并回滚到以前的版本:
kubectl rollout undo deployment.v1.apps/nginx-deployment输出:
```shell
deployment.apps/nginx-deployment
```
或者,可以通过使用 `--to-revision` 来回滚到特定修改版本:
```shell
kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2
```
输出:
```shell
deployment.apps/nginx-deployment
```
更多有关回滚相关指令,请参考 [`kubectl rollout`](/docs/reference/generated/kubectl/kubectl-commands#rollout).
现在, Deployment 将回滚到以前的稳定版本。如所见, Deployment 回滚事件回滚到修改版 2 是从 Deployment 控制器生成的。
检查回滚是否成功、 Deployment 是否正在运行,运行:
kubectl get deployment nginx-deployment输出:
```shell
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            3           30m
```
获取 Deployment 描述信息:
kubectl describe deployment nginx-deployment输出:
```shell
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.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
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.9.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
```
可以使用如下指令缩放 Deployment :
kubectl scale deployment.v1.apps/nginx-deployment --replicas=10输出:
deployment.apps/nginx-deployment scaled假设启用水平自动缩放 Pod在集群中,可以为 Deployment 设置自动缩放器,并选择最小和最大 要基于现有 Pods 的 CPU 利用率运行的 Pods。
kubectl autoscale deployment.v1.apps/nginx-deployment --min=10 --max=15 --cpu-percent=80输出:
deployment.apps/nginx-deployment scaled滚动更新 Deployments 支持同时运行应用程序的多个版本。当自动缩放器缩放处于展开中间的滚动更新 Deployment (仍在进行中或暂停)时, Deployment 控制器平衡现有活动中的其他 ReplicaSets (带 Pods 的 ReplicaSets ),以降低风险。这称为比例缩放。
例如,运行一个10个副本的 Deployment ,最大增加=3, 最大不可用=2.
确保这10个副本都在运行。
kubectl get deploy输出:
  NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
  nginx-deployment     10        10        10           10          50s更新到新镜像,该镜像恰好无法从集群内部解析。
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:sometag输出:
```shell
deployment.apps/nginx-deployment image updated
```
镜像更新使用 ReplicaSet nginx-deployment-1989198191 启动新的展开,但由于上面提到的最大不可用要求。检查展开状态:
kubectl get rs  输出:
```shell
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-1989198191   5         5         0         9s
nginx-deployment-618515232    8         8         8         1m
```
在上面的示例中,3 个副本添加到旧 ReplicaSet 中,2 个副本添加到新 ReplicaSet 。展开过程最终应将所有副本移动到新的 ReplicaSet ,假定新的副本变得正常。要确认这一点,请运行:
kubectl get deploy输出:
NAME                 DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment     15        18        7            8           7m展开状态确认副本如何添加到每个 ReplicaSet 。
kubectl get rs输出:
NAME                          DESIRED   CURRENT   READY     AGE
nginx-deployment-1989198191   7         7         0         7m
nginx-deployment-618515232    11        11        11        7m可以在触发一个或多个更新之前暂停 Deployment ,然后继续它。这允许在暂停和恢复之间应用多个修补程序,而不会触发不必要的 Deployment 。
例如,对于一个刚刚创建的 Deployment : 获取 Deployment 信息:
kubectl get deploy输出:
  NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
  nginx     3         3         3            3           1m获取 Deployment 状态:
  kubectl get rs输出:
  NAME               DESIRED   CURRENT   READY     AGE
  nginx-2142116321   3         3         3         1m使用如下指令中断运行:
```shell
kubectl rollout pause deployment.v1.apps/nginx-deployment
```
输出:
```shell
deployment.apps/nginx-deployment paused
```
然后更新 Deployment 镜像:
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1输出:
```shell
deployment.apps/nginx-deployment image updated
```
注意没有新的展开:
kubectl rollout history deployment.v1.apps/nginx-deployment输出:
```shell
deployments "nginx"
REVISION  CHANGE-CAUSE
1   <none>
```
获取展开状态确保 Deployment 更新已经成功:
kubectl get rs输出:
```shell
NAME               DESIRED   CURRENT   READY     AGE
nginx-2142116321   3         3         3         2m
```
更新是很容易的,例如,可以这样更新使用到的资源:
kubectl set resources deployment.v1.apps/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi输出:
```shell
deployment.apps/nginx-deployment resource requirements updated
```
暂停 Deployment 之前的初始状态将继续其功能,但新的更新只要暂停 Deployment , Deployment 就不会产生任何效果。
最后,恢复 Deployment 并观察新的 ReplicaSet ,并更新所有新的更新:
kubectl rollout resume deployment.v1.apps/nginx-deployment输出:
```shell
deployment.apps/nginx-deployment resumed
```
观察展开的状态,直到完成。
kubectl get rs -w输出:
```shell
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输出:
```shell
NAME               DESIRED   CURRENT   READY     AGE
nginx-2142116321   0         0         0         2m
nginx-3926361531   3         3         3         28s
```
注意:暂停的 Deployment 不可以回滚,除非恢复它以后。
一个 Deployment 的生命周期中会有许多状态。当正在生产新的 ReplicaSet 时可能是正在运行,可能是已完成,也可能是 Deployment 失败。
Kubernetes 使用 运行中 来标记一个 Deployment ,当下面的任务被执行时:
可以使用 kubectl rollout status 监视 Deployment 的进度。
Kubernetes 将 Deployment 标记为 _完成_,当它具有以下特征时:
可以使用 kubectl rollout status 检查 Deployment 是否已完成。如果展开成功完成,kubectl rollout status 返回退出代码 0。
kubectl rollout status deployment.v1.apps/nginx-deployment输出:
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment.apps/nginx-deployment successfully rolled out
$ echo $?
0你的 Deployment 可能会在未完成的情况下尝试 Deployment 其最新的 ReplicaSet 时遇到问题。可能发生此情况由于以下一些因素:
检测此条件的一种方法是在 Deployment 规范中指定截止时间参数:([.spec.progressDeadlineSeconds](#progress-deadline-seconds))。.spec.progressDeadlineSeconds 进度截止时间秒表示 Deployment 控制器在指示(处于 Deployment 状态)之前等待的秒数 Deployment 进度已停止。
以下 kubectl 命令设置具有进度的规范,使控制器报告 10 分钟后 Deployment 进度不足:
kubectl patch deployment.v1.apps/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'输出:
deployment.apps/nginx-deployment patched超过截止时间后, Deployment 控制器将添加具有以下属性到 Deployment 的 .status.conditions :
参考 Kubernetes API 约定 获取更多状态条件相关信息。
注意:Kubernetes 对已停止的 Deployment 不执行任何操作,只需使用
Reason=ProgressDeadlineExceeded。更高级别的编排器可以利用它并相应地采取行动,例如,将 Deployment 回滚到其以前的版本。
注意:如果暂停 Deployment ,Kubernetes 不会根据指定的截止时间检查进度。可以在展开栏中间安全地暂停 Deployment ,并在不触发超过最后期限时恢复。
Deployments 可能会出现短暂的错误,既不是因为设置的超时时间过短,也不是因为任何真正的暂时性错误。例如配额不足。如果描述 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 将更新状态和进度状态:
Conditions:
  Type            Status  Reason
  ----            ------  ------
  Available       True    MinimumReplicasAvailable
  Progressing     False   ProgressDeadlineExceeded
  ReplicaFailure  True    FailedCreate可以通过缩减 Deployment 来解决配额不足的问题,或者直接在命名空间中增加配额。如果配额条件满足, Deployment 控制器完成了 Deployment 展开, Deployment 状态会更新为成功(Status=True and Reason=NewReplicaSetAvailable)。
Conditions:
  Type          Status  Reason
  ----          ------  ------
  Available     True    MinimumReplicasAvailable
  Progressing   True    NewReplicaSetAvailableType=Available和 Status=True 表示 Deployment 具有最低可用性。最低可用性由 Deployment 策略中的参数指定。Type=Progressing 和 Status=True 表示 Deployment 处于展开中间,并且正在运行,或者已成功完成进度,最小所需新的副本处于可用(请参阅此种状态原因的相关细节,在我们的案例中Reason=NewReplicaSetAvailable 表示 Deployment 已完成)。
可以使用 kubectl rollout status 检查 Deployment 是否未能取得进展。kubectl rollout status如果 Deployment 已超过进度截止时间,则返回非零退出代码。
kubectl rollout status deployment.v1.apps/nginx-deployment输出:
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
error: deployment "nginx" exceeded its progress deadline
$ echo $?
1应用于完整 Deployment 的所有操作也适用于失败的 Deployment 。可以向上/向下扩展,回滚到以前的修改版,或者如果需要在 Deployment Pod 模板中应用多个调整,甚至将其暂停。
可以在 Deployment 中设置 .spec.revisionHistoryLimit ,以指定保留多少此 Deployment 的 ReplicaSets。其余的将在后台进行垃圾回收。默认情况下,是10。
注意:显式将此字段设置为 0 将导致清理 Deployment 的所有历史记录,因此 Deployment 将无法回滚。
如果要使用 Deployment 向用户或服务器子集展开版本,则可以创建多个 Deployments ,每个版本一个,遵循资源管理。
同其他 Kubernetes 配置, Deployment 需要 apiVersion, kind, 和 metadata 字段。有关配置文件的其他信息,参考 应用 Deployment ,配置容器,和 使用 kubectl 管理资源 相关文档。
Deployment 还需要 .spec 部分。
.spec仅需要 .spec.template 和 .spec.selector。
.spec.template 是一个 Pod 示例。它和 Pod的约束完全相同,除了它是嵌套的,而且没有 apiVersion 或 kind。
除了 Pod 的必填字段外, Deployment 中的 Pod 模板必须指定适当的标签和适当的重新启动策略。对于标签,请确保不要与其他控制器重叠。请参考选择器)。
只有 .spec.template.spec.restartPolicy 等于 Always 被允许,这是在没有指定时的默认设置。
.spec.replicas 是指定所需 Pod 的可选字段。它的默认值是1。
.spec.selector 是指定本次 Deployment  Pods 标签选择器的必要字段。
.spec.selector 必须匹配 .spec.template.metadata.labels,否则请求会被 API 拒绝。
在 API apps/v1版本中,.spec.selector 和 .metadata.labels 不会被默认设置为 .spec.template.metadata.labels,如果没有设置的话。所以需要明确进行设置。同时在 apps/v1版本中, Deployment 创建后 .spec.selector 是可变的。
当 Pods 的标签和选择器匹配时,此类 Pods 的模板和 .spec.template 不同,或者此类 Pods 的总数超过 .spec.replicas, Deployment 会终结这些 Pods。如果 Pods 总数达不到期望值,会用 .spec.template 创建新的 Pods。
注意:不应创建其标签与此选择器匹配的 Pods,或者直接创建另一个 Deployment ,或通过创建其他控制器(如 ReplicaSet 或复制控制器)。如果这样做,第一个 Deployment 认为它创建了这些其他 Pods。Kubernetes 不会阻止你这么做。
如果有多个具有重叠选择器的控制器,则控制器之间会因冲突而故障。
.spec.strategy 策略指定用于用新 Pods 替换旧 Pods 的策略。.spec.strategy.type 可以是“Recreate”或“RollingUpdate”。“RollingUpdate”是默认值。
当 .spec.strategy.type==Recreate,所有现有的 Pods 在创建新 Pods 之前被杀死。
Deployment 会在 .spec.strategy.type==RollingUpdate时,采取 滚动更新的方式更新Pods。可以指定 maxUnavailable 和 maxSurge 来控制滚动更新操作。
.spec.strategy.rollingUpdate.maxUnavailable 是指定最大数量的可选字段,表示在更新过程中不可用的 Pods。该值可以是绝对数字(例如,5)或所需 Pods 的百分比(例如,10%)。绝对数按百分比计算,四舍五入下来。如果 .spec.strategy.rollingUpdate.maxSurge 为 0,则该值不能为 0。默认值为 25%。
例如,当此值设置为 30% 时,滚动更新开始时会立即将旧 ReplicaSet 向下扩展到期望 Pods 的70%。新 Pods 准备就绪后,可以缩放旧 ReplicaSet 进一步向下,然后向上扩展新的 ReplicaSet ,确保可用的 Pods 总数在更新期间,任何时候都至少为 70% 所需的 Pods。
.spec.strategy.rollingUpdate.maxSurge  是指定最大 Pods 数的可选字段可在所需的 Pods 数上创建。该值可以是绝对数(例如,5)或所需 Pods 的百分比(例如,10%)。如果 MaxUnavailable 0,则值不能为 0。绝对数通过舍入从百分比计算。默认值为 25%。
例如,当此值设置为 30 时,启动滚动更新后,会立即展开新的 ReplicaSet ,以便新旧 Pod 的总数不超过所需的 130%。一旦旧 Pods 被杀死,新的 ReplicaSet 可以进一步扩展,确保更新期间任何时间运行的 Pods 总数最多为所需 Pods 总数的130%。
.spec.progressDeadlineSeconds 是一个可选字段,用于指定等待的秒数而后在系统报告中返回 Deployment 失败,同时在资源状态中 Type=Progressing、 Status=False 、 Reason=ProgressDeadlineExceeded 。  Deployment 控制器将保留正在重试 Deployment 。将来,一旦实现自动回滚, Deployment 控制器将回滚 Deployment ,只要它探测到这样的条件。
如果指定,则此字段需要大于 .spec.minReadySeconds。
.spec.minReadySeconds 是一个可选字段,用于指定新创建的 Pod 在没有任意容器崩溃情况下的最小就绪时间,以便将其视为可用。默认值为 0(Pod 在准备就绪后立即将被视为可用)。了解有关何时Pod 被视为已准备就绪,参考容器探针。
.spec.rollbackTo 字段已经在 API 版本 extensions/v1beta1 和 apps/v1beta1中废弃了,并且从 apps/v1beta2版本开始不在支持。相应的,会开始使用已经引入回滚到上一个版本中的 kubectl rollout undo。
Deployment 修改历史记录存储在它所控制的 ReplicaSets 中。
.spec.revisionHistoryLimit 修改历史记录限制是一个可选字段,用于指定要保留的旧 ReplicaSets 的数量以允许回滚。这些旧 ReplicaSets 消耗 etcd 中的资源,并占用 kubectl get rs 的输出。每个 Deployment 修改版的配置都存储在其 ReplicaSets 中;因此,一旦删除了旧的 ReplicaSet ,将失去回滚到 Deployment 版本的能力。默认情况下,将保留 10 个旧 ReplicaSets ,但其理想值取决于新 Deployment 的频率和稳定性。
更具体地说,将此字段设置为 0 意味着将清理所有具有 0 个副本的旧 ReplicaSets 。在这种情况下,无法撤消新的 Deployment 展开,因为它的修改历史被清除了。
.spec.paused 是用于暂停和恢复 Deployment 的可选布尔字段。暂停的 Deployment 和未暂停的 Deployment 唯一的区别,只要暂停 Deployment 处于暂停状态, PodTemplateSpec 的任意修改都不会触发新的展开。默认 Deployment 在创建时是不会被暂停的。
kubectl rolling update更新 Pods 和副本控制器的方式类似。但是,建议采取 Deployments 的方式来更新,因为它们是声明性的,在服务器端,并且具有其他功能,例如,即使在滚动更新完成后,也会回滚到以前的任何修改版本。
此页是否对您有帮助?
感谢反馈。如果您有一个关于如何使用 Kubernetes 的特定的、需要答案的问题,可以访问 Stack Overflow. 在 GitHub 仓库上登记新的问题 报告问题 或者 提出改进建议.