Kubernetes DaemonSet:节点守护进程部署

花开有时
花开有时
发布时间:2026-09-09 | 2人浏览过
原创

理解 DaemonSet:为什么要让每个节点运行一个 Pod

DaemonSet 与 Deployment 的核心差异在于调度模型。Deployment 关注的是期望的副本总数,控制器会根据集群资源将 Pod 随机调度到可用节点上;而 DaemonSet 遵循按节点部署原则,其目标是确保集群中每一个或符合条件的节点上恰好运行一个 Pod 副本。这种机制天然契合日志采集、节点监控以及底层网络插件等场景,因为这些组件必须紧贴宿主机运行才能获取本地指标或接管网络。当新节点加入集群时,DaemonSet 控制器会自动感知并在该节点上创建对应的 Pod;反之,当节点被移除或标记为不可调度时,控制器也会自动回收该节点上的 Pod。理解这一生命周期与节点绑定的特性,是避免使用 Deployment 强行模拟节点级部署、导致资源浪费或监控盲区的关键前提。

用真实 Kubernetes 集群节点与 DaemonSet Pod 的运行界面截图,直观展示一个节点对应一个守护 Pod 的关系
DaemonSet 为每个符合条件的 Kubernetes 节点部署一个守护 Pod。

编写并部署 DaemonSet YAML:从 Pod 模板到 kubectl apply

编写 DaemonSet 的 YAML 清单时,需严格遵循 Kubernetes API 规范。apiVersion 固定为 apps/v1,kind 声明为 DaemonSet。核心在于 spec 下的 selector 与 template 字段:selector.matchLabels 定义了控制器管理的 Pod 集合,而 spec.template.metadata.labels 必须与 selector 完全一致,否则 API Server 会直接拒绝创建请求。此外,DaemonSet 的 selector 在对象创建后不可修改,这是由底层控制器逻辑决定的。以下是一个用于采集节点系统日志的示例:

apiVersion: apps/v1

kind: DaemonSet

metadata:

name: node-log-collector

namespace: kube-system

spec:

selector:

matchLabels:

app: log-collector

template:

metadata:

labels:

app: log-collector

spec:

containers:

- name: collector

image: fluent/fluentd:v1.14

volumeMounts:

- name: varlog

mountPath: /var/log

volumes:

- name: varlog

hostPath:

path: /var/log

编写完成后,通过 kubectl apply -f daemonset.yaml 提交至集群。控制器将立即根据模板在每个节点拉起 Pod,完成部署。

展示真实 DaemonSet YAML 文件与终端执行 kubectl apply 的操作截图,突出 selector、template 和 labels 的对应关系
真实 DaemonSet YAML 展示 selector、template、labels 与 nodeSelector 的对应关系。

控制部署范围:nodeSelector、Affinity 与 Tolerations

默认情况下,DaemonSet 会尝试在集群所有符合条件的节点上调度 Pod。但在生产环境中,我们往往需要精确控制部署范围。通过 nodeSelector 可以基于节点标签进行硬性过滤,例如仅将监控组件部署在带有 role=worker 标签的节点上。若需更灵活的调度策略,可使用 nodeAffinity 实现软性偏好或硬性要求。然而,仅配置选择器并不足以保证 Pod 成功运行,因为 Kubernetes 控制平面节点默认带有 NoSchedule 污点,专用 GPU 节点也可能被标记。若 DaemonSet 未配置对应的 tolerations,Pod 即使被创建也会处于 Pending 状态。例如,在 spec.template.spec 中添加 tolerations 配置,指定 key 为 node-role.kubernetes.io/control-plane 且 effect 为 NoSchedule,即可允许守护进程调度至 Master 节点。正确组合标签选择与污点容忍,是避免资源已创建却未在目标节点运行这一典型调度陷阱的必要手段。

展示 Kubernetes 节点标签、污点以及 DaemonSet Pod 调度到指定节点的真实界面或终端输出
流程图展示 nodeSelector 标签、节点可调度状态与 DaemonSet Pod 的节点选择关系。

验证运行状态与滚动更新:确认每个节点都部署成功

部署完成后,必须通过多维度命令验证实际运行状态。执行 kubectl get daemonset 可查看 DESIRED 期望节点数、CURRENT 已调度 Pod 数与 READY 健康就绪数。若三者数值一致,说明部署成功;若 READY 小于 DESIRED,则需进一步排查。使用 kubectl get pods -o wide 可直观核对每个节点是否确实分配了一个 Pod。当需要升级镜像时,直接修改 DaemonSet YAML 中的 image 字段并重新 apply,Kubernetes 会默认采用 RollingUpdate 策略,逐个节点替换旧 Pod 以保证服务连续性。若更新后出现异常,可通过 kubectl rollout undo daemonset 快速回滚至上一版本。务必牢记,kubectl apply 成功仅表示资源对象已写入 etcd,只有当 READY 计数追平且各节点 Pod 状态为 Running 时,才代表真正的节点级部署完成。

展示真实终端中 DaemonSet 状态、各节点 Pod 分布以及滚动更新过程的截图
真实 kubectl 终端输出展示 DaemonSet 创建后各节点期望与就绪 Pod 数量。

常见避坑:调度失败、资源不足与节点级权限

在实际运维中,DaemonSet 部署失败多源于调度与权限配置疏漏。首要排查点是标签与选择器是否严格匹配,以及节点污点是否被正确容忍。若 Pod 长期处于 Pending 状态,应执行 kubectl describe pod 查看 Events 区域,重点关注 FailedScheduling 提示。常见原因包括:节点剩余 CPU 或内存不足导致资源配额拒绝调度,或 nodeSelector 条件在集群中无对应节点。此外,DaemonSet 常使用 hostPath 挂载宿主机目录或开启 hostNetwork,这会带来安全风险与端口冲突隐患。例如,多个守护进程若绑定相同宿主机端口将直接启动失败。排查此类问题时,建议优先检查节点资源水位、确认挂载路径权限,并在测试环境验证网络策略。建立先查事件、再验资源、后审权限的标准化排障路径,可大幅缩短节点级组件的部署周期。

展示真实 Kubernetes Pod Pending/FailedScheduling 事件与 describe 输出,突出调度失败原因
真实 kubectl get 与 describe pod 输出展示 Pending 状态及节点调度排查过程。
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表