如何利用EFK采集Kubernetes集群中应用自定义路径下的日志?
你好呀!针对你现在遇到的问题——用DaemonSet模式的Fluentd只能采集节点级日志,想拿到应用Pod里/tmp/logs/*路径下的日志,其实有两种靠谱的方案,我给你详细拆解下:
方案一:继续使用DaemonSet模式(推荐日志路径统一的场景)
DaemonSet本身是可以实现这个需求的,只是需要调整应用Pod的挂载配置和Fluentd的采集配置,核心思路是让应用把自定义日志目录挂载到节点上,这样节点上的Fluentd就能访问到这些日志。
步骤1:修改应用Pod的配置,将日志目录挂载到节点
在你的应用Pod的Deployment/DaemonSet配置里,添加volumes和volumeMounts,把Pod内的/tmp/logs挂载到节点的某个固定路径(比如/var/log/app-logs/<你的应用名>):
apiVersion: apps/v1 kind: Deployment metadata: name: your-app spec: template: spec: containers: - name: your-app-container image: your-app-image volumeMounts: - name: app-logs mountPath: /tmp/logs # 应用生成日志的路径 volumes: - name: app-logs hostPath: path: /var/log/app-logs/your-app # 节点上对应的挂载路径 type: DirectoryOrCreate # 如果路径不存在就自动创建
步骤2:修改Fluentd DaemonSet的配置,添加日志目录挂载
在你现有的Fluentd DaemonSet配置里,新增一个volume和volumeMounts,让Fluentd能访问到节点上的应用日志路径:
# 原Fluentd DaemonSpec部分修改 spec: template: spec: containers: - name: fluentd # ... 原有配置不变 volumeMounts: # ... 原有挂载不变 - name: app-logs mountPath: /var/log/app-logs/your-app readOnly: true volumes: # ... 原有volumes不变 - name: app-logs hostPath: path: /var/log/app-logs/your-app type: DirectoryOrCreate
步骤3:修改Fluentd的采集配置,添加自定义日志的Source
你需要给Fluentd添加一个新的采集规则,用来读取/var/log/app-logs/your-app下的日志。可以通过ConfigMap挂载配置文件(推荐用ConfigMap更灵活):
# 示例ConfigMap配置 apiVersion: v1 kind: ConfigMap metadata: name: fluentd-config namespace: efk data: custom-app.conf: | <source> @type tail path /var/log/app-logs/your-app/*.log pos_file /var/log/fluentd-app-logs.pos tag kubernetes.app.your-app <parse> @type regexp expression /^(?<time>.+) (?<level>[A-Z]+) (?<message>.*)$/ # 根据你的日志格式调整正则 </parse> </source>
然后把这个ConfigMap挂载到Fluentd容器的/etc/fluent/config.d目录下,让Fluentd加载这个配置。
方案二:使用Sidecar模式(适合日志路径多样或不想依赖节点挂载的场景)
如果你的应用日志路径不统一,或者不想修改节点的挂载配置,给每个需要采集日志的应用Pod添加Fluentd Sidecar容器是更合适的选择——Sidecar和应用Pod共享同一个Pod的网络和存储,能直接访问到应用的/tmp/logs目录。
示例应用Pod配置(带Fluentd Sidecar)
apiVersion: apps/v1 kind: Deployment metadata: name: your-app spec: template: spec: containers: - name: your-app-container image: your-app-image volumeMounts: - name: app-logs mountPath: /tmp/logs # 添加Fluentd Sidecar容器 - name: fluentd-sidecar image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1 env: - name: FLUENT_ELASTICSEARCH_HOST value: "HOST_IP" # 替换成你的ES地址 - name: FLUENT_ELASTICSEARCH_PORT value: "9200" - name: FLUENT_ELASTICSEARCH_SCHEME value: "http" resources: limits: memory: 256Mi requests: cpu: 50m memory: 100Mi volumeMounts: - name: app-logs mountPath: /tmp/logs readOnly: true - name: fluentd-config mountPath: /etc/fluent/config.d volumes: - name: app-logs emptyDir: {} # 用emptyDir让应用和Sidecar共享日志目录 - name: fluentd-config configMap: name: fluentd-sidecar-config
对应的Fluentd Sidecar配置ConfigMap
apiVersion: v1 kind: ConfigMap metadata: name: fluentd-sidecar-config data: app-log.conf: | <source> @type tail path /tmp/logs/*.log pos_file /tmp/fluentd-app-pos.pos tag kubernetes.app.your-app <parse> @type regexp expression /^(?<time>.+) (?<level>[A-Z]+) (?<message>.*)$/ # 根据你的日志格式调整 </parse> </source>
两种方案的对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| DaemonSet模式 | 资源占用少,统一管理所有日志采集,适合大规模、日志路径统一的场景 | 需要应用配合挂载日志到节点,节点挂载路径需要规划,不同应用不能冲突 |
| Sidecar模式 | 不需要依赖节点挂载,每个应用独立配置,适合日志路径多样的场景 | 每个应用Pod多一个容器,资源消耗更高,配置分散不易统一管理 |
你可以根据自己的实际场景选择合适的方案哦!
备注:内容来源于stack exchange,提问作者karthik

