Kubernetes运维之容器编排Deployment更新机制

Deployment更新机制

Deployment控制器支持两种更新策略:滚动更新(rolling update)和重新创建(recreate),默认为滚动更新。

滚动升级是默认的更新策略,它在删除一部分旧版本Pod资源的同时,补充创建一部分新版本的Pod对象进行应用升级,其优势是升级期间,容器中应用提供的服务不会中断,但要求应用程序能够应对新旧版本同时工作的情形,例如新旧版本兼容同一个数据库方案等。不过,更新操作期间,不同客户端得到的响应内容可能会来自不同版本的应用。

Deployment控制器的滚动更新操作并非在同一个ReplicaSet控制器对象下删除并创建Pod资源,而是将它们分置于两个不同的控制器之下:旧控制器的Pod对象数量不断减少的同时,新控制器的Pod对象数量不断增加,直到旧控制器不再拥有Pod对象,而新控制器的副本数量变得完全符合期望值为止,如图所示。

滚动更新时,应用升级期间还要确保可用的Pod对象数量不低于某阈值以确保可以持续处理客户端的服务请求,变动的方式和Pod对象的数量范围将通过spec.strategy.rollingUpdate.maxSurge和spec.strategy.rollingUpdate.maxUnavailable两个属性协同进行定义

  • maxSurge:指定升级期间存在的总Pod对象数量最多可超出期望值的个数,其值可以是0或正整数,也可以是一个期望值的百分比;例如,如果期望值为3,当前的属性值为1,则表示Pod对象的总数不能超过4个
  • maxUnavailable:升级期间正常可用的Pod副本数(包括新旧版本)最多不能低于期望数值的个数,其值可以是0或正整数,也可以是一个期望值的百分比;默认值为1,该值意味着如果期望值是3,则升级期间至少要有两个Pod对象处于正常提供服务的状态。

Deployment更新

创建deploy资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
  1. 先来更新 nginx Pod 以使用 nginx:1.16.1 镜像,而不是 nginx:1.14.2 镜像。

    1
    2
    kubectl --record deployment.apps/nginx-deployment set image \
    deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1

    或者使用下面的命令:

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

    输出类似于:

    1
    deployment.apps/nginx-deployment image updated

    升级过程

  2. 要查看上线状态,运行

    1
    kubectl rollout status deployment/nginx-deployment

    输出类似于:

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

    或者

    1
    deployment "nginx-deployment" successfully rolled out
  3. 通过kubectl get rs命令,以可清晰地看到滚动升级的过程

回滚 Deployment

有时,你可能想要回滚 Deployment;例如,当 Deployment 不稳定时(例如进入反复崩溃状态)。 默认情况下,Deployment 的所有上线记录都保留在系统中,以便可以随时回滚 (你可以通过修改修订历史记录限制来更改这一约束)。

  1. 首先,检查 Deployment 修订历史:

    1
    kubectl rollout history deployment.v1.apps/nginx-deployment

    输出类似于:

    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 添加注解。
    • 追加 --record 命令行标志以保存正在更改资源的 kubectl 命令。
    • 手动编辑资源的清单。
  2. 要查看修订历史的详细信息,运行:

    1
    kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2
  3. 假定现在你已决定撤消当前上线并回滚到以前的修订版本:

    通过使用 --to-revision 来回滚到特定修订版本:

    1
    kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2

    检查回滚是否成功以及 Deployment 是否正在运行,运行:

    1
    kubectl get deployment nginx-deployment

缩放 Deployment

你可以使用如下指令缩放 Deployment:

1
kubectl scale deployment.v1.apps/nginx-deployment --replicas=10

输出类似于:

1
deployment.apps/nginx-deployment scaled

假设集群启用了Pod 的水平自动缩放, 你可以为 Deployment 设置自动缩放器,并基于现有 Pods 的 CPU 利用率选择 要运行的 Pods 个数下限和上限。

1
kubectl autoscale deployment.v1.apps/nginx-deployment --min=10 --max=15 --cpu-percent=80

输出类似于:

1
deployment.apps/nginx-deployment scaled

paused(暂停的)

.spec.paused 是用于暂停和恢复 Deployment 的可选布尔字段。 暂停的 Deployment 和未暂停的 Deployment 的唯一区别是,Deployment 处于暂停状态时, PodTemplateSpec 的任何修改都不会触发新的上线。 Deployment 在创建时是默认不会处于暂停状态。

1
kubectl rollout pause deployment nginx-stop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-stop
labels:
app: nginx
spec:
paused: true
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

恢复

1
kubectl rollout resume deployment nginx-stop