导读:本期聚焦于松松建站创作的《Docker容器日志膨胀怎么办?用logrotate实现日志自动切割与清理》,敬请观看详情。容器运行久了日志文件动辄几个G,磁盘被占满导致服务异常的情况并不少见。本文介绍如何借助logrotate对容器产生的日志做定期切割、压缩和清理,内容包括Docker默认json-file日志驱动的配置限制、logrotate的安装与配置文件写法、如何配合宿主机cron定时执行、以及针对挂载目录日志的完整配置示例。同时对比了Docker自带的max-size方案与logrotate方案的适用场景,帮你根据实际情况选择合适的日志管理策略,避免磁盘被日志拖垮。

Docker容器用久了,很多人都会遇到同一个问题:磁盘空间莫名被吃掉几十个G,一查发现是/var/lib/docker/containers下面的json日志文件在疯狂膨胀。容器的stdout输出全部会写进这些json-file日志里,如果应用本身打日志很勤快,又没做任何限制,单个日志文件涨到十几G都很常见。本文介绍如何用logrotate这套老牌的日志管理工具来解决容器日志的切割与清理问题。

Docker容器日志膨胀怎么办?用logrotate实现日志自动切割与清理

先了解Docker默认的日志机制

Docker默认使用json-file日志驱动,容器的标准输出和标准错误都会被写入宿主机上的一个json文件中,路径类似/var/lib/docker/containers/<容器ID>/<容器ID>-json.log。很多初学者以为日志在容器内部,其实不然,真正落盘的位置在宿主机上。

这个默认行为本身没有任何大小限制,也就是说容器只要一直跑、一直输出,日志就会无限增长。Docker其实提供了原生的控制参数,可以在daemon.json或者docker run时直接设置:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "3"
  }
}

修改之后重启Docker服务生效。这个方案简单直接,对新建的容器立即起作用。但它也有局限:一是只对新容器生效,已经存在的旧容器需要重建;二是它只做切割不做压缩,占用的磁盘空间依然不小;三是日志轮转的粒度固定,没法按天、按周来组织日志文件。而logrotate在这些方面都更灵活。

用logrotate管理容器日志的完整配置

logrotate是Linux下最经典的日志轮转工具,绝大多数发行版都自带,如果没有可以用包管理器装一下:yum install logrotate或者apt-get install logrotate。它的配置文件放在/etc/logrotate.d/目录下,每个应用一个独立的配置文件,互不干扰。

针对Docker容器日志,可以新建一个配置文件/etc/logrotate.d/docker-containers,内容如下:

/var/lib/docker/containers/*/*.log {
  rotate 7
  daily
  compress
  size 100M
  missingok
  delaycompress
  copytruncate
  dateext
  dateformat -%Y%m%d-%s
}

各项参数的含义值得逐个说明。rotate 7表示最多保留7份历史日志,超出的自动删除;daily指定每天切割一次,也可以换成weeklymonthlycompress开启gzip压缩,配合delaycompress可以让最近一次切割的日志延迟一天再压缩,方便排查问题;size 100M表示单文件超过100M也触发切割,和daily是或的关系;missingok让日志文件不存在时不报错;dateextdateformat让切割后的文件带上日期后缀,便于辨认。

最关键的是copytruncate这个参数。容器正在运行时,Docker守护进程持有日志文件的句柄,如果直接把日志文件改名或删除,Docker还会继续往原句柄写入,导致空间不释放。copytruncate的处理方式是先复制一份副本,再把原文件清空,这样句柄不受影响,容器无感知。它的缺点是复制和清空之间存在一个极小的时间窗口,可能丢失几行日志,对绝大多数业务来说可以接受。

配合定时任务与挂载目录日志的处理

logrotate本身不负责定时执行,它依赖cron来触发。多数系统安装后已经自带了/etc/cron.daily/logrotate这个脚本,每天自动跑一次。如果需要更频繁的轮转,比如每小时检查一次,可以自己在crontab里加一条:

# 每小时执行一次日志轮转检查
0 * * * * /usr/sbin/logrotate /etc/logrotate.conf

执行完可以手动验证一下配置是否正确:logrotate -d /etc/logrotate.d/docker-containers是dry-run模式,只打印将要执行的动作不实际操作;去掉-d参数改为-f则强制立即执行一次轮转,方便确认效果。

除了Docker自管理的json日志,实际项目中更常见的还有容器通过volume挂载到宿主机的应用日志,比如把/app/logs挂到宿主机的/data/myapp/logs。这类日志同样可以用logrotate管理,配置方式完全一样,只需把路径换掉:

/data/myapp/logs/*.log {
  rotate 14
  daily
  compress
  missingok
  notifempty
  copytruncate
}

notifempty表示日志为空文件时跳过轮转,避免产生一堆无意义的空压缩包。如果应用支持发送信号重新打开日志文件(比如Nginx收到USR1信号会重开日志),也可以不用copytruncate,改用postrotate脚本来处理,这样能做到日志零丢失:

/data/myapp/logs/*.log {
  daily
  rotate 14
  compress
  missingok
  sharedscripts
  postrotate
    docker exec myapp nginx -s reopen > /dev/null 2>&1 || true
  endscript
}

sharedscripts保证多个日志文件匹配时脚本只执行一次,postrotate里的命令在轮转完成后运行,通过docker exec通知容器内的应用重新打开日志句柄。

两种方案怎么选

一般来说,如果是简单的场景、只想防止磁盘被打爆,直接配置Docker的max-size和max-file就够了,不需要额外装任何东西。但如果需要按日期归档日志、需要压缩节省空间、需要更长的保留周期和更灵活的轮转策略,logrotate明显更合适。两者也可以同时使用:Docker侧设置一个宽松的兜底限制防止极端情况,logrotate侧做精细化的切割归档,这是生产环境中比较稳妥的组合做法。

最后提醒一点,如果使用的是Kubernetes环境,容器日志管理通常交给日志采集 sidecar 或者集群层面的方案来处理,logrotate更适合单机Docker或者小规模自建的场景。工具本身没有绝对的好坏,关键是根据自己的部署形态选择合适的日志管理策略,并养成定期检查磁盘占用的习惯,别等磁盘爆了才想起来日志这回事。

logrotateDocker日志管理容器日志切割修改时间:2026-09-15 17:20:35

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260915/57402.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。