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. MichelleAdams MichelleAdams

      I appreciate the debugging commands included throughout the article.

    2. 乔治 乔治

      测试环境还好,生产环境一定要配好日志策略,不然后果很严重

    3. AllenBlack AllenBlack

      compress参数在json-file驱动下无效,换local驱动才生效,这点很重要

    4. NancyWhite NancyWhite

      The note about su user in logrotate config saved me! I had that exact problem.

    5. 周星星 周星星

      journalctl -u docker这个命令一直不知道怎么用,原来要看dockerd本身的日志

    6. KevinBrown KevinBrown

      Very detailed explanation. Saved to my bookmarks.

    7. 程序员老王 程序员老王

      每次磁盘报警都是docker日志的锅,这篇文章可以当应急预案手册了

    8. SophieMiller SophieMiller

      We switched to fluentd for centralized logging after similar disk issues.

    9. TomHanks TomHanks

      "最麻烦的不是配错,而是配了但没验证" - 这句话说得太对了!

    10. 赵四儿 赵四儿

      请问如果我用rancher管理容器,日志策略应该在哪里配?

    11. LisaWang LisaWang

      用local驱动配合compress真的太香了,比json-file省一半空间