Docker 容器运行稳定,并不代表宿主机磁盘一定安全。许多磁盘空间告警都与容器持续输出日志、日志驱动缺少轮转配置有关。尤其是默认使用 json-file 时,如果没有设置容量上限,高频访问日志、异常堆栈或调试信息可能不断累积,最终影响镜像拉取、容器启动,甚至拖垮整台主机。下面从配置、排查和治理三个方面给出一套可直接执行的处理思路。🔍
一、先了解 Docker 日志驱动
Docker 会收集容器进程写入标准输出和标准错误的内容,再交给日志驱动处理。常见驱动包括 json-file、local、journald、syslog、fluentd、gelf 以及云平台提供的日志驱动。可以执行 docker info | grep "Logging Driver" 查看守护进程的默认日志驱动,也可以执行 docker inspect 容器名或ID,检查具体容器的 HostConfig.LogConfig 配置。
Docker 默认通常使用 json-file 驱动,将每个容器的日志保存为 JSON 格式文件。该驱动便于配合 docker logs 查看内容,但默认不会主动限制日志总量。Docker 官方因此建议根据运行环境配置轮转,或者采用默认具备轮转能力、存储格式更高效的 local 驱动。相关说明可参考 Docker 日志驱动配置文档。citeturn1search2
二、配置 json-file 日志轮转
如果现有运维流程依赖 docker logs,可以继续使用 json-file,并在 Docker 守护进程配置文件中设置 max-size 和 max-file。Linux 环境通常编辑 /etc/docker/daemon.json,加入 log-driver 为 json-file,同时在 log-opts 中配置 max-size 为 10m、max-file 为 3。其中 max-size 表示单个日志文件达到指定大小后触发轮转,max-file 表示最多保留的日志文件数量。
配置示意:log-driver 使用 json-file;log-opts 中设置 max-size 为 10m,max-file 为 3。daemon.json 内的日志选项值应使用字符串形式。
修改完成后,可先使用 dockerd --validate --config-file=/etc/docker/daemon.json 检查配置,再根据业务窗口重启 Docker 服务。需要注意,守护进程级别的新配置只会自动应用于之后创建的容器,已经存在的容器不会直接继承,因此通常需要重新创建相关容器。具体参数含义可查阅 json-file 官方文档。citeturn1search1
三、考虑改用 local 驱动
如果没有兼容旧环境或特殊采集工具的限制,可以将默认日志驱动设置为 local。该驱动支持日志轮转,同时采用更节省磁盘空间的存储方式,并且仍然可以使用 docker logs 查看日志。配置时,在 daemon.json 中将 log-driver 设置为 local,也可以通过 log-opts 根据磁盘容量和日志保留要求调整单文件大小及保留数量。
选择驱动时不要只看存储空间,还要考虑日志查询方式。如果日志需要集中发送到 Elasticsearch、Loki、Splunk、云日志平台或 syslog 服务,应结合现有采集链路选择对应驱动,并验证网络异常时的缓存、阻塞和丢失策略。生产环境最好保留本地短期排障能力,同时将重要日志发送到独立平台。📦
四、定位哪些容器正在吞噬磁盘
- 确认磁盘占用:执行 df -h 检查 Docker 数据目录所在分区,判断是否已经接近容量上限。
- 确认 Docker 根目录:执行 docker info,查看 Docker Root Dir,避免误以为数据一定存放在 /var/lib/docker。
- 查找大日志:在 Docker 根目录的 containers 子目录中,使用 du、find 或 ls 按文件大小排序,重点关注名称以 json.log 结尾的文件。
- 映射容器身份:日志目录通常以完整容器 ID 命名,可通过 docker ps --no-trunc 将目录 ID 与容器名称、镜像和运行状态对应起来。
- 检查输出速率:执行 docker logs --since 10m --timestamps 容器名,观察最近日志是否持续刷屏,并结合应用访问量判断是否异常。
定位到大文件后,还要继续分析源头。常见原因包括应用开启调试级别、接口异常导致堆栈反复输出、健康检查请求被完整记录、重试逻辑没有退避、数据库连接失败形成循环告警,以及访问日志记录了大量低价值请求。只删除日志文件而不修复输出源,磁盘占用很快还会再次增长。⚠️
五、磁盘告急时如何应急处理
当磁盘空间已经影响服务时,应先控制日志源,例如临时调整应用日志级别、停止异常容器或限制流量。随后再释放空间。对于正由 Docker 管理的 json-file 日志,不建议直接删除文件,也不建议使用外部工具擅自轮转,因为这可能干扰 Docker 对文件句柄和日志状态的管理。官方同样提示,此类文件应由 Docker 守护进程负责访问和维护。citeturn1search1
紧急情况下,如果已经确认日志可以丢弃,可对目标日志文件进行安全截断处理,并立即补充轮转配置、重新创建容器。操作前应核对容器 ID、文件路径和审计要求,重要故障日志则应先复制到其他磁盘或上传至集中日志平台。不要执行未经筛选的批量删除命令,以免误删容器元数据或仍需保留的证据。
六、建立长期防护机制
- 为所有生产主机统一设置默认日志驱动和轮转上限,避免依赖人工配置。
- 在 Compose 文件或部署平台中显式声明 logging 配置,减少不同环境之间的行为差异。
- 监控磁盘使用率、剩余空间、日志增长速率和异常日志数量,并设置分级告警。
- 应用默认使用 info 或 warn 级别,调试日志开启后应设置明确的关闭时间。
- 对重复异常增加采样、限频或聚合机制,避免同一错误每秒输出大量相同内容。
- 定期检查新建容器是否已继承正确配置,并通过故障演练验证轮转和集中采集链路。
总结
Docker 日志文件过度增长,表面上是磁盘问题,根因通常是日志驱动未限制、应用输出失控或监控缺失。可靠的治理顺序应是:先确认日志驱动,再定位大文件与对应容器,随后控制异常输出,最后通过 json-file 轮转、local 驱动或集中日志平台建立长期机制。只要把容量限制、应用日志策略和磁盘监控同时纳入日常运维,就能显著降低容器日志撑满宿主机的风险。✅