--- reviewers: - janetkuo title: 对 DaemonSet 执行滚动更新 content_template: templates/task --- {{% capture overview %}} 本文介绍了如何对 DaemonSet 执行滚动更新。 {{% /capture %}} {{% capture prerequisites %}} * Kubernetes 1.6 或者更高版本中才支持 DaemonSet 滚动更新功能。 {{% /capture %}} {{% capture steps %}} ## DaemonSet 更新策略 DaemonSet 有两种更新策略: * OnDelete: 使用 `OnDelete` 更新策略时,在更新 DaemonSet 模板后,只有当您手动删除老的 DaemonSet pods 之后,新的 DaemonSet pods *才会*被自动创建。跟 Kubernetes 1.6 以前的版本类似。 * RollingUpdate: 这是默认的更新策略。使用 `RollingUpdate` 更新策略时,在更新 DaemonSet 模板后,老的 DaemonSet pods 将被终止,并且将以受控方式自动创建新的 DaemonSet pods。 ## 执行滚动更新 要启用 DaemonSet 的滚动更新功能,必须设置 `.spec.updateStrategy.type` 为 `RollingUpdate`。 您可能想设置[`.spec.updateStrategy.rollingUpdate.maxUnavailable`](/docs/concepts/workloads/controllers/deployment/#max-unavailable) (默认为 1) 和[`.spec.minReadySeconds`](/docs/concepts/workloads/controllers/deployment/#min-ready-seconds) (默认为 0)。 ### 步骤 1: 检查 DaemonSet 的滚动更新策略 首先,检查 DaemonSet 的更新策略,确保已经将其设置为 `RollingUpdate`: ```shell kubectl get ds/ -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}' ``` 如果还没在系统中创建 DaemonSet,请使用以下命令检查 DaemonSet 的清单: ```shell kubectl create -f ds.yaml --dry-run -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}' ``` 两个命令的输出都应该为: ```shell RollingUpdate ``` 如果输出不是 `RollingUpdate`,请返回并相应地修改 DaemonSet 对象或者清单。 ### 步骤 2:使用 `RollingUpdate` 更新策略创建 DaemonSet 如果已经创建了 DaemonSet,则可以跳过该步骤并跳转到步骤 3。 验证 DaemonSet 清单的更新策略后,创建 DaemonSet: ```shell kubectl create -f ds.yaml ``` 或者,您打算使用 `kubectl apply` 更新 DaemonSet,请使用 `kubectl apply` 创建相同的 DaemonSet。 ```shell kubectl apply -f ds.yaml ``` ### 步骤 3:更新 DaemonSet 模板 对 `RollingUpdate` DaemonSet `.spec.template` 的任何更新都将触发滚动更新。这可以通过几个不同的 `kubectl` 命令来完成。 #### 声明式命令 如果您使用[配置文件](/docs/concepts/overview/object-management-kubectl/declarative-config/)来更新 DaemonSets,请使用 `kubectl apply`: ```shell kubectl apply -f ds-v2.yaml ``` #### 命令式命令 如果您使用[命令式命令](/docs/concepts/overview/object-management-kubectl/imperative-command/)来更新 DaemonSets,请使用`kubectl edit` 或者 `kubectl patch`: ```shell kubectl edit ds/ ``` ```shell kubectl patch ds/ -p= ``` ##### 只更新容器镜像 如果您只需要更新 DaemonSet 模板里的容器镜像,比如,`.spec.template.spec.containers[*].image`, 请使用 `kubectl set image`: ```shell kubectl set image ds/ = ``` ### 步骤 4:查看滚动更新状态 最后,观察 DaemonSet 最新滚动更新的进度: ```shell kubectl rollout status ds/ ``` 当滚动更新完成时,输出结果如下: ```shell daemonset "" successfully rolled out ``` ## 故障排查 ### DaemonSet 滚动更新卡住 有时,DaemonSet 滚动更新可能会卡住。可能原因如下: #### 一些节点资源用尽 由于新 DaemonSet pods 无法调度到至少一个节点时,滚动更新就会卡住。这可能是由于节点已经[资源用尽](/docs/tasks/administer-cluster/out-of-resource/)。 发生这种情况时,通过对 `kubectl get nodes` 和下面命令行的输出作比较,找出没有调度部署 DaemonSet pods 的节点: ```shell kubectl get pods -l = -o wide ``` 一旦找到这些节点,从节点上删除一些非 DaemonSet pods,为新的 DaemonSet pods 腾出空间。 {{< note >}} 当所删除的 pods 不受任何控制器管理,也不是多副本的 pods,上述操作将导致服务中断。 同时,上述操作也不会考虑 [PodDisruptionBudget](/docs/tasks/configure-pod-container/configure-pod-disruption-budget/) 所施加的约束。 {{< /note >}} #### 滚动更新中断 如果最近的 DaemonSet 模板更新被破坏了,比如,容器处于崩溃循环状态或者容器镜像不存在(通常由于拼写错误),就会发生 DaemonSet 滚动更新中断。 要解决此问题,只需再次更新 DaemonSet 模板即可。以前不健康的滚动更新不会阻止新的滚动更新。 #### 时钟偏差 如果在 DaemonSet 中指定了 `.spec.minReadySeconds`,主节点和工作节点之间的时钟偏差会使 DaemonSet 无法检测到正确的滚动更新进度。 {{% /capture %}} {{% capture whatsnext %}} * 查看[任务: 在 DaemonSet 上执行回滚](/docs/tasks/manage-daemon/rollback-daemon-set/) * 查看[概念: 创建 DaemonSet 以适应现有的 DaemonSet pods](/docs/concepts/workloads/controllers/daemonset/) {{% /capture %}}