Docker日志管理手册:避免磁盘爆满与配置最佳实践
核心问题:默认 json-file 驱动无日志轮转
- 日志位置: /var/lib/docker/containers/<container-id>/<container-id>-json.log
- 风险: 默认配置下,此日志文件会无限增长。若不干预,最终会耗尽磁盘空间(尤其是 /var分区),导致容器或宿主机故障。
- 表象: 出现 No space left on device错误,服务不可用。使用df -h检查磁盘,常发现/var或/var/lib占用率 100%。
解决方案核心:配置日志轮转 (Log Rotation)
主要针对最常用的 json-file 驱动。目标是限制单个日志文件大小和保留的历史文件数量。
配置方法 (三选一):
- docker run启动时指定 (推荐:灵活控制)- 1 
 2
 3
 4
 5
 6
 7- docker run -d \ 
 --log-driver json-file \ # 通常可省略(默认)
 --log-opt max-size=10m \ # 单个日志文件最大大小(支持 k, m, g)
 --log-opt max-file=3 \ # 保留的旧日志文件最大数量(包含当前活跃文件)
 --log-opt compress=true \ # 可选:压缩轮转后的旧日志(gzip)
 --name my-container \
 your-image:tag- 总日志量估算: max-size*max-file(例如10m * 3 ≈ 30MB)。
- 轮转机制: 当前日志文件达到 max-size时,会被重命名为<container-id>-json.log.1(之前的.1变为.2,依此类推),并新建一个空日志文件。当文件数超过max-file时,最旧的日志文件 (.3) 被删除。
- 优点: 按容器精细化管理策略。
 
- 总日志量估算: 
- 修改 Docker Daemon 全局配置 (推荐:一劳永逸) - 编辑配置文件 /etc/docker/daemon.json(不存在则创建):1 
 2
 3
 4
 5
 6
 7
 8{ 
 "log-driver": "json-file",
 "log-opts": {
 "max-size": "20m", // 全局默认单个文件大小
 "max-file": "5", // 全局默认保留文件数
 "compress": "true" // 可选:压缩旧日志
 }
 }
- 保存文件,确保权限正确 (通常 root:root,644)。
- 重启 Docker 服务使配置生效:1 sudo systemctl restart docker # 或 sudo service docker restart 
- 重要:- 此配置仅对之后新创建的容器生效。
- 单个容器 docker run时的--log-opt会覆盖此全局设置。
- 重启 Docker 会短暂中断服务,请在维护窗口操作。
 
 
- 编辑配置文件 
- 处理正在运行的容器 (临时/根治) - 临时清理 (应急,谨慎!):- 查找日志路径:docker inspect -f '{{.LogPath}}' <container-name-or-id>
- 清空前务必确认: 最好先停止容器 (docker stop),避免日志写入冲突或丢失。
- 清空文件 (两种方式):1 
 2
 3
 4# 方法 1: Truncate (保留文件 inode,速度快) 
 sudo truncate -s 0 $(docker inspect -f '{{.LogPath}}' <container-id>)
 # 方法 2: Echo (覆盖内容)
 sudo sh -c 'echo "" > $(docker inspect -f '{{.LogPath}}' <container-id>)'
- 风险: 只是临时释放空间。如果容器持续输出日志,文件会再次增大。不清空源头(未配置轮转)问题会重现。
 
- 查找日志路径:
- 根治方案 (推荐):重建容器- 记录容器配置:使用 docker inspect查看完整配置,或借助工具runlike(docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike <container-id>) 生成等效的docker run命令。
- 停止并删除旧容器:1 
 2docker stop <container-id> 
 docker rm <container-id>
- 使用记录的命令重新创建容器,并在 docker run命令中加入--log-opt max-size和--log-opt max-file参数。
 
- 记录容器配置:使用 
 
- 临时清理 (应急,谨慎!):
其他日志驱动概览 (按需选择)
| 驱动名称 | 原理简述 | 主要优点 | 主要缺点/考量 | 适用场景 | 
|---|---|---|---|---|
| json-file | 写日志到宿主机 JSON 文件 | 简单, docker logs可用 | 必须手动配置轮转! | 开发、测试、需 docker logs | 
| journald | 发送日志到宿主 Systemd Journal | 集成系统日志,自带轮转管理 | 需 Systemd 系统,需学 journalctl | Systemd Linux 宿主机 | 
| syslog | 转发日志到 Syslog 服务器 | 集中收集,利用现有设施 | 需配置维护 Syslog 服务 | 集成到现有 Syslog 环境 | 
| fluentdgelfawslogssplunk等 | 发送到外部日志收集/分析平台 | 强大分析、存储、可视化;卸载本地存储 | 配置较复杂,依赖外部服务/网络 | 生产环境、大规模、云环境、需集中日志分析 | 
配置建议与最佳实践
- 必须配置轮转: 无论使用哪种驱动(特别是 json-file),绝不能依赖默认的无限制设置。
- json-file轮转参数参考:- 开发环境: max-size=5m,max-file=2-3(总量 ~10-15MB)
- 测试环境: max-size=10m-20m,max-file=3-5(总量 ~30-100MB)
- 生产环境: max-size=50m-100m,max-file=5-10(总量 ~250MB-1GB)。核心应用取高值。 强烈建议启用compress: "true"。
 
- 开发环境: 
- 优先全局配置 (daemon.json): 设置合理的全局默认值 (json-file+max-size+max-file+compress),防止遗漏。这是最保险的方式。
- 按需覆盖: 对特殊需求的容器,在 docker run或docker-compose.yml中覆盖全局默认值。
- docker-compose.yml配置示例:- 1 
 2
 3
 4
 5
 6
 7
 8
 9- services: 
 my-service:
 image: your-image:tag
 logging:
 driver: json-file
 options:
 max-size: "50m"
 max-file: "5"
 compress: "true"
- 谨慎操作:- 避免 --log-driver=none: 这会禁用docker logs和所有 stdout/stderr 捕获,极度不推荐,除非应用有完善的自定义日志机制。
- 批量清理 (find ... -exec truncate ...) 仅用于紧急救援,且务必评估风险。 清空后必须立即配置轮转。
 
- 避免 
- 监控:- 监控宿主机关键分区(/,/var,/var/lib/docker)的磁盘使用率。
- 设置磁盘空间告警阈值(如 80%)。
- (可选) 监控重要容器日志文件大小。
 
- 监控宿主机关键分区(
- 驱动选择:- 中小规模/简单环境:json-file+ 轮转 或journald(Systemd 系统)。
- 生产/大规模/云环境:强烈推荐 fluentd,gelf,awslogs等驱动接入集中式日志平台 (ELK, Loki, Splunk, CloudWatch Logs 等),解决本地存储限制并提供强大分析能力。
 
- 中小规模/简单环境:
总结:
Docker 默认日志配置存在磁盘耗尽风险。核心解决方案是为 json-file 驱动配置 max-size 和 max-file 日志轮转。最佳实践是修改 /etc/docker/daemon.json 设置全局默认轮转参数,并根据需要为特定容器覆盖配置。对于已存在的“日志大户”,重建容器是根治方案。生产环境应优先考虑将日志发送到集中式管理平台。定期检查磁盘和日志配置是维护健康 Docker 环境的关键步骤。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 羽墨!
 评论




