是否有支持Docker journald日志驱动的Fluentd DaemonSet用于K8S日志转储至ES?
适配Docker journald日志驱动的Fluentd DaemonSet方案(K8S → Elasticsearch)
是的,完全存在这样的可行方案!我之前在kubeadm部署的集群里也碰到过一模一样的痛点——不想把Docker日志改回json-file(确实属于技术倒退,还得额外维护日志轮转),但现有EFK套件都依赖/var/log/containers的文件日志。下面是亲测有效的配置方案:
核心思路
既然Docker用journald驱动,那Fluentd就不能再用tail插件读文件了,得直接从systemd journal里抓取容器日志,再通过K8S API补全Pod元数据,最后转发到Elasticsearch。
步骤1:构建适配的Fluentd镜像
大部分现成镜像没预装systemd输入插件和K8S元数据过滤插件,建议自己构建:
# 用debian基础镜像,兼容性更好 FROM fluentd:v1.16-debian-1 USER root # 安装systemd插件依赖 RUN apt-get update && apt-get install -y --no-install-recommends \ libsystemd-dev \ && rm -rf /var/lib/apt/lists/* # 安装所需fluentd插件 RUN gem install \ fluent-plugin-systemd \ fluent-plugin-kubernetes_metadata_filter \ fluent-plugin-elasticsearch \ --no-document USER fluent
构建完成后推送到你的私有镜像仓库即可。
步骤2:Fluentd配置文件(conf)
创建fluentd.conf,重点是用systemd输入源、过滤Docker容器日志、补全K8S元数据:
<source> @type systemd path /var/log/journal filters [{ "_SYSTEMD_UNIT": "docker.service" }] read_from_head true tag docker.journald </source> <filter docker.journald> @type kubernetes_metadata kubernetes_url "https://kubernetes.default.svc:443" verify_ssl true ca_file /var/run/secrets/kubernetes.io/serviceaccount/ca.crt token_file /var/run/secrets/kubernetes.io/serviceaccount/token </filter> <filter docker.journald> @type parser key_name MESSAGE <parse> @type json reserve_data true </parse> </filter> <match docker.journald> @type elasticsearch host elasticsearch-logging.default.svc.cluster.local port 9200 index_name fluentd-k8s-%Y%m%d logstash_format false </match>
systemd输入部分:只抓取docker.service的日志,避免混入其他系统日志kubernetes_metadata插件:自动从K8S API获取容器对应的Pod名称、命名空间、标签等元数据- 解析部分:把Docker输出的JSON格式日志解析开(如果你的容器日志是纯文本,可调整此部分配置)
步骤3:DaemonSet配置YAML
创建fluentd-daemonset.yaml,关键是挂载journal目录和配置K8S权限:
apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd-journald namespace: kube-system labels: k8s-app: fluentd-logging spec: selector: matchLabels: name: fluentd-journald template: metadata: labels: name: fluentd-journald spec: serviceAccountName: fluentd tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: fluentd image: YOUR_PRIVATE_REGISTRY/fluentd-journald:v1.0 resources: limits: memory: 200Mi requests: cpu: 100m memory: 200Mi volumeMounts: - name: journal mountPath: /var/log/journal readOnly: true - name: run-journal mountPath: /run/log/journal readOnly: true - name: config mountPath: /fluentd/etc/fluentd.conf subPath: fluentd.conf securityContext: # 加入systemd-journal组,确保能读取日志(GID根据你的主机调整,用getent group systemd-journal查看) supplementalGroups: [100000] volumes: - name: journal hostPath: path: /var/log/journal - name: run-journal hostPath: path: /run/log/journal - name: config configMap: name: fluentd-journald-config
补充:ServiceAccount权限配置
需要给Fluentd的ServiceAccount配置权限,让它能访问K8S API获取元数据:
apiVersion: v1 kind: ServiceAccount metadata: name: fluentd namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: fluentd rules: - apiGroups: [""] resources: ["pods", "namespaces"] verbs: ["get", "list", "watch"] --- 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版本是否兼容,比如Fluentd v1.16搭配最新插件版本一般没问题,避免使用过于老旧的基础镜像
- 读取不到日志:检查主机上的
/var/log/journal和/run/log/journal是否存在,容器内的补充组GID是否和主机的systemd-journal组一致 - 元数据补全失败:检查ServiceAccount的权限配置是否正确,确认K8S API能被容器正常访问
这样配置后,Fluentd就能直接从journald抓取Docker容器日志,完全不需要修改Docker的日志驱动,完美契合你的需求!
内容的提问来源于stack exchange,提问作者mon
相关产品推荐
相关产品推荐

