
1. 什么是DaemonSet为什么我们需要它在Kubernetes集群中DaemonSet是一种特殊的工作负载控制器它确保集群中的每个节点或符合特定条件的节点都运行一个Pod副本。与Deployment不同Deployment关注的是运行指定数量的Pod而DaemonSet关注的是每个节点都运行这个Pod。想象一下你管理着一个由50台服务器组成的Kubernetes集群。现在你需要在每个节点上运行日志收集代理如Fluentd在每个节点上部署监控代理如Prometheus Node Exporter在每个节点上运行存储守护进程如Ceph在每个节点上配置网络插件如Calico如果手动操作你需要登录每台服务器安装配置这些组件。而使用DaemonSet你只需要定义一个YAML文件Kubernetes就会自动帮你完成这些工作。当新节点加入集群时DaemonSet会立即在新节点上创建对应的Pod当节点被移除时对应的Pod也会被垃圾回收。2. DaemonSet的核心工作机制解析2.1 DaemonSet的调度逻辑DaemonSet的调度器不经过默认的kube-scheduler而是由DaemonSet控制器直接管理。当创建DaemonSet时控制器会监听集群中所有节点的状态变化对每个节点检查是否符合Pod模板中的nodeSelector和affinity规则对于符合条件的节点确保有且只有一个匹配的Pod在运行如果节点被标记为不可调度cordonedDaemonSet仍然会在该节点上运行Pod这与普通Pod行为不同2.2 与节点标签的交互DaemonSet可以通过nodeSelector选择特定节点。例如如果你有一组带有diskssd标签的节点可以这样配置apiVersion: apps/v1 kind: DaemonSet metadata: name: ssd-monitor spec: selector: matchLabels: name: ssd-monitor template: metadata: labels: name: ssd-monitor spec: nodeSelector: disk: ssd containers: - name: main image: ssd-monitor:v12.3 Pod模板更新与滚动升级当DaemonSet的Pod模板spec.template发生变化时控制器会按照以下策略更新现有Pod默认策略是RollingUpdate滚动更新可以配置maxUnavailable默认1也可以设置为OnDelete即只在手动删除旧Pod后才创建新Pod更新顺序默认是不确定的但可以通过.spec.updateStrategy.rollingUpdate.daemonSetSurge启用临时增量Pod3. 典型使用场景与实战示例3.1 集群存储守护进程以Rook Ceph为例需要在每个节点上运行OSD守护进程apiVersion: apps/v1 kind: DaemonSet metadata: name: rook-ceph-osd namespace: rook-ceph spec: selector: matchLabels: app: rook-ceph-osd template: metadata: labels: app: rook-ceph-osd spec: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet containers: - name: osd image: rook/ceph:v1.8 command: [/tini, --, /usr/local/bin/rook] args: [ceph, osd, start] volumeMounts: - name: devices mountPath: /dev volumes: - name: devices hostPath: path: /dev3.2 日志收集方案使用Fluentd收集节点日志的典型配置apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd namespace: logging labels: k8s-app: fluentd-logging spec: selector: matchLabels: name: fluentd template: metadata: labels: name: fluentd spec: tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: fluentd image: fluent/fluentd-kubernetes-daemonset:v1-debian-elasticsearch env: - name: FLUENT_ELASTICSEARCH_HOST value: elasticsearch.logging.svc.cluster.local volumeMounts: - name: varlog mountPath: /var/log - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true volumes: - name: varlog hostPath: path: /var/log - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers3.3 网络插件部署Calico网络插件的节点组件通常以DaemonSet形式部署apiVersion: apps/v1 kind: DaemonSet metadata: name: calico-node namespace: kube-system spec: selector: matchLabels: k8s-app: calico-node template: metadata: labels: k8s-app: calico-node spec: hostNetwork: true tolerations: - effect: NoSchedule operator: Exists containers: - name: calico-node image: calico/node:v3.20 env: - name: DATASTORE_TYPE value: kubernetes securityContext: privileged: true volumeMounts: - mountPath: /var/run/calico name: var-run-calico volumes: - name: var-run-calico hostPath: path: /var/run/calico4. 高级配置与疑难排查4.1 资源限制与调度优化虽然DaemonSet Pod会忽略节点的资源不足状态因为它们是系统关键组件但合理设置资源请求和限制仍然重要resources: limits: cpu: 2 memory: 2Gi requests: cpu: 500m memory: 512Mi对于关键DaemonSet建议设置priorityClassName: system-node-critical4.2 污点与容忍度配置要在master节点上运行DaemonSet Pod默认master有NoSchedule污点需要添加容忍度tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule对于存在特殊污点的节点可以这样配置tolerations: - key: special-node operator: Exists effect: NoSchedule4.3 常见问题排查问题1DaemonSet Pod没有在某些节点上创建排查步骤检查节点标签kubectl get nodes --show-labels检查DaemonSet的nodeSelector配置检查节点是否被标记为不可调度kubectl get nodes查看STATUS列检查DaemonSet事件kubectl describe daemonset name问题2DaemonSet Pod不断重启排查步骤查看Pod日志kubectl logs pod-name -p-p查看前一个容器的日志检查资源限制是否过小检查volume挂载是否正确检查必要的内核模块是否加载问题3滚动更新卡住解决方法检查maxUnavailable设置是否过小检查新版本镜像是否可正常启动可以临时设置updateStrategy为OnDelete进行调试5. 最佳实践与性能考量5.1 镜像大小优化由于DaemonSet会在每个节点上运行镜像下载会占用大量带宽。建议使用Alpine等小型基础镜像多阶段构建减少最终镜像大小在节点预拉取镜像使用DaemonSet预拉取镜像的DaemonSet5.2 启动顺序依赖如果DaemonSet Pod依赖节点上的其他服务如网络插件依赖kube-proxy可以通过initContainer实现等待逻辑initContainers: - name: wait-for-kube-proxy image: busybox:1.28 command: [sh, -c, while ! nslookup kube-dns.kube-system.svc.cluster.local; do sleep 2; done]5.3 监控与告警建议为DaemonSet配置以下监控每个节点上应有的Pod数量与实际运行数量的差异Pod重启次数监控资源使用率监控特别是CPU/内存Prometheus示例告警规则- alert: DaemonSetPodNotRunning expr: kube_daemonset_status_current_number_scheduled ! kube_daemonset_status_desired_number_scheduled for: 5m labels: severity: critical annotations: summary: DaemonSet {{ $labels.daemonset }} has uncheduled pods5.4 与Operator模式的结合对于复杂的守护进程如Ceph、Etcd推荐使用Operator管理DaemonSet。Operator可以处理守护进程的生命周期处理配置更新执行升级和回滚监控守护进程健康状态例如Ceph Operator会根据集群状态自动创建/删除OSD DaemonSet并处理配置更新。