【Kubernetes】使用DaemonSet进行的资源调度,日志收集案例

K8s DaemonSet 实战:从日志收集到节点选择的完整指南

在 Kubernetes 集群中,有些任务需要在每个节点(或指定节点)上运行一个实例——比如日志收集、监控代理、网络插件等。DaemonSet 正是为这类场景设计的控制器。本文将通过一个日志收集的实战案例,详解 DaemonSet 的核心特性、配置方法和节点选择策略,帮助初学者快速掌握其用法。

什么是 DaemonSet?

DaemonSet 是 Kubernetes 提供的一种控制器,用于在集群的所有节点(或符合条件的节点)上运行且仅运行一个 Pod 实例。它的核心特性包括:

  • 自动部署:新节点加入集群时,DaemonSet 会自动在该节点上创建对应的 Pod
  • 自动清理:节点从集群移除后,DaemonSet 会自动删除该节点上的 Pod
  • 节点选择:可通过标签选择器指定仅在特定节点上部署 Pod
  • 无副本数配置:无需手动设置 replicas,Pod 数量由集群节点数决定(受节点选择限制)

最典型的应用场景就是日志收集(如本文的 Fluentd 案例)和节点监控(如 Prometheus Node Exporter)。


DaemonSet(守护进程集)的核心作用:日志收集与自动化管理

对于初学者来说,可以这样理解 DaemonSet 的核心价值:

1. 解决什么问题?—— 日志收集的“痛点”

传统微服务部署时,会遇到一个麻烦:

  • 一个集群有多个节点(node),每个节点上可能运行多个微服务的 Pod;
  • 每个 Pod 都有自己的日志,分散在各个节点的本地文件里;
  • 如果服务出故障,需要逐个登录节点、逐个查找 Pod 日志,效率极低。

DaemonSet 的第一个作用,就是在每个节点上“自动部署一个专用的日志收集进程”(比如你提到的 Fluentd),统一收集该节点上所有 Pod 的日志,再发送到 Elasticsearch(日志存储)或 Prometheus(监控),避免手动逐个节点查日志。

2. 为什么用 DaemonSet 而不是普通 Deployment?

普通 Deployment 是“指定数量部署”(比如部署 3 个 Pod),而 DaemonSet 有两个关键特性,完美适配日志收集场景:

  • “节点级守护”:只要集群里有新节点加入,DaemonSet 会自动在新节点上部署一个 Pod(确保每个节点都有日志收集进程);
  • “自动化管理”:不需要手动登录节点启动进程,只需写一个 DaemonSet 配置文件,K8s 会自动完成部署、重启、扩容(新节点加入时)。
3. 如何指定“要收集哪些日志”?

如果只想收集某类节点的日志(比如只收集标记为“生产环境”的节点),可以用 nodeSelector 做筛选:

  • 先给目标节点打标签(比如 kubectl label nodes 节点名 type=production);
  • 在 DaemonSet 配置里加 nodeSelector: {type: production}
  • 这样 DaemonSet 只会在带有 type=production 标签的节点上部署日志收集进程,避免“无差别收集”。

实战场景:用 DaemonSet 部署 Fluentd 日志收集器

我们将通过部署 Fluentd(一款日志收集工具),演示 DaemonSet 的工作流程。目标是让 Fluentd 在指定节点上运行,收集节点上的容器日志并发送到存储后端(如 Elasticsearch)。

步骤1:编写 DaemonSet 配置文件

创建 fluentd-ds.yaml 配置文件,定义 DaemonSet 及相关配置:

apiVersion: apps/v1
kind: DaemonSet  # 资源类型为 DaemonSet
metadata:
  name: fluentd  # DaemonSet 名称
spec:
  selector:  # 标签选择器(必须与 Pod 标签匹配)
    matchLabels:
      app: logging
  template:  # Pod 模板(定义要运行的容器)
    metadata:
      labels:
        app: logging  # 与 selector.matchLabels 对应
        id: fluentd
    spec:
      containers:
      - name: fluentd-es  # 容器名称
        image: agilestacks/fluentd-elasticsearch:v1.3.0  # Fluentd 镜像
        env:  # 环境变量(简化日志输出)
        - name: FLUENTD_ARGS
          value: -qq  # 安静模式,减少日志输出
        volumeMounts:  # 挂载主机目录(用于读取日志)
        - name: containers  # 数据卷名称(与下方 volumes 对应)
          mountPath: /var/lib/docker/containers  # 容器日志存储路径(主机目录)
        - name: varlog  # 数据卷名称
          mountPath: /var/log  # 系统日志路径(主机目录)
      volumes:  # 定义数据卷(关联主机目录)
      - name: containers
        hostPath:
          path: /var/lib/docker/containers  # 主机上的容器日志目录
      - name: varlog
        hostPath:
          path: /var/log  # 主机上的系统日志目录
配置关键点解析:
  • 无副本数配置:DaemonSet 无需设置 replicas,Pod 数量由节点数决定
  • 数据卷挂载:通过 hostPath 将主机的日志目录(/var/lib/docker/containers/var/log)挂载到容器,使 Fluentd 能读取节点日志
  • 标签选择器selector 用于关联 DaemonSet 和 Pod,必须与 Pod 模板的 labels 匹配

