[CKAD] DaemonSet: 节点级基础设施代理的保证部署与管理

大家好!今天,我们将了解Kubernetes中管理工作负载的四大核心之一,一个执行着特殊任务的朋友。它不像Web服务器或API服务器那样根据流量进行伸缩。它是一个默默无闻、必须在每个节点(服务器)上存在一个的基础设施级守护者,那就是DaemonSet。🛡️

CKAD考试中也经常出现“仅在特定节点上部署日志收集器”之类的题目,所以今天我们投入15分钟,彻底掌握这个概念吧!


###

1. 引言:为什么每个节点都需要一个Pod? 🤔

我们通常使用的Deployment,当你请求“为我们的服务启动3个Pod!”时,调度器会自动将它们适当地放置在有可用资源的节点上。一个节点上可能会启动2个,或者3个Pod都分布在不同的节点上。

但如果情况改变了呢?

假设你有一个由100台服务器(节点)组成的Kubernetes集群。你需要收集这100台服务器上产生的所有系统日志。

  • 使用Deployment设置`replicas: 100`可以吗?
  • 👉 不行! 如果运气不好,某些节点上可能会启动2个日志收集器,而某些节点上一个都没有。

这时就需要DaemonSet,它是一个控制器,能够“确保集群中所有节点(或满足特定条件的节点)上精确地运行一个Pod副本”。

2. DaemonSet的主要任务 (Use Cases) 🛠️

DaemonSet通常用于执行基础设施级别的任务,而非应用程序逻辑。它的主要职责是作为管理或监控节点本身的“代理”。

典型的使用场景如下:

  1. 📝 运行日志收集守护进程:
    • 收集每个节点上产生的容器日志或系统日志,并将其发送到中央日志存储(如Elasticsearch、Loki等)。
    • 示例: Fluentd, Fluent Bit, Filebeat
    1. 📊 运行监控守护进程:
      • 收集每个节点的CPU、内存、磁盘使用情况等节点自身的状态信息。
      • 示例: Prometheus Node Exporter, Datadog Agent
      1. 🌐 集群存储守护进程和网络插件:
        • 帮助在每个节点上挂载存储,或运行负责节点间网络通信的CNI插件。
        • 示例: Glusterd, Ceph, Calico, Flannel

        💡 核心总结: 当新的节点加入集群时,DaemonSet会自动创建Pod;当节点被移除时,它也会一并清理Pod。它真是个可靠的守护者,不是吗?

        3. CKAD实战!YAML中的DaemonSet 📄

        百闻不如一见!让我们通过实际代码来看看它与Deployment有何不同。

        最大的区别是没有`replicas`字段。Pod的数量由节点的数量决定!

        下面是一个简单的DaemonSet示例,用于在所有节点上部署名为fluentd的日志收集器。

        apiVersion: apps/v1
        kind: DaemonSet  # 👈 类型是 DaemonSet。
        metadata:
          name: fluentd-elasticsearch
          namespace: kube-system # 通常,基础设施相关的部署在 kube-system 中。
          labels:
            k8s-app: fluentd-logging
        spec:
          # replicas: 3 👈 与 Deployment 不同,此字段不存在!
          selector:
            matchLabels:
              name: fluentd-elasticsearch
          template: # 从这里开始,与 Pod 模板相同。
            metadata:
              labels:
                name: fluentd-elasticsearch
            spec:
              # 将节点系统日志路径挂载到 Pod 的设置(示例)
              volumes:
              - name: varlog
                hostPath:
                  path: /var/log
              containers:
              - name: fluentd-elasticsearch
                image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
                volumeMounts:
                - name: varlog
                  mountPath: /var/log
                resources:
                  limits:
                    memory: 200Mi
                  requests:
                    cpu: 100m
                    memory: 200Mi
              # 如果要部署到主节点(控制平面),可能需要容忍污点。
              tolerations:
              - key: node-role.kubernetes.io/control-plane
                operator: Exists
                effect: NoSchedule
              - key: node-role.kubernetes.io/master
                operator: Exists
                effect: NoSchedule

        4. CKAD进阶:“我只想部署到特定节点!” (Node Selector) 🎯

        在CKAD考试中,除了简单地创建DaemonSet,给出条件的情况也很多。

        “仅在带有GPU的节点上以DaemonSet形式部署监控代理。”

        DaemonSet默认部署在所有节点上,但你可以使用`nodeSelector`或`affinity`来仅在带有特定标签的节点上启动Pod。

        示例场景: 如果你想只部署到带有`type=gpu-node`标签的节点上怎么办?

        apiVersion: apps/v1
        kind: DaemonSet
        metadata:
          name: gpu-monitor
        spec:
          selector:
            matchLabels:
              app: gpu-monitor
          template:
            metadata:
              labels:
                app: gpu-monitor
            spec:
              # 👇 这部分是关键!
              nodeSelector:
                type: gpu-node
              containers:
              - name: nvidia-gpu-exporter
                image: nvidia/gpu-monitoring-tools
                # ... 省略 ...

        这样设置后,DaemonSet控制器将从集群节点中选择带有`type=gpu-node`标签的节点,并在每个节点上创建一个Pod。非常智能,不是吗? 🧠

        5. DaemonSet的更新策略 (RollingUpdate vs OnDelete) 🔄

        如果更改了DaemonSet部署的Pod镜像会发生什么?与Deployment一样,DaemonSet也有更新策略。

        • RollingUpdate (默认值):
        • 这是最推荐的方式。它不像Deployment那样一次性杀死所有Pod,而是逐个节点地顺序删除旧版本Pod并创建新版本Pod。这可以在不中断服务的情况下更新基础设施代理。
        • `maxUnavailable`设置可以控制同时有多少个节点可以进行更新(即有多少个Pod可以暂时不可用)(默认值为1)。
        • OnDelete:
        • 顾名思义,“删除时”更新。即使修改了模板,正在运行的Pod也不会改变。
        • 操作员必须手动使用`kubectl delete pod …`删除相应节点上的Pod,DaemonSet控制器才会创建新版本的Pod。当你想完全手动控制更新时机时使用。

        6. 总结:CKAD考场小贴士 🍯

        DaemonSet只要概念掌握牢固,就和Deployment一样简单。

        1. 记住目的: 它的目的是“每个节点的独立基础设施管理”,而不是“服务扩展(Scaling)”。
        2. YAML结构: 务必记住没有`replicas`字段。
        3. 节点选择: 如果考试中出现“仅部署到特定节点”的要求,不要慌张,只需在Pod模板(`spec.template.spec`)中添加`nodeSelector`。
        4. Toleration: 如果需要部署到主节点(控制平面),可能需要`tolerations`设置来容忍主节点的Taint。(虽然最新版本有时会自动添加,但明确声明更好。)

        今天学习的DaemonSet,感觉如何?它是不是像一个可靠的支援者,在幕后默默工作,以保持集群的稳定? 👮‍♂️

        如果您在准备CKAD考试时有任何疑问,请随时提问。我衷心祝愿您考试成功!加油! 💪



Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注