Deployment

    只需在Deployment对象中描述所期望的状态 ,Deployment Controller就会以受控的速率将实际状态逐步转变为你所期望的状态。您可以定义Deployment以创建新的ReplicaSet,也可删除现有Deployment并让新的Deployment采用其所有资源。

    注意:您不应该管理Deployment所拥有的ReplicaSet。而应该操作Deployment对象从而管理ReplicaSet。如果你认为有必须直接管理Deployment所拥有的ReplicaSet的场景,请考虑在Kubernetes repo中提Issue。

    以下是Deployment的典型用例:

    • (创建Deployment从而升级ReplicaSet)。 ReplicaSet在后台创建Pod。检查升级的状态,看是否成功。
    • 通过更新Deployment的PodTemplateSpec来 Declare the new state of the Pods (声明Pod的新状态)。 这样,会创建一个新的ReplicaSet,并且Deployment会以受控的速率,将Pod从旧ReplicaSet移到新的ReplicaSet。每个新的ReplicaSet都会更新Deployment的修订版本。
    • 如果的Deployment当前状态不稳定,则 (回滚到之前的Deployment修订版本)。每次回滚都会更新Deployment的修订版本。
    • Scale up the Deployment to facilitate more load (扩展Deployment,以便更多的负载)
    • (暂停Deployment),从而将多个补丁应用于其PodTemplateSpec,然后恢复它,开始新的升级。
    • Use the status of the Deployment (使用Deployment的状态)作为升级卡住的指示器。
    • 清理您不再需要的 (清理旧的ReplicaSet)

    创建Deployment

    以下是Deployment的示例。它创建一个包含三个nginx Pod的ReplicaSet:

    在本例中:

    • 将创建名为nginx-deployment 的Deployment,由metadata: name 字段定义。
    • Deployment创建三个Pod副本,由replicas 字段定义。
    • Pod模板的规范,即:template: spec字段定义Pod运行一个 nginx 容器,它运行1.7.9版的nginx Docker Hub 镜像。
    • Deployment打开80端口供Pod使用。

    template 字段包含以下说明:

    • Pod被打上了app: nginx 的标签
    • 创建一个名为nginx 的容器。
    • 运行nginx 1.7.9 镜像。
    • 打开端口80 ,以便容器可以发送和接收流量。

    要创建此Deployment,请运行以下命令:

    1. kubectl create -f https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/master/docs/concepts/workloads/controllers/nginx-deployment.yaml

    注意:您可以将--record 附加到此命令以在资源的annotation中记录当前命令。这对将来的审查(review)很有用,例如调查在每个Deployment修订版中执行了哪些命令。

    接下来,运行kubectl get deployments ,将会输出类似如下内容:

    1. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
    2. nginx-deployment 3 0 0 0 1s

    当您inspect集群中的“Deployment”时,将会显示以下字段:

    • NAME 列出了集群中Deployment的名称。

    • DESIRED 显示您创建Deployment时所定义的期望副本数。这是所需的状态

    • CURRENT 显示当前正在运行的副本数。

    • UP-TO-DATE 显示已更新,从而实现期望状态的副本数。

    • AVAILABLE 显示当前有可用副本的数量。

    • AGE 显示应用程序已经运行了多久。

    注意每个字段中的值如何对应于Deployment规范中的值:

    • 根据spec: replicas 字段,期望的副本数量是3。
    • 根据.status.replicas 字段,当前副本的数量为0。
    • 根据.status.updatedReplicas 字段,最新副本的数量为0。
    • 根据.status.availableReplicas 字段,可用副本的数量为0。

    要查看Deployment升级的状态,请运行 kubectl rollout status deployment/nginx-deployment 。此命令将会返回类似如下的输出:

    1. Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
    2. deployment "nginx-deployment" successfully rolled out

    几秒钟后再次运行kubectl get deployments

    1. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
    2. nginx-deployment 3 3 3 3 18s

    由结果可知,Deployment已创建三个Pod副本,并且所有副本都是最新的(它们包含最新的Pod模板)并且可用(Pod状态为Ready的持续时间至少得达到.spec.minReadySeconds 字段定义的值)。

    编者按:拓展阅读:

    要查看Deployment创建的ReplicaSet( rs ),可运行kubectl get rs

    1. NAME DESIRED CURRENT READY AGE
    2. nginx-deployment-2035384211 3 3 3 18s

    请注意,ReplicaSet的名称的格式始终为 [DEPLOYMENT-NAME]-[POD-TEMPLATE-HASH-VALUE] 。创建Deployment时会自动生成该hash。

    要查看为每个Pod自动生成的label,请运行 kubectl get pods --show-labels 。 可返回类似以下输出:

    1. NAME READY STATUS RESTARTS AGE LABELS
    2. nginx-deployment-2035384211-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211
    3. nginx-deployment-2035384211-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211
    4. nginx-deployment-2035384211-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211

    ReplicaSet会确保在任何时候都有三个nginx Pod运行。

    注意:您必须在Deployment中指定适当的选择器和Pod模板标签(在本例中为app: nginx )。不要与其他Controller(包括其他Deployment和StatefulSet)所使用的标签或选择器重叠。Kubernetes不会阻止您重叠,如果多个Controller选择器发生重叠,那么这些Controller可能会出现冲突并且出现意外。

    注意:请勿修改此标签。

    pod-template-hash label由Deployment Controller添加到其创建或采用的每个ReplicaSet上。

    此标签可确保Deployment的子ReplicaSet不重叠。 它通过将ReplicaSet的PodTemplate 进行hash,并将生成的hash值作为标签,添加到ReplicaSet选择器、Pod模板标签、ReplicaSet所拥有的任何现有Pod中。

    升级Deployment

    注意:当且仅当Deployment的Pod模板(即.spec.template )发生变化时,Deployment才会发生升级。例如,如果模板的标签或容器镜像被更新,则会触发Deployment的更新。 其他更新,例如对Deployment伸缩,不会触发更新。

    假设我们现在想要升级nginx Pod,让其使用nginx:1.9.1 镜像,而非nginx:1.7.9 镜像。

    1. $ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
    2. deployment "nginx-deployment" image updated

    也可edit Deployment,并将.spec.template.spec.containers[0].imagenginx:1.7.9 改为 nginx:1.9.1

    1. $ kubectl edit deployment/nginx-deployment
    2. deployment "nginx-deployment" edited

    要想查看升级的状态,可运行:

    1. $ kubectl rollout status deployment/nginx-deployment
    2. Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
    3. deployment "nginx-deployment" successfully rolled out

    升级成功后,您可能希望get Deployment:

    1. $ kubectl get deployments
    2. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
    3. nginx-deployment 3 3 3 3 36s
    • up-to-date:表示Deployment已升级为最新配置的副本数量
    • current:表示此Deployment管理的副本总数
    • available:表示当前可用副本的数量。

    运行kubectl get rs 即可看到,Deployment通过创建一个新的ReplicaSet并将其扩展到3个副本,并将旧ReplicaSet减少到0个副本的方式更新Pod。

    1. $ kubectl get rs
    2. NAME DESIRED CURRENT READY AGE
    3. nginx-deployment-1564180365 3 3 3 6s
    4. nginx-deployment-2035384211 0 0 0 36s

    运行get pods ,则只会显示新的Pod:

    1. $ kubectl get pods
    2. NAME READY STATUS RESTARTS AGE
    3. nginx-deployment-1564180365-khku8 1/1 Running 0 14s
    4. nginx-deployment-1564180365-nacti 1/1 Running 0 14s
    5. nginx-deployment-1564180365-z9gth 1/1 Running 0 14s

    当下次我们要更新这些Pod时,只需再次更新Deployment的Pod模板。

    Deployment可确保在升级时,只有一定数量的Pod会被关闭。默认情况下,它确保至少少有于1个期望数量的Pod运行(最多1个不可用)。

    Deployment还可确保在期望数量的Pod上,只能创建一定数量的Pod。 默认情况下,它确保最多有多于1个期望数量的Pod运行(最多1个波动)。

    未来,默认值将从1-1变为25%-25%。

    例如,如果您仔细观察上述Deployment,您将看到它首先创建了一个新Pod,然后删除一些旧Pod并创建新Pod。直到新新Pod的数量已经足够,它才会杀死旧Pod;直到足够数量的老Pod被杀死才创建新Pod。 它确保可用的Pod数量至少为2,并且Pod总数量至多为4。

    1. $ kubectl describe deployments
    2. Name: nginx-deployment
    3. Namespace: default
    4. CreationTimestamp: Tue, 15 Mar 2016 12:01:06 -0700
    5. Labels: app=nginx
    6. Annotations: deployment.kubernetes.io/revision=2
    7. Selector: app=nginx
    8. Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
    9. StrategyType: RollingUpdate
    10. MinReadySeconds: 0
    11. RollingUpdateStrategy: 1 max unavailable, 1 max surge
    12. Pod Template:
    13. Labels: app=nginx
    14. Containers:
    15. nginx:
    16. Image: nginx:1.9.1
    17. Port: 80/TCP
    18. Mounts: <none>
    19. Volumes: <none>
    20. Conditions:
    21. Type Status Reason
    22. ---- ------ ------
    23. Available True MinimumReplicasAvailable
    24. Progressing True NewReplicaSetAvailable
    25. OldReplicaSets: <none>
    26. NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created)
    27. Events:
    28. FirstSeen LastSeen Count From SubobjectPath Type Reason Message
    29. --------- -------- ----- ---- ------------- -------- ------ -------
    30. 36s 36s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3
    31. 23s 23s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1
    32. 23s 23s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2
    33. 23s 23s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2
    34. 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0
    35. 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3

    由上可知,当我们第一次创建Deployment时,它创建了一个ReplicaSet(nginx-deployment-2035384211),并直接将其扩容到3个副本。当我们升级Deployment时,它创建了一个新ReplicaSet(nginx-deployment-1564180365),并将其扩容到1,然后将旧ReplicaSet缩容到2。这样,在任何时候,至少有2个Pod可用,并且至多创建4个Pod。 然后,继续按照相同的滚动更新策略对新旧ReplicaSet进行扩容/缩容。最后,新ReplicaSet中将会有3个可用副本,旧ReplicaSet副本缩小到0。

    Rollover(翻转)(也称为multiple updates in-flight[不停机多更新、多个升级并行])

    如果在更新Deployment时,另一个更新正在进行中,那么Deployment就会为每个更新创建一个新的ReplicaSet,并开始扩容,并将滚动以前扩容的ReplicaSet——它会将其添加到旧ReplicaSet列表中,并开始缩容它。

    例如,假设您创建一个Deployment,让它创建5个nginx:1.7.9 副本,当仅3个nginx:1.7.9 副本完成创建时,你开始更新Deployment,让它创建5个nginx:1.9.1 副本。在这种情况下,Deployment将会立即开始杀死已创建的3个nginx:1.7.9 Pod,并将开始创建nginx:1.9.1 Pod。它不会等待5个副本的nginx:1.7.9 都创建完成后再开始创建1.9.1的Pod。

    标签选择器更新

    通常不鼓励更新标签选择器,建议您预先规划好您的选择器。无论如何,如果您需要更新标签选择器,请务必谨慎,并确保您已经掌握了所有的含义。

    注意:在API版本apps/v1beta2 中,Deployment的标签选择器创建后不可变。

    • 添加选择器要求Deployment规范中的Pod模板标签也更新为新标签,否则将会返回验证错误。此更改是不重叠的,这意味着新选择器不会选择使用旧选择器所创建的ReplicaSet和Pod,也就是说,所有旧版本的ReplicaSet都会被丢弃,并创建新ReplicaSet。
    • 更新选择器——即,更改选择器中key中的现有value,会导致与添加相同的行为。
    • 删除选择器——即从Deployment选择器中删除现有key——不需要对Pod模板标签进行任何更改。现有的ReplicaSet不会被孤立,也不会创建新的ReplicaSet,但请注意,删除的标签仍然存在于任何现有的Pod和ReplicaSet中。

    回滚Deployment

    有时您可能想要回滚Deployment;例如,当Deployment不稳定时,例如循环崩溃。 默认情况下,所有Deployment的升级历史记录都保留在系统中,以便能随时回滚(可通过修改“版本历史记录限制”进行更改)。

    注意:当Deployment的升级被触发时,会创建Deployment的修订版本。这意味着当且仅当更改Deployment的Pod模板( .spec.template )时,才会创建新版本,例如,模板的标签或容器镜像发生改变。其他更新(例如伸缩Deployment)不会创建Deployment修订版本,以便我们可以方便同时进行手动或自动缩放。这意味着,当您回滚到较早的版本时,对于一个Deployment,只有Pod模板部分会被回滚。

    假设我们在更新Deployment时写错了字,将镜像名称写成了nginx:1.91 而非nginx:1.9.1

    升级将被卡住。

    1. $ kubectl rollout status deployments nginx-deployment
    2. Waiting for rollout to finish: 2 out of 3 new replicas have been updated...

    按下Ctrl-C,即可停止查阅上述状态。有关升级卡住的更多信息,请 read more here

    您还将看到旧副本(nginx-deployment-1564180365和nginx-deployment-2035384211)和新副本(nginx-deployment-3066724191)的数量都是2。

    1. $ kubectl get rs
    2. NAME DESIRED CURRENT READY AGE
    3. nginx-deployment-1564180365 2 2 0 25s
    4. nginx-deployment-2035384211 0 0 0 36s
    5. nginx-deployment-3066724191 2 2 2 6s

    查看创建的Pod,您将看到由新ReplicaSet创建的2个Pod卡在拉取镜像的过程中。

    1. $ kubectl get pods
    2. nginx-deployment-1564180365-70iae 1/1 Running 0 25s
    3. nginx-deployment-1564180365-jbqqo 1/1 Running 0 25s
    4. nginx-deployment-3066724191-08mng 0/1 ImagePullBackOff 0 6s
    5. nginx-deployment-3066724191-eocby 0/1 ImagePullBackOff 0 6s

    注意:Deployment Controller将自动停止不良的升级,并将停止扩容新的ReplicaSet。这取决于您指定的rollingUpdate参数(具体为maxUnavailable )。默认情况下,Kubernetes将maxUnavailable设为1,而spec.replicas也为1,因此,如果您没有关注过这些参数设置,则默认情况下,您的Deployment可能100%不可用!这将在未来版本的Kubernetes中修复。

    1. $ kubectl describe deployment
    2. Name: nginx-deployment
    3. Namespace: default
    4. CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700
    5. Labels: app=nginx
    6. Selector: app=nginx
    7. Replicas: 2 updated | 3 total | 2 available | 2 unavailable
    8. StrategyType: RollingUpdate
    9. MinReadySeconds: 0
    10. RollingUpdateStrategy: 1 max unavailable, 1 max surge
    11. OldReplicaSets: nginx-deployment-1564180365 (2/2 replicas created)
    12. NewReplicaSet: nginx-deployment-3066724191 (2/2 replicas created)
    13. Events:
    14. FirstSeen LastSeen Count From SubobjectPath Type Reason Message
    15. --------- -------- ----- ---- ------------- -------- ------ -------
    16. 1m 1m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3
    17. 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1
    18. 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2
    19. 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2
    20. 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0
    21. 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3
    22. 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1
    23. 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-1564180365 to 2
    24. 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 2

    为解决以上问题,我们需要回滚到以前稳定版本的Deployment。

    检查Deployment的升级历史记录

    首先,检查此Deployment的修订版本:

    1. $ kubectl rollout history deployment/nginx-deployment
    2. deployments "nginx-deployment"
    3. REVISION CHANGE-CAUSE
    4. 1 kubectl create -f docs/user-guide/nginx-deployment.yaml --record
    5. 2 kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
    6. 3 kubectl set image deployment/nginx-deployment nginx=nginx:1.91

    因为我们在创建此Deployment时,使用--record 记录了命令,所以我们能够轻松看到我们在每个版本中所做的更改。

    要进一步查看每个版本的详细信息,请运行:

    1. $ kubectl rollout history deployment/nginx-deployment --revision=2
    2. deployments "nginx-deployment" revision 2
    3. Labels: app=nginx
    4. pod-template-hash=1159050644
    5. Annotations: kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
    6. Containers:
    7. nginx:
    8. Image: nginx:1.9.1
    9. Port: 80/TCP
    10. QoS Tier:
    11. cpu: BestEffort
    12. memory: BestEffort
    13. Environment Variables: <none>
    14. No volumes.

    回滚到以前的版本

    现在我们决定:撤消当前的升级并回滚到以前的版本:

    1. $ kubectl rollout undo deployment/nginx-deployment
    2. deployment "nginx-deployment" rolled back

    或者,可通过--to-revision 参数指定回滚到特定修订版本:

    1. $ kubectl rollout undo deployment/nginx-deployment --to-revision=2
    2. deployment "nginx-deployment" rolled back

    有关回滚命令相关的信息,详见 。

    现在,Deployment就会回滚到以前的稳定版本。如下可知,Deployment Controller会生成DeploymentRollback 事件。

    1. $ kubectl get deployment
    2. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
    3. nginx-deployment 3 3 3 3 30m
    4. $ kubectl describe deployment
    5. Name: nginx-deployment
    6. Namespace: default
    7. CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700
    8. Labels: app=nginx
    9. Selector: app=nginx
    10. Replicas: 3 updated | 3 total | 3 available | 0 unavailable
    11. StrategyType: RollingUpdate
    12. MinReadySeconds: 0
    13. RollingUpdateStrategy: 1 max unavailable, 1 max surge
    14. OldReplicaSets: <none>
    15. NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created)
    16. Events:
    17. FirstSeen LastSeen Count From SubobjectPath Type Reason Message
    18. --------- -------- ----- ---- ------------- -------- ------ -------
    19. 30m 30m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3
    20. 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1
    21. 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2
    22. 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2
    23. 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0
    24. 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 2
    25. 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1
    26. 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-1564180365 to 2
    27. 2m 2m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-3066724191 to 0
    28. 2m 2m 1 {deployment-controller } Normal DeploymentRollback Rolled back deployment "nginx-deployment" to revision 2
    29. 29m 2m 2 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3

    可使用如下命令伸缩Deployment:

    1. $ kubectl scale deployment nginx-deployment --replicas=10
    2. deployment "nginx-deployment" scaled

    假设您的群集启用了 horizontal pod autoscaling 功能,您可以为Deployment设置一个autoscaler,并根据现有Pod的CPU利用率,选择要运行的Pod的最小和最大个数。

    1. $ kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
    2. deployment "nginx-deployment" autoscaled

    Proportional scaling(比例缩放)

    RollingUpdate Deployment支持同时运行一个应用程序的多个版本。当您或autoscaler伸缩一个正处于升级中(正在进行或暂停)的RollingUpdate Deployment时,Deployment Controller就会平衡现有的、正在活动的ReplicaSet(ReplicaSet with Pod)中新增的副本,以减轻风险。 这称为比例缩放

    例如,您正在运行一个具有10个副本的Deployment,=3, maxUnavailable=2。

    1. $ kubectl get deploy
    2. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE

    你更新到一个新的镜像,该镜像在集群内部无法找到。

    1. $ kubectl set image deploy/nginx-deployment nginx=nginx:sometag
    2. deployment "nginx-deployment" image updated

    镜像使用ReplicaSet nginx-deployment-1989198191开始升级,但是由于上面设置了maxUnavailable=2,升级将被阻塞。

    然后,发起一个新的Deployment扩容请求。autoscaler将Deployment副本增加到15个。Deployment Controller需要决定在哪里添加这个5个新副本。如果我们不使用比例缩放,那么5个副本都将会被添加到新的ReplicaSet中。使用比例缩放,则新添加的副本将传播到所有ReplicaSet中。较大比例会被加入到有更多的副本的ReplicaSet,较低比例会被加入到较少的副本的ReplicaSet。剩余部分将添加到具有最多副本的ReplicaSet中。具有零个副本的ReplicaSet不会被扩容。

    在上面的示例中,3个副本将被添加到旧ReplicaSet中,2个副本将添加到新ReplicaSet中。升级进程最终会将所有副本移动到新的ReplicaSet中,假设新副本变为健康状态。

    1. $ kubectl get deploy
    2. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
    3. nginx-deployment 15 18 7 8 7m
    4. $ kubectl get rs
    5. NAME DESIRED CURRENT READY AGE
    6. nginx-deployment-1989198191 7 7 0 7m
    7. nginx-deployment-618515232 11 11 11 7m

    暂停与恢复Deployment

    在触发一个或多个更新之前,您可以暂停Deployment,然后恢复。这将允许您在暂停和恢复之间应用多个补丁,而不会触发不必要的升级。

    例如,使用刚刚创建的Deployment:

    1. $ kubectl get deploy
    2. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
    3. nginx 3 3 3 3 1m
    4. $ kubectl get rs
    5. NAME DESIRED CURRENT READY AGE
    6. nginx-2142116321 3 3 3 1m

    通过运行以下命令暂停:

    1. $ kubectl rollout pause deployment/nginx-deployment
    2. deployment "nginx-deployment" paused

    然后升级Deployment的镜像:

    1. $ kubectl set image deploy/nginx-deployment nginx=nginx:1.9.1
    2. deployment "nginx-deployment" image updated

    请注意,并不会产生新的ReplicaSet:

    1. $ kubectl rollout history deploy/nginx-deployment
    2. deployments "nginx"
    3. REVISION CHANGE-CAUSE
    4. 1 <none>
    5. $ kubectl get rs
    6. NAME DESIRED CURRENT READY AGE
    7. nginx-2142116321 3 3 3 2m

    您可以根据需要进行多次更新,例如,更新将要使用的资源:

    1. $ kubectl set resources deployment nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
    2. deployment "nginx-deployment" resource requirements updated

    在暂停之前,Deployment的初始状态将继续执行其功能;只要Deployment暂停,Deployment的更新将不会有任何影响。

    最终,恢复Deployment并观察一个新的ReplicaSet提供了所有新的更新:

    1. $ kubectl rollout resume deploy/nginx-deployment
    2. deployment "nginx" resumed
    3. $ kubectl get rs -w
    4. NAME DESIRED CURRENT READY AGE
    5. nginx-2142116321 2 2 2 2m
    6. nginx-3926361531 2 2 0 6s
    7. nginx-3926361531 2 2 1 18s
    8. nginx-2142116321 1 2 2 2m
    9. nginx-2142116321 1 2 2 2m
    10. nginx-3926361531 3 2 1 18s
    11. nginx-3926361531 3 2 1 18s
    12. nginx-3926361531 3 3 1 18s
    13. nginx-3926361531 3 3 2 19s
    14. nginx-2142116321 0 1 1 2m
    15. nginx-2142116321 0 1 1 2m
    16. nginx-2142116321 0 0 0 2m
    17. nginx-3926361531 3 3 3 20s
    18. ^C
    19. $ kubectl get rs
    20. NAME DESIRED CURRENT READY AGE
    21. nginx-2142116321 0 0 0 2m
    22. nginx-3926361531 3 3 3 28s

    注意:恢复暂停的Deployment之前,您无法回滚。

    Deployment状态

    Deployment在其生命周期中有各种状态。在升级新ReplicaSet时是 ,也可以是 complete 或 状态。

    Progressing Deployment(进行中的Deployment)

    当执行以下任务之一时,Kubernetes将Deployment标记为progressing

    • Deployment创建一个新ReplicaSet。
    • 该Deployment正在扩容其最新ReplicaSet。
    • Deployment正在缩容其旧版ReplicaSet。
    • 新Pod已准备就绪或可用(Ready状态至少持续了 MinReadySeconds 时间)。

    您可使用kubectl rollout status 监视部署的进度。

    Deployment具有以下特点时候,Kubernetes将Deployment标记为complete

    • 与Deployment相关联的所有副本都已被更新为您所指定的最新版本,也就是说您所请求的任何更新都已完成。
    • 与Deployment相关联的所有副本都可用。
    • Deployment的旧副本都不运行。

    可使用kubectl rollout status 来检查Deployment是否已经完成。如果升级成功,则kubectl rollout status 将会返回一个为零的退出代码。

    1. $ kubectl rollout status deploy/nginx-deployment
    2. Waiting for rollout to finish: 2 of 3 updated replicas are available...
    3. deployment "nginx" successfully rolled out
    4. $ echo $?
    5. 0

    Failed Deployment(失败的Deployment)

    您的Deployment在尝试部署最新ReplicaSet的过程中可能会阻塞,永远也无法完成。这可能是由于以下一些因素造成的:

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

    您可以检测到这种情况的一种方法,是在Deployment spec中指定一个期限参数:( )。 spec.progressDeadlineSeconds 表示Deployment Controller等待多少秒后认为Deployment进程已停止。

    1. $ kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'
    2. "nginx-deployment" patched

    一旦超过截止时间,Deployment Controller就会将一个DeploymentCondition添加到Deployment的status.conditions ,DeploymentCondition包含以下属性:

    • Type=Progressing
    • Status=False
    • Reason=ProgressDeadlineExceeded

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

    注意:除报告Reason=ProgressDeadlineExceeded 以外,Kubernetes不会对停滞的Deployment采取任何行动。 更高级别的协调者,可利用它并采取相应的行动,例如,将Deployment恢复到之前的版本。

    注意:如果暂停Deployment,Kubernetes不会根据您指定的截止时间检查进度。 您可以在升级过程中安全地暂停Deployment,然后再恢复,这样不会触发超过截止时间的条件。

    您的Deployments可能会遇到短暂的错误,这可能是由于您设置的超时时间偏低,或者可能是由于可被视为“短暂”的其他类型的错误。例如,配额不足。 如果您describe Deployment,将可看到以下部分的内容:

    1. $ kubectl describe deployment nginx-deployment
    2. <...>
    3. Conditions:
    4. Type Status Reason
    5. ---- ------ ------
    6. Available True MinimumReplicasAvailable
    7. Progressing True ReplicaSetUpdated
    8. ReplicaFailure True FailedCreate
    9. <...>

    如果运行kubectl get deployment nginx-deployment -o yaml ,则Deployment状态可能如下所示:

    1. status:
    2. availableReplicas: 2
    3. conditions:
    4. - lastTransitionTime: 2016-10-04T12:25:39Z
    5. lastUpdateTime: 2016-10-04T12:25:39Z
    6. message: Replica set "nginx-deployment-4262182780" is progressing.
    7. reason: ReplicaSetUpdated
    8. status: "True"
    9. type: Progressing
    10. - lastTransitionTime: 2016-10-04T12:25:42Z
    11. lastUpdateTime: 2016-10-04T12:25:42Z
    12. message: Deployment has minimum availability.
    13. reason: MinimumReplicasAvailable
    14. status: "True"
    15. type: Available
    16. - lastTransitionTime: 2016-10-04T12:25:39Z
    17. lastUpdateTime: 2016-10-04T12:25:39Z
    18. message: 'Error creating: pods "nginx-deployment-4262182780-" is forbidden: exceeded quota:
    19. object-counts, requested: pods=1, used: pods=3, limited: pods=2'
    20. reason: FailedCreate
    21. status: "True"
    22. type: ReplicaFailure
    23. observedGeneration: 3
    24. replicas: 2
    25. unavailableReplicas: 2

    最终,一旦Deployment进度超过了截止时间,Kubernetes将会更新状态以及导致Progressing的原因:

    1. Conditions:
    2. Type Status Reason
    3. ---- ------ ------
    4. Available True MinimumReplicasAvailable
    5. Progressing False ProgressDeadlineExceeded
    6. ReplicaFailure True FailedCreate

    可缩容Deployment、缩容正在运行的其他Controller或通过增加namespace中的配额,从而解决配额不足的问题。当您满足配额条件后,Deployment Controller就会完成升级,您将看到Deployment的状态更新为成功( Status=TrueReason=NewReplicaSetAvailable )。

    1. Conditions:
    2. Type Status Reason
    3. ---- ------ ------
    4. Progressing True NewReplicaSetAvailable

    Type=Available ,并且Status=True 表示您的Deployment具有最低可用性。 最低可用性由部署策略中指定的参数决定。 Type=Progressing ,并且 Status=True 表示您的Deployment正在升级中;正处于progressing状态;抑或已成功完成其进度,并且达到所需的最小可用新副本个数(请查看特定状态的原因——本例中,Reason=NewReplicaSetAvailable 意味着Deployment完成)。

    可使用kubectl rollout status 来检查Deployment进程是否失败。如果Deployment已超过截止之间,则kubectl rollout status 将会返回非零的退出代码。

    操作失败的Deployment

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

    清理策略

    可在Deployment中设置.spec.revisionHistoryLimit 字段,从而指定该Deployment要保留多少个旧版本ReplicaSet。 其余的将在后台垃圾收集。 默认情况下,所有修订历史都将被保留。在将来的版本中,默认是2。

    注意:明确将此字段设置为0将会导致清除Deployment的所有历史记录,这会导致Deployment无法回滚。

    Canary Deployment(金丝雀部署)

    如果要使用Deployment向一部分用户或服务器发布版本,则可以按照 描述的金丝雀模式,创建多个Deployment,每个Deployment对应各自的版本。

    编写Deployment Spec

    与所有其他Kubernetes配置一样,Deployment需要apiVersionkindmetadata 等字段。有关使用配置文件的一般信息,请参阅 deploying applications ,配置容器以及 文档。

    Deployment还需要一个 .spec section

    Pod Template

    .spec.template.spec 唯一必需的字段。

    .spec.template是一个 。它与 Pod 有完全相同的schema,除了它是嵌套的,并且没有apiVersionkind

    除了Pod必需的字段之外,Deployment中的Pod模板必须指定适当的标签和重启策略。对于标签,请确保不与其他Controller重叠。详见 )。

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

    副本

    .spec.replicas 是一个可选字段,用于指定期望的.spec.replicas 的数量,默认为1。

    选择器

    .spec.selector 是一个可选字段,指定此Deployment所关联的Pod的 。

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

    在API版本apps/v1beta2 中,如果未经设置,则.spec.selector.metadata.labels 不再默认与.spec.template.metadata.labels 相同。 所以,必须明确设定这些字段。 另请注意,在apps/v1beta2 中,.spec.selector 在Deployment创建后是不可变的。

    对于模板与.spec.template 不同,抑或副本总数超过.spec.replicas 定义的Pod,Deployment可能会终止这些Pod。如果Pod的数量小于所需的数量,它将会使用.spec.template 的定义启动新Pod。

    译者按:“模板与.spec.template 不同”的场景:Deployment先创建,然后修改YAML定义文件,升级镜像的版本。此时,旧Pod的镜像字段就与.spec.template 不同了

    注意:你不应该建立其他与该选择器相匹配的Pod,无论是直接创建,还是通过另一个Deployment创建,抑或通过另一个Controller创建(例如ReplicaSet或ReplicationController)。如果这样做,第一个Deployment将会认为是它创造了这些Pod。 Kubernetes并不会阻止你这么做。

    如果多个Controller的选择器发生重叠,Controller会发生冲突,并导致不正常的行为。

    .spec.strategy 指定使用新Pod代替旧Pod的策略。.spec.strategy.type 可有“Recreate”或“RollingUpdate” 两种取值。默认为“RollingUpdate”。

    Recreate Deployment

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

    Rolling Update Deployment(滚动更新Deployment)

    .spec.strategy.type==RollingUpdate 时,Deployment以 rolling update 的方式更新Pod。可指定maxUnavailablemaxSurge 控制滚动更新的过程。

    Max Unavailable

    .spec.strategy.rollingUpdate.maxUnavailable 是一个可选字段,用于指定在更新的过程中,不可用Pod的最大数量。该值可以是一个绝对值(例如5),也可以是期望Pod数量的百分比(例如10%)。通过百分比计算出来的绝对值会向下取整。如果 .spec.strategy.rollingUpdate.maxSurge是0,那么该值不能为0。默认值是25%。

    例如,此值被设置为30%,当滚动更新开始时,旧ReplicaSet会立即缩容到期望Pod数量的70%。一旦新的Pod进入Ready状态,老ReplicaSet可进一步缩容,然后扩容新ReplicaSet,确保在更新过程中,任何时候都会有至少70%的可用Pod。

    Max Surge

    .spec.strategy.rollingUpdate.maxSurge 是一个可选字段,用于指定在更新的过程中,超过Pod期望数量的最大数量。该值可以是一个绝对值(例如5),也可以是期望Pod数量的百分比(例如10%)。如果MaxUnavailable为0,该值不能为0。通过百分比计算出来的绝对值会绝对会向上取整。默认值是25%。

    例如,此值被设置为30%,当滚动更新开始时,新ReplicaSet会立即扩容, 新旧Pod的总数不超过期望Pod数量的130%。一旦老Pod已被杀死,新ReplicaSet可进一步扩容,确保在更新过程中,任何时候运行的Pod总数不超过期望Pod数量的130%。

    Progress Deadline Seconds

    .spec.progressDeadlineSeconds 是一个可选字段,用于指定表示Deployment Controller等待多少秒后认为Deployment进程已 ——表现为在资源状态中有: Type=ProgressingStatus=False,以及Reason=ProgressDeadlineExceeded 。Deployment Controller将继续重试该Deployment。在未来,一旦实现自动回滚,Deployment Controller观察到这种状况时,就会尽快回滚 Deployment。

    如需设置本字段,值必须大于.spec.minReadySeconds

    Min Ready Seconds

    .spec.minReadySeconds 是一个可选字段,用于指定新创建的Pod进入Ready状态(Pod的容器持续多少秒不发生崩溃,就被认为可用)的最小秒数。默认为0( Pod在Ready后就会被认为是可用状态)。要了解什么时候Pod会被认为已Ready,详见 Container Probes

    Rollback To

    在API版本extensions/v1beta1apps/v1beta1 中,.spec.rollbackTo 已被弃用,并且在API版本apps/v1beta2 中不再支持该字段。取而代之的是,建议使用kubectl rollout undo ,详见 。

    Revision History Limit(修订历史限制)

    Deployment的修订历史记录存储在它所控制的ReplicaSet内。

    .spec.revisionHistoryLimit 是一个可选字段,用于指定要保留的ReplicaSet数量,以便回滚。它的理想取值取决于新Deployment的频率和稳定性。默认情况下,所有老ReplicaSet都被保存,将资源存储在etcd 中,使用kubectl get rs 查询ReplicaSet信息。每个Deployment修订的配置都被存储在其ReplicaSet;因此,一旦旧ReplicaSet被删除,Deployment将无法回滚到那个修订版本。

    更具体地讲,将该字段设为零,意味着所有0副本的旧ReplicaSet将被清理。在这种情况下,一个新的Deployment无法回滚,因为其修订历史都被清除了。

    Paused

    是一个可选的布尔类型的字段,用于暂停和恢复Deployment。Deployment暂停和未暂停之间唯一的区别是:对暂停Deployment的PodTemplateSpec所做的任何更改,不会触发新的升级。当Deployment创建后,默认情况下不会暂停。

    Deployment的替代方案

    kubectl滚动更新

    Kubectl rolling update 以类似的方式更新Pod和ReplicationControllers。但是建议使用Deployment,因为是声明式、服务器端的,并有额外的功能,例如滚动更新完成后可回滚到历史版本。

    原文