执行滚动更新

本页面介绍如何在 Google Kubernetes Engine 中为应用执行滚动更新。

概览

您可以执行滚动更新,以更新集群中工作负载的映像、配置、标签、注释和资源限制/请求。 滚动更新会逐步将您资源的 Pod 替换为新的 Pod,然后与可用资源一同在节点上进行调度。滚动更新旨在实现无需停机的工作负载更新。

以下对象表示 Kubernetes 工作负载。您可以通过更新其 Pod 模板来触发这些工作负载的滚动更新:

  • DaemonSets
  • Deployment(部署)
  • StatefulSet

其中每个对象都有一个 Pod 模板,由对象清单中的 spec: template 字段表示。Pod 模板字段包含控制器创建的用于实现所需状态或行为的 Pod 规范。您可以通过更新对象的 spec: template 触发更新“发布”

Pod 模板包括以下字段:

如需详细了解 Pod 模板,请参阅 PodTemplateSpec 文档。

扩缩资源或更新 Pod 模板之外的字段不会触发发布。

准备工作

在开始之前,请确保您已执行以下任务:

使用以下任一方法设定默认的 gcloud 设置:

  • 使用 gcloud init(如果您想要在系统引导下完成默认设置)。
  • 使用 gcloud config(如果您想单独设置项目 ID、区域和地区)。

使用 gcloud init

如果您收到 One of [--zone, --region] must be supplied: Please specify location 错误,请完成本部分。

  1. 运行 gcloud init 并按照说明操作:

    gcloud init

    如果您要在远程服务器上使用 SSH,请使用 --console-only 标志来防止命令启动浏览器:

    gcloud init --console-only
  2. 按照说明授权 gcloud 使用您的 Google Cloud 帐号。
  3. 创建新配置或选择现有配置。
  4. 选择 Google Cloud 项目。
  5. 选择默认的 Compute Engine 区域。

使用 gcloud config

  • 设置默认项目 ID
    gcloud config set project project-id
  • 如果您使用的是区域级集群,请设置默认计算区域
    gcloud config set compute/zone compute-zone
  • 如果您使用的是地区级集群,请设置默认计算地区
    gcloud config set compute/region compute-region
  • gcloud 更新到最新版本:
    gcloud components update

更新应用

以下部分介绍如何使用 Google Cloud Console 或 kubectl 更新应用。

kubectl set

您可以使用 kubectl set 更改对象的 imageresources(计算资源,如 CPU 和内存)或 selector 字段。

例如,如需将 Deployment 从 nginx 版本 1.7.9 更新为 1.9.1,请运行以下命令:

kubectl set image deployment nginx nginx=nginx:1.9.1

kubectl set image 命令一次只更新一个 Deployment Pod 的 nginx 映像。

再举一例,如需设置 Deployment 的资源请求和限制:

kubectl set resources deployment nginx --limits cpu=200m,memory=512Mi --requests cpu=100m,memory=256Mi

或者,删除部署的资源请求:

kubectl set resources deployment nginx --limits cpu=0,memory=0 --requests cpu=0,memory=0

kubectl apply

您可以使用 kubectl apply 通过应用新的或更新后的清单文件来更新对象。

如需应用新的清单文件,请运行以下命令:

kubectl apply -f [MANIFEST]

其中,[MANIFEST] 是更新的清单文件。

控制台

如需修改应用的实时配置,请执行以下步骤:

  1. 访问 Cloud Console 中的 Google Kubernetes Engine“工作负载”菜单。

    访问“工作负载”菜单

  2. 选择所需的工作负载。

  3. 点击修改

  4. 使用编辑器对对象的标签或 Pod 模板进行所需的更改。

  5. 点击保存

管理更新发布

您可以使用 kubectl rollout 在执行发布时对其进行检查,暂停和恢复发布、回滚更新以及查看对象的发布历史记录。

使用 kubectl rollout status 检查发布

您可以使用 kubectl rollout status 命令检查发布的状态。

例如,您可以通过运行以下命令来检查 nginx Deployment 的发布:

kubectl rollout status deployment nginx

输出类似于以下内容:

Waiting for rollout to finish: 2 out of 3 newreplicas have been updated...
deployment "nginx" successfully rolled out

发布成功后,运行 kubectl get deployment nginx 以验证其所有 Pod 都在运行。输出类似于以下内容:

NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx              3         3         3            3           36s

暂停和恢复发布

您可以使用 kubectl rollout pause 暂停发布。

例如,如需暂停 nginx Deployment 的发布,请运行以下命令:

kubectl rollout pause deployment nginx

如需恢复发布,请运行以下命令:

kubectl rollout resume deployment nginx

使用 kubectl rollout history 查看发布历史记录

您可以使用 kubectl rollout history 查看对象的发布历史记录。

例如,如需查看 nginx Deployment 的发布历史记录,请运行以下命令:

kubectl rollout history deployment nginx

如需查看第三个修订版本的历史记录,请运行以下命令:

kubectl rollout history deployment nginx --revision 3

使用 kubectl rollout undo 回滚更新

您可以使用 kubectl rollout undo 命令回滚对象的发布。

例如,如需回滚到先前版本的 nginx Deployment,请运行以下命令:

kubectl rollout undo deployments nginx

或者,如需回滚到 Deployment 的第三个修订版本,请运行以下命令:

kubectl rollout undo deployment nginx --to-revision 3

StatefulSet 和 DaemonSet 的注意事项

