核心是打通 stdout/stderr 通路,由 docker 日志驱动(如 fluentd、syslog、awslogs)或外部采集器(如 filebeat、fluent bit)从源头抓取;禁用应用内重定向,确保日志经 docker 管控。

让 Docker 容器日志进得去集中式系统,核心不是“重定向应用日志文件”,而是确保 stdout/stderr 这条通路畅通,并由日志驱动或采集器从源头接管。
用 Docker 原生日志驱动直连后端
Docker 内置多种日志驱动,无需改代码、不依赖外部进程,启动时指定即可把容器输出发往目标系统:
-
Fluentd 驱动:适合已有 Fluentd 集群的环境。命令示例:
docker run --log-driver=fluentd --log-opt fluentd-address=10.0.1.5:24224 --log-opt tag=docker.app myapp -
Syslog 驱动:对接 rsyslog 或 syslog-ng,兼容传统运维体系:
--log-driver=syslog --log-opt syslog-address=tcp://192.168.1.100:514 -
AWS CloudWatch Logs:云上场景常用,需提前配置 IAM 权限和 log-group:
--log-driver=awslogs --log-opt awslogs-region=us-west-2 --log-opt awslogs-group=/myapp/prod -
json-file(带轮转):开发或小规模可用,但必须加限制防磁盘打满:
--log-opt max-size=10m --log-opt max-file=3
用 Filebeat 或 Fluent Bit 主动采集 JSON 日志文件
Docker 默认将 stdout/stderr 存为 JSON 文件(路径:/var/lib/docker/containers/<id>/<id>-json.log</id></id>),Filebeat 和 Fluent Bit 可监听并结构化解析:
- Filebeat 配置启用 container 类型输入:
type: container,路径设为/var/lib/docker/containers/*/*.log,开启json.keys_under_root: true自动展开字段 - Fluent Bit 使用
tail输入插件 +docker解析器,自动提取time、stream、log字段 - 务必挂载宿主机日志目录到采集容器:
-v /var/lib/docker/containers:/var/lib/docker/containers:ro
避免日志通路断裂的关键操作
很多问题源于应用层无意中绕开了 Docker 的日志管控:
- 禁止在
CMD或启动脚本里做重定向,例如:CMD ["sh", "-c", "python app.py > /var/log/app.log 2>&1"]→ 日志进文件,docker logs返回空 - 不要让应用自己写日志文件(如
RUN echo ... >> /var/log/app.log),采集器无法识别上下文 - 正确做法是让应用直接输出到终端(
print()、console.log()),或用软链把服务日志指向/dev/stdout(如 Nginx:ln -sf /dev/stdout /var/log/nginx/access.log)
本地落盘 + 远程双写的合规方案
当审计或合规要求日志必须同时留存本地和远程时,不能靠应用双写,而应利用日志驱动能力:
- Docker 不支持原生双写,但可通过 Fluent Bit 或 Filebeat 实现:一边转发至 Elasticsearch/Loki,一边写入本地文件系统(启用
file输出插件) - 也可部署两个采集器实例:一个走 fluentd 驱动发远程,另一个用 tail 方式读取 JSON 文件做本地归档
- 所有方案都需确保时间戳、容器 ID、标签等元数据完整保留,满足可追溯性要求











