daemonset是kubernetes中确保每个符合条件节点运行且仅运行一个pod副本的控制器,适用于日志收集(fluentd/filebeat/vector)、监控代理、网络插件等节点级守护进程,支持自动扩缩容、污点容忍与精准调度。

DaemonSet 是 Kubernetes 中确保每个节点(或匹配的节点)上都运行一个 Pod 副本的核心控制器,非常适合部署日志收集代理(如 Fluentd、Filebeat 或 Vector)。它的核心逻辑是:只要节点满足调度条件(如标签、污点等),就会自动部署并维持一个 Pod 实例——节点上线自动加,节点下线自动删,无需手动扩缩。
选择合适的日志收集器并准备镜像
主流选型有:
-
Fluentd:生态成熟,插件丰富,适合复杂解析和转发(如发往 Elasticsearch、Loki);推荐使用
fluent/fluentd-kubernetes-daemonset官方镜像,已预装常用插件 -
Filebeat:轻量、资源占用低,原生支持 Kubernetes 模块(
kubernetesinput),能自动发现容器、读取 stdout/stderr 和容器日志文件(如/var/log/pods/) - Vector:高性能、Rust 编写,配置简洁,支持结构化日志处理和多种 sink,适合对吞吐和延迟敏感的场景
注意:优先选用已适配 Kubernetes 的镜像版本(例如 Filebeat 镜像需开启 processors.kubernetes),避免自行构建时遗漏权限或挂载配置。
编写 DaemonSet YAML:关键字段不能漏
以下是最小可行示例(以 Filebeat 为例),重点说明必须配置的部分:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat
namespace: kube-system
spec:
selector:
matchLabels:
app: filebeat
template:
metadata:
labels:
app: filebeat
spec:
serviceAccountName: filebeat # 必须绑定有 RBAC 权限的 SA
hostNetwork: true # 可选,若需监听宿主机网络(如采集 node 日志)
dnsPolicy: ClusterFirstWithHostNet # 若 hostNetwork 为 true,需显式设置
tolerations:
- operator: Exists # 允许容忍所有污点,确保调度到 master/tainted 节点(如需)
containers:
- name: filebeat
image: docker.elastic.co/beats/filebeat:8.13.0
args: [
"-c", "/etc/filebeat.yml",
"-e",
]
volumeMounts:
- name: config
mountPath: /etc/filebeat.yml
subPath: filebeat.yml
readOnly: true
- name: data
mountPath: /usr/share/filebeat/data
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
- name: varlog
mountPath: /var/log
readOnly: true
- name: varlogpods
mountPath: /var/log/pods
readOnly: true
volumes:
- name: config
configMap:
name: filebeat-config
- name: data
emptyDir: {}
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
- name: varlog
hostPath:
path: /var/log
- name: varlogpods
hostPath:
path: /var/log/pods
关键点说明:
-
hostPath 挂载必须准确:Kubernetes 容器日志默认路径是
/var/log/pods/(由 kubelet 写入),Docker 容器日志在/var/lib/docker/containers/,系统日志在/var/log/;不同 CRI(如 containerd)路径略有差异,需按实际调整(例如 containerd 日志在/run/containerd/io.containerd.runtime.v2.task/k8s.io/*/logs/,但通常仍通过/var/log/pods/访问) - RABC 权限不可少:Filebeat 需要 list/watch Pods、Nodes、Namespaces 等资源来自动关联元数据,必须创建对应 ServiceAccount + ClusterRoleBinding
-
tolerations 和 nodeSelector 可控调度范围:如只部署到 worker 节点,可加
nodeSelector: node-role.kubernetes.io/worker: "";如跳过带node-role.kubernetes.io/control-plane: ""污点的 master 节点,则不加 toleration 或显式排除
验证与调优常见问题
部署后快速确认是否生效:
- 执行
kubectl get ds -n kube-system filebeat,看DESIRED == CURRENT == READY,且数量等于你期望覆盖的节点数 - 查 Pod 分布:
kubectl get pods -n kube-system -l app=filebeat -o wide,确认每个目标节点上都有且仅有一个 Pod - 进任意一个 Pod:
kubectl exec -n kube-system -it <filebeat-pod> -- sh</filebeat-pod>,检查日志路径是否可读(如ls /var/log/pods/)、配置是否加载成功(filebeat test config和test output)
典型问题及应对:
-
Pod 卡在 Pending:大概率是节点不满足调度条件(污点未容忍、资源不足、nodeSelector 不匹配),用
kubectl describe pod查 Events -
日志没采集到:先确认挂载路径是否真实存在且非空;再检查 Filebeat 配置中
input是否启用kubernetes模块,并设置了正确的paths(如/var/log/pods/*/*.log) -
CPU/Memory 过高:限制 resource requests/limits;关闭不必要的 modules(如 system、nginx);Filebeat 默认启用了大量输入,精简配置只留
kubernetes和container
后续建议:对接统一日志后端
DaemonSet 只解决“采集”一环,还需把日志可靠发送出去:
- 发往 Loki:用 Promtail(本身就是 DaemonSet 设计)或 Filebeat 的
lokioutput,天然支持多租户和 label 打标 - 发往 Elasticsearch:注意连接数、批量大小(bulk_size)、重试策略,避免压垮 ES;生产环境建议加 Logstash 或 Kafka 做缓冲
- 发往 S3/OSS:适合归档,可用 Fluentd 的
s3插件或 Vector 的aws_s3sink,按时间切片压缩存储
无论选哪种后端,都建议在 DaemonSet 配置中注入集群名、环境标签(如 env: prod),便于日志查询时过滤和聚合。











