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
7docker 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 环境 |
fluentd gelf awslogs splunk 等 |
发送到外部日志收集/分析平台 | 强大分析、存储、可视化;卸载本地存储 | 配置较复杂,依赖外部服务/网络 | 生产环境、大规模、云环境、需集中日志分析 |
配置建议与最佳实践
- 必须配置轮转: 无论使用哪种驱动(特别是
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
9services:
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 许可协议。转载请注明来自 羽墨!
评论