[故障排查] Docker 容器日志导致磁盘爆满的排查与日志轮转策略 (Portainer)
# [故障排查] Docker 容器日志导致磁盘爆满的排查与日志轮转策略 (Portainer)
# 1. 问题描述 (Issue Description)
故障现象:监控系统报警显示服务器磁盘(Root Partition /)使用率达到 100%。
初步分析:服务运行缓慢,部分写入操作失败。经排查,发现 Docker 存储目录下存在单文件占用高达 9.4G 的异常情况。
# 2. 排查过程 (Diagnosis)
# 2.1 磁盘空间分布分析
首先通过 df 确认挂载点,随后使用 du 结合管道命令对目录进行层级扫描,快速定位大文件路径。
# 1. 确认磁盘整体使用情况
df -h
# 2. 定位根目录下的一级子目录占用,按大小降序排列
du -sh /* | sort -hr
# 3. 递归定位具体文件(最终定位到 Docker 容器目录)
# 路径示例:/var/lib/docker/containers/{container_id}/
9.4G /var/lib/docker/containers/51f588d6.../51f588d6...-json.log
2
3
4
5
6
7
8
9
10
# 2.2 关联容器身份
通过文件名中的 Container ID 反查具体的业务容器:
docker ps -a --filter "id=51f588d6"
# 输出结果确认是某个长期运行的核心业务服务
2
3
# 3. 原因分析 (Root Cause Analysis)
核心原因:Docker 默认的日志驱动是 json-file。在该模式下,容器内标准输出(STDOUT)和标准错误(STDERR)的所有日志都会被 Docker 守护进程捕获并写入到上述 JSON 文件中。
缺省行为:Docker 默认配置未限制日志文件的大小和数量。对于高并发或开启了 Debug 模式的长期运行容器,该日志文件会无限增长,最终耗尽宿主机磁盘 inode 或空间。
# 4. 紧急处置 (Immediate Mitigation)
在生产环境中,严禁直接使用 rm 命令删除日志文件。
- 风险:Docker 进程持有该文件的句柄(File Handle)。直接删除文件后,文件系统层面的空间不会立即释放,且可能导致 Docker logging driver 异常,必须重启 Docker Daemon 才能修复。
正确方案:使用重定向操作符截断文件内容(Truncate)。
# 将空字符重定向至日志文件,瞬间释放磁盘空间
echo "" > /var/lib/docker/containers/51f588d6.../51f588d6...-json.log
2
3
执行后再次运行 df -h,确认空间已释放,服务恢复正常。
# 5. 长期解决方案 (Permanent Solution)
为防止问题复发,必须配置 Log Rotation (日志轮转) 策略。本文主要介绍基于 Portainer 的两种配置方式。
# 5.1 方案 A:针对单容器配置 (Portainer GUI)
适用于手动管理的独立容器。
- 进入 Portainer,选择目标容器,点击 Duplicate/Edit(注意:此操作将重建容器)。
- 定位至 Advanced container settings -> Logging。
- Driver 保持为
json-file。 - 添加 Options 键值对:
max-size:100m(限制单文件最大 100MB)max-file:3(滚动保留最近 3 个文件)
- 点击 Deploy the container 并选择 Replace。
# 5.2 方案 B:针对 Stack 配置 (Docker Compose)
适用于微服务架构,推荐使用 IaC (Infrastructure as Code) 方式管理。在 Stack 的 YAML 文件中显式声明 logging 配置。
version: '3'
services:
app-service:
image: your-image:latest
restart: always
# 添加日志轮转配置
logging:
driver: "json-file"
options:
max-size: "100m" # 单个日志文件大小上限
max-file: "3" # 保留的日志文件数量
2
3
4
5
6
7
8
9
10
11
12
点击 Update the stack,Portainer 将自动重建容器并应用新策略。
# 6. 最佳实践 (Best Practices)
除了针对单个容器配置外,建议在服务器初始化阶段修改 Docker Daemon 的全局配置,为所有新容器设置默认兜底策略。
修改文件:/etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "500m",
"max-file": "3"
}
}
2
3
4
5
6
7
8
修改后需执行 systemctl restart docker 生效。注意:全局配置仅对新建容器生效,已存在的容器仍需按上述方案重建。
总结:容器日志管理是 DevOps 运维中容易被忽视的一环。通过配置 max-size 和 max-file,可以有效避免因日志失控导致的“磁盘雪崩”事故,保障系统稳定性。