DockerDaemon日志滚动策略与磁盘溢出预防

dockerd日志不自动轮转导致磁盘占满,需禁用stdout重定向、启用journald或配置logrotate;容器日志须通过daemon.json设置json-file或local驱动的max-size/max-file限制,否则/var/lib/docker/containers下残留日志会持续增长。

dockerdaemon日志滚动策略与磁盘溢出预防

dockerd 日志不自动轮转,磁盘被 /var/log/docker.log 填满

默认情况下,dockerd 自身输出的日志(即 systemd 管理的守护进程日志)**不会自动滚动或压缩**,全量写入 /var/log/docker.log 或直接由 journald 接管——但若你手动重定向了 stdout/stderr 到文件,就极易失控。

常见错误现象:df -h 显示 / 分区 100%;ls -lh /var/log/docker.log 发现文件超 10GB;journalctl -u docker 查不到近期记录(说明日志被重定向到文件且没管控)。

  • 确认日志去向:运行 ps aux | grep dockerd,看是否带 > /var/log/docker.log 2>&1 类重定向
  • 若用 systemd 启动,优先交由 journald 管理,**不要自行重定向 stdout**;改用 journalctl -u docker --since "2 weeks ago" 查日志
  • 如确需落盘文件,必须配 logrotate:新建 /etc/logrotate.d/docker-daemon,内容包含 /var/log/docker.log { rotate 7 daily compress missingok notifempty }

logrotate 配置后仍不生效,logrotate -d /etc/logrotate.d/docker-daemon 报错

logrotate 调试模式(-d)只模拟,不真正轮转;但报错说明配置语法或路径权限有问题,常见于路径不存在、用户无读写权、或 glob 匹配失败。

使用场景:你已写了配置,但 docker.log 还在疯长,logrotate -f 手动触发也无效。

  • 确保 /var/log/docker.log 文件存在且属主为 rootdockerd 通常以 root 运行)
  • 检查配置中路径是否拼错,比如写成 /var/log/docker/docker.log 却实际是 /var/log/docker.log
  • logrotate 默认以 root 身份运行,但如果配置里写了 su docker docker,而 docker 用户无权读写该日志,就会静默失败
  • dateextdateformat -%Y%m%d 可避免覆盖,但注意 compress 依赖 gzip 是否安装

启用 journald 的日志大小限制后,docker logs <container> 仍查不到旧记录

docker logs 查的是容器内应用 stdout/stderr,和 dockerd 守护进程日志完全无关。journald 限的是 docker.service 的 journal 日志,不影响容器日志存储逻辑。

闪念贝壳

闪念贝壳是一款AI 驱动的智能语音笔记,随时随地用语音记录你的每一个想法。

下载

性能影响:journald 默认不限大小,长期运行后 /run/log/journal//var/log/journal/ 可能占数 GB;容器日志则取决于你用的 log-driver(如 json-file)及其配置。

  • 容器日志控制靠 daemon.json:{"log-driver": "json-file", "log-opts": {"max-size": "10m", "max-file": "3"}}
  • 修改后必须 systemctl restart docker,否则新配置对后续容器生效,旧容器仍沿用启动时配置
  • max-size 是单个日志文件上限(如 10m),不是总大小;max-file: "3" 表示最多保留 3 个轮转文件
  • 注意:json-file 驱动无法压缩,要压缩得换 local 驱动或外接 fluentd

容器日志写满 /var/lib/docker/containers/ 导致磁盘爆掉

这是最常被忽略的溢出点:每个容器的 json-file 日志默认存在 /var/lib/docker/containers/<id>/<id>-json.log,且**不随容器删除自动清理**——哪怕容器 rm -f 了,日志文件还在。

容易踩的坑:以为删容器就等于清日志;或给 max-size 设了 100m 却没设 max-file,结果单个容器日志滚出几十个百兆文件。

  • 清理残留日志:先 docker ps -a -q | xargs -r docker inspect --format='{{.LogPath}}' 2>/dev/null | grep -v "^\s*$" 看哪些日志路径还活着,再结合 find /var/lib/docker/containers/ -name "*-json.log" -size +100M 定位大文件
  • 批量清理已停止容器的日志:find /var/lib/docker/containers/ -name "*-json.log" -mtime +30 -delete(慎用,先 -print 确认)
  • 生产环境建议统一用 local 驱动:{"log-driver": "local", "log-opts": {"max-size": "10m", "max-file": "5", "compress": "true"}},它原生支持压缩和更准的磁盘用量控制

最麻烦的不是配错,而是配了但没验证——上线前务必跑一个长周期日志生成容器,盯 24 小时磁盘增长和轮转行为。

已有 2960 条评论

    1. 东方不败 东方不败

      用docker三年,今天才知道有这么多日志管理的细节,惭愧

    2. BrianJohnson BrianJohnson

      Clear, concise, and practical. Exactly what I needed.

    3. 洪七公 洪七公

      删容器不清日志这个设计真坑,还好有解决方案

    4. MeganScott MeganScott

      Thanks for the reminder to always verify configurations after deployment.

    5. 令狐冲 令狐冲

      max-file设多少合适?要根据业务日志量评估吗?

    6. ThomasEdison ThomasEdison

      Very thorough explanation. This should be in the official Docker docs.

    7. 黄蓉 黄蓉

      如果同时用了ELK,本地还需要保留日志文件吗?

    8. PeterJackson PeterJackson

      The performance impact note about journald default limits is spot on.

    9. 郭靖 郭靖

      干货!转发到我们运维群了

    10. DianaRoss DianaRoss

      I didn't know containers kept logs after removal. That explains a lot!

    11. 杨过 杨过

      建议补充一下如何监控日志大小并自动告警