Kubernetes DaemonSet 实战:部署 Fluentd 日志收集程序
DaemonSet 核心知识点
- DaemonSet 特性:
- 确保集群中每个节点(或符合特定条件的节点)运行一个 Pod 副本
- 当新节点加入集群时自动部署 Pod
- 适合部署系统级服务(如日志收集、监控代理等)
- 与 Deployment 的区别:
- Deployment 关注的是应用实例数量
- DaemonSet 关注的是节点覆盖
- 典型使用场景:
- 日志收集(如 Fluentd、Filebeat)
- 节点监控(如 Prometheus Node Exporter)
- 网络插件(如 Calico、Weave)
实战部署 Fluentd 日志收集
1. 创建 Fluentd DaemonSet 配置文件
Fluentd 是一个开源的统一日志收集和分发系统,专为处理大规模日志数据而设计。它由云原生计算基金会(CNCF)孵化,是 Kubernetes 生态中主流的日志收集工具之一(常与 Elasticsearch、Kibana 等组成 EFK 技术栈)。本文仅部署Fluentd程序进行学习DaemonSet的使用。
graph LR A[应用日志] -->|写入文件| B(Fluentd 收集) B -->|过滤/转发| C[Elasticsearch 存储] C --> D[Kibana 可视化]
需要创建的 RBAC 资源
首先需要创建 ServiceAccount 和必要的 RBAC 权限:
# 创建 ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd
namespace: kube-system
---
# 创建 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fluentd
rules:
- apiGroups: [""]
resources:
- pods
- namespaces
verbs: ["get", "list", "watch"]
---
# 创建 ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fluentd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: fluentd
subjects:
- kind: ServiceAccount
name: fluentd
namespace: kube-system
部署Fluentd DaemonSet
---
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config # ConfigMap 名称(必须与 DaemonSet 中引用的名称一致)
data:
output.conf: | # 配置文件内容(Key 是文件名,Value 是文件内容)
<match **> # 匹配所有日志标签(** 是通配符)
@type elasticsearch # 使用 elasticsearch 输出插件
host elasticsearch-logging # Elasticsearch 服务地址
port 9200 # Elasticsearch 端口
scheme http # 使用 HTTP 协议
logstash_format true # 启用 Logstash 兼容格式
logstash_prefix fluentd # 索引名前缀(实际索引名会是 fluentd-YYYY.MM.DD)
include_tag_key true # 在日志中包含 Fluentd 的 tag 字段
type_name _doc # Elasticsearch 7.x 后固定用 _doc
</match>
---
apiVersion: apps/v1 # 使用的 Kubernetes API 版本
kind: DaemonSet # 资源类型为 DaemonSet,确保每个节点运行一个 Pod 副本
metadata:
name: fluentd # DaemonSet 名称
namespace: kube-system # 部署在 kube-system 命名空间
labels:
k8s-app: fluentd-logging # 应用的标签,用于识别和选择
spec:
selector: # 标签选择器,匹配要管理的 Pod
matchLabels:
name: fluentd # 必须与 template.metadata.labels 中定义的标签一致
updateStrategy: # 更新策略配置
type: RollingUpdate # 滚动更新方式
rollingUpdate:
maxUnavailable: 1 # 更新期间允许不可用的 Pod 最大数量
template: # Pod 模板定义
metadata:
labels:
name: fluentd # Pod 标签,与 selector.matchLabels 对应
spec:
serviceAccountName: fluentd # 指定 Pod 使用的服务账号
tolerations: # 容忍度配置,允许 Pod 调度到带有特定污点的节点
# 容忍 master 节点的污点
- key: node-role.kubernetes.io/master
operator: Exists # 只要存在该 key 的污点就容忍
effect: NoSchedule # 容忍调度限制效果
# 容忍 worker 节点的污点(如果有)
- key: node-role.kubernetes.io/worker
operator: Exists
effect: NoSchedule
# 容忍所有节点的通用污点
- operator: Exists # 容忍任何污点(无条件容忍)
effect: NoSchedule
containers:
- name: fluentd # 容器名称
image: fluent/fluentd-kubernetes-daemonset:v1.16.2-debian-elasticsearch7-1.1 # 使用的镜像
env: # 环境变量配置
- name: FLUENT_ELASTICSEARCH_HOST # Elasticsearch 主机地址
value: "elasticsearch-logging"
- name: FLUENT_ELASTICSEARCH_PORT # Elasticsearch 端口
value: "9200"
- name: FLUENT_ELASTICSEARCH_SCHEME # 使用 HTTP 协议
value: "http"
- name: FLUENT_UID # 运行 Fluentd 的用户 ID(0 表示 root)
value: "0"
resources: # 资源限制和请求
limits:
memory: 500Mi # 内存上限 500MB
requests:
cpu: 100m # 请求 0.1 个 CPU 核心
memory: 200Mi # 请求 200MB 内存
volumeMounts: # 挂载点配置
- name: varlog # 挂载宿主机系统日志目录
mountPath: /var/log
- name: varlibdockercontainers # 挂载 Docker 容器日志目录
mountPath: /var/lib/docker/containers
readOnly: true # 只读挂载
- name: config-volume # 挂载配置文件
mountPath: /fluentd/etc/conf.d
terminationGracePeriodSeconds: 30 # Pod 终止宽限期(秒)
volumes: # 卷定义
- name: varlog # 宿主机系统日志目录
hostPath:
path: /var/log
- name: varlibdockercontainers # Docker 容器数据目录
hostPath:
path: /var/lib/docker/containers
- name: config-volume # 配置卷(来自 ConfigMap)
configMap:
name: fluentd-config # 使用的 ConfigMap 名称
2. 关键配置解析
- tolerations:允许在 master 节点上运行(默认 master 节点有污点)
- volumeMounts:挂载宿主机日志目录
/var/log
:系统日志/var/lib/docker/containers
:容器日志
- 环境变量:配置 Fluentd 输出到 Elasticsearch
- 资源限制:限制 CPU 和内存使用
3. 部署 Fluentd
kubectl apply -f fluentd-daemonset.yaml
4. 验证部署
# 查看 DaemonSet 状态
kubectl -n kube-system get ds
# 查看 Pod 分布(应该在每个节点运行一个)
kubectl -n kube-system get pods -o wide -l name=fluentd
# 查看 Fluentd 日志
kubectl -n kube-system logs -f <fluentd-pod-name>
进阶配置
1. 自定义 Fluentd 配置
创建并修改 ConfigMap 存储自定义配置文件举例:
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
namespace: kube-system
data:
fluent.conf: |
<source>
@type tail
path /var/log/containers/*.log
pos_file /var/log/fluentd-containers.log.pos
tag raw.kubernetes.*
read_from_head true
<parse>
@type json
time_format %Y-%m-%dT%H:%M:%S.%NZ
</parse>
</source>
<match raw.kubernetes.**>
@type elasticsearch
host elasticsearch-logging
port 9200
logstash_format true
logstash_prefix fluentd
include_tag_key true
</match>
然后在 DaemonSet 中挂载此 ConfigMap。
2. 节点选择器
只在特定节点运行 Fluentd:
spec:
template:
spec:
nodeSelector:
logging: "true"
3. 更新策略
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
[!NOTE]
常见问题排查
Pod 无法调度:
- 检查节点污点和 Pod 容忍配置
- 检查节点资源是否充足
日志收集失败:
- 检查 Fluentd 与 Elasticsearch/Kafka 等日志后端的连接
- 检查挂载的宿主机目录权限
性能问题:
- 调整 Fluentd 缓冲区配置
- 增加资源限制
查看 Fluentd 内部状态:
kubectl -n kube-system exec -it <fluentd-pod> -- fluentd --dry-run
评论需开启科学上网!