步骤2:创建 DaemonSet 并查看初始状态

执行以下命令创建 DaemonSet:

kubectl create -f fluentd-ds.yaml
查看 DaemonSet 状态:
kubectl get ds  # ds 是 daemonsets 的缩写

输出如下(DESIRED 表示期望在 2 个节点上部署):

NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
fluentd   2         2         0       2            0           <none>          14s
查看 Pod 分布:
kubectl get po -o wide  # -o wide 显示 Pod 所在节点

输出显示 Pod 分布在 k8snode1k8snode2 上(默认不会部署在 master 节点,因 master 有 node-role.kubernetes.io/control-plane 标签限制):

NAME               READY   STATUS    IP            NODE       ...
fluentd-c27qt      1/1     Running   10.244.2.61   k8snode2   ...
fluentd-mzrcc      1/1     Running   10.244.1.58   k8snode1   ...
关键结论:
  • DaemonSet 会自动在所有符合条件的节点上部署 Pod(默认排除 master 节点)
  • 无需配置 replicas,Pod 数量自动匹配节点数(受节点选择限制)

步骤3:用节点标签限制 DaemonSet 部署范围

默认情况下,DaemonSet 会在所有非 master 节点部署 Pod。但实际场景中,我们可能只需要在“微服务节点”上收集日志。此时可通过节点标签 + 节点选择器实现。

操作1:为节点添加标签

给需要部署 Fluentd 的节点(如 k8snode1)添加 type=microservices 标签:

kubectl label node k8snode1 type=microservices

查看标签是否生效:

kubectl get nodes --show-labels

输出显示 k8snode1 已添加标签:

NAME        STATUS   LABELS... type=microservices  # k8snode1 的标签
k8snode2    Ready    LABELS...  # 无 type=microservices 标签
操作2:配置 DaemonSet 的节点选择器

通过 kubectl edit ds fluentd 编辑 DaemonSet,添加节点选择器:

spec:
  template:
    spec:
      nodeSelector:  # 仅在带有 type=microservices 标签的节点上部署
        type: microservices
操作3:验证部署结果

查看 DaemonSet 和 Pod 状态:

# 查看 DaemonSet:DESIRED 变为 1(仅 k8snode1 符合标签条件)
kubectl get ds
# 输出:NAME      DESIRED   CURRENT   READY   NODE SELECTOR        AGE
#       fluentd   1         1         1       type=microservices   ...

# 查看 Pod:仅在 k8snode1 上运行
kubectl get po -o wide
# 输出:NAME            READY   NODE       ...
#       fluentd-vn5zh   1/1     k8snode1   ...
关键结论:
  • 通过 nodeSelector 可限制 DaemonSet 仅在带有指定标签的节点上部署 Pod
  • 标签更新后,DaemonSet 会自动删除不符合条件的 Pod,在符合条件的节点上创建新 Pod

步骤4:动态调整部署节点(添加新标签)

若后续需要在 k8snode2 上也部署 Fluentd,只需给 k8snode2 添加相同标签:

kubectl label node k8snode2 type=microservices

查看 Pod 状态,发现 DaemonSet 自动在 k8snode2 上创建了新 Pod:

kubectl get po -o wide
# 输出:
# fluentd-lgjjs   1/1     Running   10.244.2.62   k8snode2   ...
# fluentd-vn5zh   1/1     Running   10.244.1.59   k8snode1   ...
关键结论:
  • 节点标签更新后,DaemonSet 会自动调整 Pod 分布(新增符合条件的节点时自动部署,移除标签时自动删除)

DaemonSet 核心特性总结

通过上述实战,我们可以总结 DaemonSet 的核心特性:

特性说明
部署策略在所有符合条件的节点上运行且仅运行一个 Pod
自动扩缩容新节点加入时自动部署 Pod,节点移除时自动删除 Pod
节点选择通过 nodeSelector + 节点标签,限制仅在特定节点部署
无副本数配置无需设置 replicas,Pod 数量由符合条件的节点数决定
默认行为不部署在 master 节点(因 master 有 control-plane 标签限制)

DaemonSet vs Deployment:核心差异

特性DaemonSetDeployment
Pod 分布每个节点最多一个 Pod(按节点部署)不限制节点,按副本数部署(随机分布)
副本数控制由节点数决定(无需配置 replicas)需手动配置 replicas
典型用途日志收集、监控代理、网络插件(节点级任务)微服务、API 服务(应用级任务)
扩缩容方式添加/移除节点或标签调整 replicas 数量

总结

本文通过部署 Fluentd 日志收集器,演示了 DaemonSet 的核心用法:

  1. 核心作用:在指定节点上运行且仅运行一个 Pod,适合节点级任务(如日志收集、监控)
  2. 自动部署:新节点加入时自动部署 Pod,无需手动操作
  3. 节点选择:通过 nodeSelector + 节点标签,灵活控制部署范围
  4. 与 Deployment 区别:DaemonSet 按节点部署,Deployment 按副本数部署

掌握 DaemonSet 后,你可以轻松实现节点级工具的批量部署和管理,为集群监控、日志收集等基础能力提供支撑。


https://github.com/0voice

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值