一、DaemonSet 有两种常见更新策略

DaemonSet 主要有两种更新方式:

  • OnDelete
  • RollingUpdate

这和 StatefulSet 很像,但应用场景又更偏节点基础设施。比如日志采集器、监控代理和 CNI 相关组件,通常都要求更新过程尽量稳、尽量可控。

二、OnDelete:先改模板,再手动删 Pod

OnDelete 的特点是保守。即使你更新了 DaemonSet 模板,旧 Pod 也不会自动替换,只有你手工删除某个 Pod,控制器才会在该节点上拉起新的版本。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx
spec:
  updateStrategy:
    type: OnDelete
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.12

把镜像改成新版本并替换对象后:

kubectl replace -f nginx-ds.yaml
kubectl get pods -l app=nginx -oyaml | grep image
kubectl delete pod nginx-vf4ch
kubectl get pods -l app=nginx -oyaml | grep image

你会看到:只有被删掉的那个 Pod 才会按新镜像重建,其他节点仍然维持旧版本。

三、RollingUpdate:更适合自动化推进

如果使用 RollingUpdate,DaemonSet 会自动逐步把所有节点上的 Pod 替换掉。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2

更新后直接执行:

kubectl replace -f nginx-ds.yaml
kubectl get pods -l app=nginx -oyaml | grep image

和 OnDelete 相比,它更省人工,但也意味着你需要对镜像质量、探针和节点兼容性更有信心。

四、DaemonSet 回滚看什么、怎么回

原文里通过连续修改镜像,演示了 DaemonSet 的版本历史和回滚流程。

先制造两次变更:

kubectl set image daemonset nginx nginx=nginx:1.9.1 --record
kubectl set image daemonset nginx nginx=nginx:1.16.1 --record

查看历史:

kubectl rollout history daemonset nginx
kubectl rollout history daemonset nginx --revision=12

回滚到上一版:

kubectl rollout undo daemonset nginx

回滚到指定版本:

kubectl rollout undo daemonset nginx --to-revision=11

再看底层版本对象:

kubectl get controllerrevision

这里的 ControllerRevision,就相当于 DaemonSet 和 StatefulSet 在底层记录模板历史的重要抓手。

五、生产里怎么选更稳

如果你更新的是节点基础组件,建议这样理解:

  • 先小范围节点验证,再全量滚动
  • 高风险组件优先考虑 OnDelete
  • 日常稳定组件可用 RollingUpdate 提高效率
  • 回滚命令要提前演练,不要等线上异常时再第一次使用

DaemonSet 的风险不在对象本身,而在于它天然覆盖多个节点。一旦更新策略选错,影响面会比普通业务 Deployment 大得多,所以“慢一点、稳一点”通常才是更专业的做法。