sidecar日志收集不能直接读宿主机文件,因容器默认隔离,log-agent无法访问应用容器的/var/log/app.log;必须通过emptydir等共享卷打通文件可见性,否则报“no such file”错误。

Sidecar 日志收集为什么不能直接读宿主机文件
因为容器默认是隔离的,log-agent 容器无法直接访问应用容器的 /var/log/app.log —— 即使路径相同,也属于不同 mount namespace。必须通过共享卷(emptyDir 或 hostPath)打通文件可见性。
常见错误现象:open /var/log/app.log: no such file or directory,本质是路径存在但不在当前容器的 rootfs 中。
- 优先用
emptyDir:安全、轻量、生命周期与 Pod 一致,适合应用写日志到本地再由 Sidecar 转发 - 避免直接用
hostPath:权限复杂、节点亲和性高、日志残留风险大 - 应用容器必须把日志输出到挂载路径,比如启动时指定
--log-dir=/var/log,而非默认 stdout
如何配置共享 volume 让两个容器看到同一份日志
关键不是“复制”,而是“共用一个目录”。Kubernetes 的 volumeMounts 必须和 volumes 名称严格匹配,且两个容器都需声明挂载点。
典型 YAML 片段:
volumes:
- name: log-storage
emptyDir: {}
containers:
- name: app
image: my-app:1.2
volumeMounts:
- name: log-storage
mountPath: /var/log
- name: log-agent
image: fluentbit:2.1
volumeMounts:
- name: log-storage
mountPath: /var/log
- mountPath 必须完全一致(如都用
/var/log),否则文件系统视角不重叠 - 应用容器要确保日志写入该路径下的具体文件,例如
/var/log/access.log,而不是只写 stdout - Fluent Bit 等工具需配置
Input类型为tail,监听该路径,例如Path /var/log/*.log
Fluent Bit 配置 tail 输入时容易漏掉的关键项
只配 Path 不够,日志轮转、编码、起始位置都会导致丢日志或重复采集。
-
DB /fluent-bit/tail-db.db:必须开启数据库,否则重启后从头读,造成重复 -
Refresh_Interval 5:太长会延迟发现新日志文件;太短(如 1s)增加 inotify 压力 -
Rotate_Wait 10:应对 logrotate 场景,等文件 rename 完再读,避免截断 -
Key log:指定解析后字段名,下游(如 Loki)依赖这个字段存原始行 - 如果日志含中文或特殊编码,加
Buffer_Chunk_Size 128k和Buffer_Max_Size 256k防截断
Sidecar 日志采集要不要接管 stdout
不建议。Kubernetes 原生 kubelet → containerd → journald 日志路径已稳定,docker logs 和 kubectl logs 都依赖它。Sidecar 强行抓 stdout 会引入额外复杂度:
- 需要
stdin: false+tty: false+args: ["/bin/sh", "-c", "tail -n+1 -f /proc/1/fd/1"],脆弱且不可靠 - 容器 PID 1 可能不是应用进程(如用了
gunicorn或supervisord),/proc/1/fd/1指向错误 - stdout 是流式字节流,无文件边界,Sidecar 很难判断一条完整日志的结束位置
真正需要 Sidecar 的场景,是结构化日志落盘、审计日志分离、或对接非标准后端(如私有 SaaS)。普通调试日志,kubectl logs 更快更准。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











