Edit This Page

对 DaemonSet 执行滚动更新

本文介绍了如何对 DaemonSet 执行滚动更新。

准备开始

  • Kubernetes 1.6 或者更高版本中才支持 DaemonSet 滚动更新功能。

DaemonSet 更新策略

DaemonSet 有两种更新策略:

  • OnDelete: 使用 OnDelete 更新策略时,在更新 DaemonSet 模板后,只有当您手动删除老的 DaemonSet pods 之后,新的 DaemonSet pods 才会被自动创建。跟 Kubernetes 1.6 以前的版本类似。
  • RollingUpdate: 这是默认的更新策略。使用 RollingUpdate 更新策略时,在更新 DaemonSet 模板后,老的 DaemonSet pods 将被终止,并且将以受控方式自动创建新的 DaemonSet pods。

执行滚动更新

要启用 DaemonSet 的滚动更新功能,必须设置 .spec.updateStrategy.typeRollingUpdate

您可能想设置.spec.updateStrategy.rollingUpdate.maxUnavailable (默认为 1) 和.spec.minReadySeconds (默认为 0)。

步骤 1: 检查 DaemonSet 的滚动更新策略

首先,检查 DaemonSet 的更新策略,确保已经将其设置为 RollingUpdate:

kubectl get ds/<daemonset-name> -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'

如果还没在系统中创建 DaemonSet,请使用以下命令检查 DaemonSet 的清单:

kubectl create -f ds.yaml --dry-run -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'

两个命令的输出都应该为:

RollingUpdate

如果输出不是 RollingUpdate,请返回并相应地修改 DaemonSet 对象或者清单。

步骤 2:使用 RollingUpdate 更新策略创建 DaemonSet

如果已经创建了 DaemonSet,则可以跳过该步骤并跳转到步骤 3。

验证 DaemonSet 清单的更新策略后,创建 DaemonSet:

kubectl create -f ds.yaml

或者,您打算使用 kubectl apply 更新 DaemonSet,请使用 kubectl apply 创建相同的 DaemonSet。

kubectl apply -f ds.yaml

步骤 3:更新 DaemonSet 模板

RollingUpdate DaemonSet .spec.template 的任何更新都将触发滚动更新。这可以通过几个不同的 kubectl 命令来完成。

声明式命令

如果您使用配置文件来更新 DaemonSets,请使用 kubectl apply:

kubectl apply -f ds-v2.yaml

命令式命令

如果您使用命令式命令来更新 DaemonSets,请使用kubectl edit 或者 kubectl patch:

kubectl edit ds/<daemonset-name>
kubectl patch ds/<daemonset-name> -p=<strategic-merge-patch>
只更新容器镜像

如果您只需要更新 DaemonSet 模板里的容器镜像,比如,.spec.template.spec.containers[*].image, 请使用 kubectl set image:

kubectl set image ds/<daemonset-name> <container-name>=<container-new-image>

步骤 4:查看滚动更新状态

最后,观察 DaemonSet 最新滚动更新的进度:

kubectl rollout status ds/<daemonset-name>

当滚动更新完成时,输出结果如下:

daemonset "<daemonset-name>" successfully rolled out

故障排查

DaemonSet 滚动更新卡住

有时,DaemonSet 滚动更新可能会卡住。可能原因如下:

一些节点资源用尽

由于新 DaemonSet pods 无法调度到至少一个节点时,滚动更新就会卡住。这可能是由于节点已经资源用尽

发生这种情况时,通过对 kubectl get nodes 和下面命令行的输出作比较,找出没有调度部署 DaemonSet pods 的节点:

kubectl get pods -l <daemonset-selector-key>=<daemonset-selector-value> -o wide

一旦找到这些节点,从节点上删除一些非 DaemonSet pods,为新的 DaemonSet pods 腾出空间。

说明: 当所删除的 pods 不受任何控制器管理,也不是多副本的 pods,上述操作将导致服务中断。 同时,上述操作也不会考虑 PodDisruptionBudget 所施加的约束。

滚动更新中断

如果最近的 DaemonSet 模板更新被破坏了,比如,容器处于崩溃循环状态或者容器镜像不存在(通常由于拼写错误),就会发生 DaemonSet 滚动更新中断。

要解决此问题,只需再次更新 DaemonSet 模板即可。以前不健康的滚动更新不会阻止新的滚动更新。

时钟偏差

如果在 DaemonSet 中指定了 .spec.minReadySeconds,主节点和工作节点之间的时钟偏差会使 DaemonSet 无法检测到正确的滚动更新进度。

接下来