作为Kubernetes集群中的核心控制器之一,DaemonSet在集群管理中扮演着特殊而重要的角色。本文将通过实际案例带大家深入了解它的三种典型应用场景及其底层实现逻辑,手把手教你在生产环境中玩转DaemonSet。


1. 认识DaemonSet:它和Deployment有什么不同?

想象一下这样的场景:你的Kubernetes集群有50个节点,现在需要确保每个节点上都运行特定的服务程序。这时候Deployment就显得无能为力了——它关注的是应用副本的弹性扩展,而非节点级别的全覆盖。DaemonSet的设计初衷正是解决这种场景需求。

二者的核心差异在于调度策略:

  • Deployment:根据副本数进行调度,目标节点随机
  • DaemonSet:强制在满足条件的每个节点部署实例

当节点被添加或移除时,DaemonSet会自动进行Pod的新建或销毁。这种特性使其成为以下场景的理想选择:

  • 系统级后台服务(如监控Agent)
  • 硬件相关服务(如GPU驱动管理)
  • 网络组件(如CNI插件)

2. 节点监控实战:Prometheus Node Exporter部署

技术栈:Prometheus + Grafana + Kubernetes

假设我们需要收集所有Kubernetes节点的硬件指标,以下为完整的DaemonSet配置示例:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      hostNetwork: true   # 共享节点网络命名空间
      hostPID: true       # 访问节点进程树
      containers:
      - name: node-exporter
        image: prom/node-exporter:v1.3.1
        ports:
        - containerPort: 9100
          hostPort: 9100   # 固定端口映射
        resources:
          limits:
            cpu: 200m
            memory: 200Mi
        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

关键设计解析

  • 通过hostNetwork直接暴露节点网络信息
  • 挂载/proc/sys获取系统指标
  • 资源限制避免过度占用节点资源

3. 日志收集方案:Fluentd实现分布式日志采集

技术栈:Fluentd + ElasticSearch + Kibana

当集群规模达到上百节点时,传统的手工日志收集方式完全不可行。下面这个DaemonSet配置展示了如何实现自动化的日志收集:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-logging
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: fluentd-logging
  template:
    metadata:
      labels:
        app: fluentd-logging
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: fluentd
        image: fluent/fluentd-kubernetes-daemonset:v1.14.6-debian-elasticsearch7-1.0
        env:
          - name: FLUENT_ELASTICSEARCH_HOST
            value: "elasticsearch-logging"
          - name: FLUENT_ELASTICSEARCH_PORT
            value: "9200"
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdocker
          mountPath: /var/lib/docker/containers
          readOnly: true
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdocker
        hostPath:
          path: /var/lib/docker/containers

特殊配置说明

  • 通过tolerations实现Master节点日志采集
  • 容器内挂载宿主机的日志目录
  • 多日志源配置(系统日志+Docker日志)

4. 网络插件部署:Calico CNI安装详解

技术栈:Calico + Kubernetes

网络插件是DaemonSet的典型应用场景之一,以下是Calico网络插件的部分配置片段:

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
      serviceAccountName: calico-node
      containers:
        - name: calico-node
          image: calico/node:v3.21.5
          env:
            - name: DATASTORE_TYPE
              value: "kubernetes"
            - name: FELIX_IPV6SUPPORT
              value: "false"
          securityContext:
            privileged: true
          volumeMounts:
            - mountPath: /host/driver
              name: flexvol-driver-host
      volumes:
        - name: flexvol-driver-host
          hostPath:
            path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec/nodeagent~uds
            type: DirectoryOrCreate

技术要点

  • 特权模式运行容器(securityContext)
  • 直接操作宿主机网络栈(hostNetwork)
  • 通过FlexVolume与kubelet集成

5. 必须掌握的关联技术

5.1 Kubelet协作机制
DaemonSet实际通过kubelet进行Pod的生命周期管理,其健康检查功能需要合理配置:

livenessProbe:
  exec:
    command:
    - sh
    - -c
    - pgrep -x node_exporter || exit 1
  initialDelaySeconds: 5
  periodSeconds: 10

5.2 CNI插件交互流程
网络插件的DaemonSet需要与以下组件配合:

  1. kube-proxy实现服务代理
  2. kubelet进行CNI配置管理
  3. etcd/apiserver存储网络策略

6. 技术方案对比分析

特性 节点监控方案 日志收集方案 网络插件方案
Pod资源消耗 中等(每个实例约300MB) 较高(需处理日志压缩) 低(主要消耗网络资源)
更新策略 滚动更新 灰度更新 强制替换
调度限制 需容忍master节点 需要考虑存储卷性能 必须运行在全部节点
典型故障场景 指标采集中断 日志堆积导致存储压力 网络策略配置错误

7. 生产环境注意事项

资源分配陷阱
监控Agent的Memory Limit设置过小导致OOM:

resources:
  limits:
    memory: 100Mi  # 节点负载高时频繁OOM

# 正确配置
resources:
  limits:
    memory: 500Mi
    cpu: 500m

版本兼容性问题
网络插件需要严格匹配Kubernetes版本:

Calico v3.21 → Kubernetes 1.21+
Cilium 1.11 → Kubernetes 1.23+

安全策略配置
Service Account的权限最小化原则:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluentd-logger
  namespace: kube-system
automountServiceAccountToken: false  # 禁用自动挂载

8. 方案优化思路

智能调度优化
通过nodeAffinity实现异构集群调度:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: gpu-type
          operator: Exists

多架构镜像支持
ARM节点需要特殊处理:

image: prom/node-exporter:v1.3.1-linux-arm64

9. 典型问题排查指南

Pod未全部调度
检查流程:

  1. 节点是否存在taint
  2. Pod资源是否超额
  3. 节点selector是否匹配

网络插件异常
诊断命令:

calicoctl node status
iptables-save | grep CALI

10. 技术总结

经过多个生产环境的实践检验,DaemonSet在以下三个方面表现出显著优势:

  • 部署确定性:确保关键服务覆盖全部节点
  • 生命周期自动管理:节点增减自动适配
  • 资源隔离性:独立于业务Pod运行

但同时需要注意其带来的额外资源开销,建议遵循以下原则:

  1. 同类型服务尽量合并部署
  2. 设置合理的更新策略
  3. 完善的监控告警机制