Kubernetes DaemonSet 详细介绍

Kubernetes DaemonSet 详细介绍

文章目录

    • [Kubernetes DaemonSet 详细介绍](#Kubernetes DaemonSet 详细介绍)
      • [1. 主要用途](#1. 主要用途)
      • [2. 工作原理](#2. 工作原理)
      • [3. 调度机制](#3. 调度机制)
        • [3.1 nodeSelector](#3.1 nodeSelector)
        • [3.2 节点亲和性 (nodeAffinity)](#3.2 节点亲和性 (nodeAffinity))
        • [3.3 污点和容忍度 (Taints and Tolerations)](#3.3 污点和容忍度 (Taints and Tolerations))
      • [4. 创建与管理](#4. 创建与管理)
      • [5. Pod 调度细节](#5. Pod 调度细节)
      • [6. 更新策略](#6. 更新策略)
        • [6.1 RollingUpdate(默认)](#6.1 RollingUpdate(默认))
        • [6.2 OnDelete](#6.2 OnDelete)
      • [7. 回滚](#7. 回滚)
      • [8. 与 Deployment 的区别](#8. 与 Deployment 的区别)
      • [9. 常见用例示例](#9. 常见用例示例)
        • [9.1 在每个节点运行 Fluentd 收集日志](#9.1 在每个节点运行 Fluentd 收集日志)
        • [9.2 在每个节点运行 Node Exporter](#9.2 在每个节点运行 Node Exporter)
      • [10. 高级特性与注意事项](#10. 高级特性与注意事项)
      • [11. 总结](#11. 总结)

DaemonSet 是 Kubernetes 中一种重要的控制器资源,它确保在集群中的 所有(或部分)节点 上运行一个 Pod 的副本。当有新节点加入集群时,DaemonSet 会自动在该节点上创建指定的 Pod;当节点从集群中移除时,这些 Pod 也会被回收。删除 DaemonSet 将清理它之前创建的所有 Pod。

【冷知识】DaemonSet 的翻译:官方/技术文档中通常不翻译,如果硬要翻译,可以翻译为:守护进程集(借鉴了 Linux 系统中"守护进程"(Daemon)的概念,指在每个节点上长期运行的后台任务。这个翻译比较贴切地表达了它在每个节点上运行"守护"角色的含义。)

1. 主要用途

DaemonSet 通常用于部署那些需要在每个节点上都运行的后台支撑服务,典型的应用场景包括:

  • 日志收集:如 Fluentd、Logstash,用于采集每个节点的容器日志。
  • 监控代理:如 Prometheus Node Exporter、Datadog Agent,收集节点级别的指标。
  • 集群存储守护进程:如 GlusterFS、Ceph 的客户端 daemon,为节点提供持久化存储支持。
  • 网络插件 :如 Calico、Flannel 的节点代理(如 calico-nodeflanneld),实现节点网络互通。
  • 安全与合规:如运行节点扫描、入侵检测 agent。
  • 系统组件 :如 kube-proxy 本身也常以 DaemonSet 形式运行,确保每个节点都有网络代理。

2. 工作原理

DaemonSet 控制器运行在 Kubernetes 控制平面中,持续监控集群节点的状态。它的核心逻辑是:

  • 每当一个新节点添加到集群时,控制器检查该节点是否需要运行 DaemonSet 的 Pod(根据调度约束)。
  • 如果需要,且该 Pod 尚未在该节点上运行,控制器就会创建 Pod,并将其绑定到目标节点(绕过默认调度器)。
  • 当节点被删除时,控制器自动回收该节点上的对应 Pod。
  • 当 DaemonSet 被更新(如镜像版本变更)时,控制器根据更新策略逐步替换旧的 Pod。

3. 调度机制

DaemonSet 创建的 Pod 默认会被调度到所有节点上,但可以通过以下方式限制 Pod 运行的节点范围:

3.1 nodeSelector

在 DaemonSet 的 Pod 模板中设置 spec.nodeSelector,只有标签匹配的节点才会运行 Pod。

yaml 复制代码
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: my-daemon
spec:
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      nodeSelector:
        disktype: ssd      # 仅 disktype=ssd 的节点运行
      containers:
      - name: main
        image: myimage
3.2 节点亲和性 (nodeAffinity)

使用更灵活的节点亲和性规则,例如要求节点在某个区域,或优先选择某些节点。

yaml 复制代码
spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: topology.kubernetes.io/zone
                operator: In
                values:
                - us-east-1
3.3 污点和容忍度 (Taints and Tolerations)

如果节点设置了污点(Taint),DaemonSet 的 Pod 必须定义对应的容忍度(Toleration)才能在该节点上运行。这常用于隔离专用节点(如 GPU 节点、基础设施节点)。

yaml 复制代码
spec:
  template:
    spec:
      tolerations:
      - key: "dedicated"
        operator: "Equal"
        value: "gpu"
        effect: "NoSchedule"

4. 创建与管理

DaemonSet 使用 YAML 定义,结构类似于 Deployment,但没有 replicas 字段(副本数由节点数量决定)。关键字段:

  • apiVersion: apps/v1
  • kind: DaemonSet
  • metadata: 名称、标签等
  • spec:
    • selector: 选择器,必须与 Pod 模板的标签匹配。
    • template: Pod 模板,定义 Pod 的规范(容器、卷、环境变量等)。
    • updateStrategy: 更新策略(见下文)。
    • minReadySeconds: Pod 被认为可用的最短时间。
    • revisionHistoryLimit: 保留的历史版本数量。

创建 DaemonSet:

bash 复制代码
kubectl apply -f daemonset.yaml

查看 DaemonSet 状态:

bash 复制代码
kubectl get daemonsets
kubectl describe daemonset <name>

5. Pod 调度细节

DaemonSet 控制器在创建 Pod 时,会直接在 Pod 的 spec.nodeName 字段中指定目标节点,从而绕过 Kubernetes 调度器。这意味着:

  • 即使节点有资源压力、调度器不可用,DaemonSet 依然能尝试将 Pod 调度到节点上(但节点必须满足资源要求,否则 Pod 会处于 Pending 状态)。
  • 因此,DaemonSet 通常用于部署关键的系统级守护进程,它们应该尽量保证在节点上运行,除非明确排除。

6. 更新策略

DaemonSet 支持两种更新策略:

6.1 RollingUpdate(默认)

逐步替换旧的 Pod。可以通过 spec.updateStrategy.rollingUpdate.maxUnavailable 控制同时不可用的 Pod 数量(绝对值或百分比),避免全部中断。

yaml 复制代码
updateStrategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 1

当 DaemonSet 模板变化后,执行 kubectl rollout status daemonset/<name> 可以查看更新进度。

6.2 OnDelete

只有手动删除 Pod 时,才会创建新的 Pod。适用于需要逐个节点手动控制的场景。

yaml 复制代码
updateStrategy:
  type: OnDelete

7. 回滚

DaemonSet 支持版本回滚,类似于 Deployment:

bash 复制代码
# 查看历史版本
kubectl rollout history daemonset <name>

# 回滚到上一个版本
kubectl rollout undo daemonset <name>

# 回滚到指定版本
kubectl rollout undo daemonset <name> --to-revision=<revision>

8. 与 Deployment 的区别

特性 DaemonSet Deployment
副本数 自动匹配节点数量(受调度约束影响) 手动指定 replicas
Pod 分布 每个节点最多一个 Pod(通常每个节点一个) 可任意分布,多个 Pod 可在同一节点(若允许)
调度方式 控制器直接指定节点,绕过调度器 由调度器分配节点
典型用途 系统级守护进程(日志、监控、网络) 无状态应用(Web 服务、API)
节点扩展 新节点自动运行 Pod 需调度器分配,可能因资源不足而 pending

9. 常见用例示例

9.1 在每个节点运行 Fluentd 收集日志
yaml 复制代码
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
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:v1.14
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: containers
          mountPath: /var/lib/docker/containers
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: containers
        hostPath:
          path: /var/lib/docker/containers

这个例子还添加了容忍度,允许在 master 节点上运行,并使用 hostPath 挂载宿主机日志目录。

9.2 在每个节点运行 Node Exporter
yaml 复制代码
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      hostPID: true
      hostNetwork: true
      containers:
      - name: node-exporter
        image: prom/node-exporter:latest
        args:
        - --path.procfs=/host/proc
        - --path.sysfs=/host/sys
        volumeMounts:
        - name: proc
          mountPath: /host/proc
          readOnly: true
        - name: sys
          mountPath: /host/sys
          readOnly: true
      volumes:
      - name: proc
        hostPath:
          path: /proc
      - name: sys
        hostPath:
          path: /sys

这里使用了 hostPIDhostNetwork,让 Pod 能够访问宿主机的进程和网络命名空间。

10. 高级特性与注意事项

  • 资源预留:由于 DaemonSet Pod 可能运行在所有节点上,需要合理设置资源请求(requests)和限制(limits),避免资源竞争影响其他工作负载。
  • 优先级:可以为 DaemonSet Pod 设置优先级(PriorityClass),确保关键系统守护进程在节点资源紧张时优先调度。
  • 节点不可用 :如果节点处于 NotReady 状态,DaemonSet 不会立即删除该节点上的 Pod,而是等待节点恢复;但可以通过 spec.minReadySeconds 控制。
  • 容忍度与守护 :DaemonSet 通常需要容忍 node.kubernetes.io/not-readynode.kubernetes.io/unreachable 等常见污点,以确保在节点临时故障时 Pod 不会被驱逐(默认添加了 tolerationSeconds 为 300 秒的容忍度,Kubernetes 会自动注入这些容忍度给 DaemonSet 的 Pod)。

11. 总结

DaemonSet 是 Kubernetes 中针对节点级守护进程的专用控制器,它保证每个符合条件的节点上都运行一个 Pod 副本。理解其调度机制、更新策略和典型用例,有助于在集群中高效部署监控、日志、网络等基础组件,实现集群的自运维能力。

相关推荐
努力搬砖的咸鱼12 小时前
一个域名搞定前后端:用 Ingress 配置 / 和 /api 路由
微服务·云原生·容器·架构·kubernetes
Zhu_S W15 小时前
Kubernetes (K8s) 完全指南:Java 开发者的容器编排实践
java·容器·kubernetes
m0_5761164121 小时前
kubectl:k8s集群管理命令和Node节点
docker·容器·kubernetes
切糕师学AI1 天前
Kubernetes 完全指南:从集群架构到应用模型
容器·架构·kubernetes
糟糕喔1 天前
k8s运维-pod篇(1)
云原生·容器·kubernetes
期待のcode1 天前
Kubernetes与Minikube
运维·容器·kubernetes
悠闲蜗牛�1 天前
Kubernetes从零到集群:本地Minikube环境搭建与Spring Cloud微服务运维实战
spring cloud·微服务·kubernetes
AC赳赳老秦1 天前
2026云原生AI规模化趋势预测:DeepSeek在K8s集群中的部署与运维实战
运维·人工智能·云原生·架构·kubernetes·prometheus·deepseek
是小崔啊2 天前
叩丁狼k8s-运维管理
运维·容器·kubernetes