Kubernetes 1.7 版后的 StatefulSet 和 Kubernetes 1.6 版后的 DaemonSet 使用一种更新策略来配置和停用对其 Pod 的容器、标签、资源请求/限制以及注释的自动滚动更新。此更新策略使用 spec.updateStrategy 字段进行配置。

spec.updateStrategy.type 字段接受 OnDeleteRollingUpdate 作为值。

如果未指定 spec.updateStrategy.type,则默认行为是 OnDeleteOnDelete 可防止控制器自动更新其 Pod。您必须手动删除 Pod,以使控制器创建新 Pod 来反映您的更改。如果您希望手动更新 Pod,则 OnDelete 非常有用。

RollingUpdate 实现 StatefulSet 中的 Pod 的自动滚动更新。RollingUpdate 使控制器删除并重新创建其每个 Pod,并且一次只能处理一个 Pod。在更新的 Pod 运行并就绪之后,控制器才会更新其上一个 Pod。

StatefulSet 控制器以反向顺序更新所有 Pod,同时遵循 StatefulSet 保证规则。

使用 RollingUpdate 策略

您可以使用 RollingUpdate 策略自动更新 StatefulSet 或 DaemonSet 中的所有 Pod。

例如,要修补 web StatefulSet 以应用 RollingUpdate 策略,请运行以下命令:

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}'

接下来,对 StatefulSet 的 spec.template 进行更改。例如,您可以使用 kubectl set 更改容器映像。在以下示例中,web StatefulSet 的设置会使其 nginx 容器运行 nginx-slim:0.7 映像:

kubectl set image statefulset web nginx=nginx-slim:0.7

如需检查运行 nginx 容器的 StatefulSet 中的 Pod 是否正在更新,请运行以下命令:

kubectl get pods -l app=nginx -w

输出类似于以下内容:

NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          7m
web-1     1/1       Running   0          7m
web-2     1/1       Running   0          8m
web-2     1/1       Terminating   0         8m
web-2     1/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Terminating   0         8m
web-2     0/1       Pending   0         0s
web-2     0/1       Pending   0         0s
web-2     0/1       ContainerCreating   0         0s
web-2     1/1       Running   0         19s
web-1     1/1       Terminating   0         8m
web-1     0/1       Terminating   0         8m
web-1     0/1       Terminating   0         8m
web-1     0/1       Terminating   0         8m
web-1     0/1       Pending   0         0s
web-1     0/1       Pending   0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running   0         6s
web-0     1/1       Terminating   0         7m
web-0     1/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Terminating   0         7m
web-0     0/1       Pending   0         0s
web-0     0/1       Pending   0         0s
web-0     0/1       ContainerCreating   0         0s
web-0     1/1       Running   0         10s

StatefulSet 中的 Pod 以反向顺序更新。StatefulSet 控制器终止每个 Pod,并在更新下一个 Pod 之前等待它转换为“正在运行且就绪”状态。

RollingUpdate 进行分区

您可以指定 StatefulSet 的 RollingUpdate 字段的 partition 参数。

如果您指定 partition,则所有序号大于或等于 partition 值的 Pod 都会更新。序号小于 partition 值的所有 Pod 都不会更新,即使它们被删除,在重新创建时也会使用以前的版本。

如果 partition 值大于其 replicas 数,则更新不会传播到其 Pod。如果要模拟更新、发布 Canary 版或进行阶段发布,分区都非常有用。

例如,如需对 web StatefulSet 进行分区,请运行以下命令:

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}'

这会导致更新序号大于等于 3 的 Pod 进行更新。

DaemonSet 的 maxUnavailable 参数

DaemonSet 的可选 maxUnavailable 参数是其 rollingUpdate 字段的子元素。

maxUnavailable 确定更新期间不可用的 DaemonSet Pod 的最大数量。如果省略,则默认值为 1。该值不能为 0,但可以是绝对数或百分比。

使用 OnDelete 策略进行更新

如果您希望手动更新 StatefulSet 或 DaemonSet,则可以忽略 spec.updateStrategy 字段,这会指示控制器使用 OnDelete 策略。

如需更新使用 OnDelete 策略的控制器,必须在更改其 Pod 模板后手动删除其 Pod。

例如,您可以将 web StatefulSet 设置为使用 nginx-slim:0.7 映像:

kubectl set image statefulset web nginx=nginx-slim:0.7

然后,如需删除第一个 web Pod,请运行以下命令:

kubectl delete pod web-0

如需在 StatefulSet 重新创建 Pod 并将其转换为“正在运行且就绪”状态的过程中进行观察,请运行以下命令:

kubectl get pod web-0 -w

此命令的输出应类似于以下内容:

NAME      READY     STATUS               RESTARTS   AGE
web-0     1/1       Running              0          54s
web-0     1/1       Terminating          0         1m
web-0     0/1       Terminating          0         1m
web-0     0/1       Terminating          0         1m
web-0     0/1       Terminating          0         1m
web-0     0/1       Pending              0         0s
web-0     0/1       Pending              0         0s
web-0     0/1       ContainerCreating    0         0s
web-0     1/1       Running              0         3s

更新作业

更新作业的配置时,新作业及其 Pod 将使用新配置运行。更新作业后,如果需要,您必须手动删除旧作业及其 Pod。

如需删除一个 Job 及其所有 Pod,请运行以下命令:

kubectl delete job my-job

如需删除一个 Job 但保持其 Pod 继续运行,请指定 --cascade=false 标志:

kubectl delete job my-job --cascade=false

您还可以运行 kubectl describe deployment nginx,从而生成有关 Deployment 的更多信息。

后续步骤