一、为什么容器日志会撑爆磁盘?
想象一下你家的垃圾桶。如果从来不倒垃圾,总有一天会把厨房塞满。Docker容器也是这样,默认情况下它会把所有日志都堆在主机的一个文件里,特别是像Java应用这种话痨,几天就能生成几个G的日志文件。
常见症状包括:
- 服务器突然报"磁盘空间不足"
df -h命令显示/var/lib/docker目录异常膨胀- 容器莫名其妙被OOM(内存不足)杀死
二、Docker自带的日志限制
Docker其实自带了简易的日志控制功能,就像给垃圾桶加了个盖子。在运行容器时可以通过参数控制:
# 技术栈:Docker
# 限制单个日志文件100MB,最多保留3个旧日志
docker run --log-opt max-size=100m --log-opt max-file=3 nginx
参数解释:
max-size:单个日志文件的最大值,到达后自动分割max-file:保留的旧日志文件数量,超出会自动删除最老的
但这种方式有两个不足:
- 不能按时间轮转(比如每天自动分割)
- 所有容器需要单独配置
三、使用logrotate专业方案
Linux自带的logrotate才是真正的"智能垃圾桶管理系统",它能:
- 按时间或大小轮转
- 压缩旧日志节省空间
- 通过cron定时任务自动运行
3.1 配置Docker全局日志策略
# 技术栈:Docker + Linux
# 创建专用配置文件
sudo tee /etc/logrotate.d/docker <<'EOF'
/var/lib/docker/containers/*/*.log {
# 每天轮转一次
daily
# 保留最近7天的日志
rotate 7
# 轮转后延迟压缩(避免影响正在写的日志)
delaycompress
# 使用gzip压缩旧日志
compress
# 如果日志缺失也不报错
missingok
# 轮转后创建新空日志文件
create
# 文件大于100M也触发轮转
size 100M
}
EOF
3.2 手动测试配置
# 强制立即执行轮转测试
sudo logrotate -vf /etc/logrotate.d/docker
你会看到类似这样的输出:
reading config file /etc/logrotate.d/docker
Handling 18 logs
rotating /var/lib/docker/containers/abcd1234/abcd1234-json.log
四、进阶技巧与注意事项
4.1 容器运行时日志驱动选择
Docker支持多种日志输出方式,就像不同的垃圾处理方式:
# 使用系统日志工具(syslog)接管
docker run --log-driver=syslog nginx
# 直接禁用容器日志(极端情况使用)
docker run --log-driver=none alpine
4.2 容器内应用日志的最佳实践
聪明的应用应该自己管理日志:
// 技术栈:Java + Logback
// 在logback.xml中配置滚动策略
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/logs/app.log</file>
<!-- 按日期和大小滚动 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 每天滚动 -->
<fileNamePattern>/logs/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 单个文件最大100MB -->
<maxFileSize>100MB</maxFileSize>
<!-- 保留30天 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
</configuration>
4.3 注意事项清单
- 监控报警:即使有轮转也要监控磁盘使用率
- 日志分级:生产环境建议关闭DEBUG日志
- 集中收集:考虑ELK等方案集中管理日志
- 特殊容器:数据库类容器要特别小心日志配置
五、方案对比与选择建议
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Docker原生配置 | 简单直接 | 功能有限 | 开发测试环境 |
| logrotate | 功能全面 | 需要额外配置 | 生产环境物理机 |
| 应用自身管理 | 最精准控制 | 需要改应用代码 | 可控的自研应用 |
对于大多数场景,我推荐组合方案:
- 使用logrotate作为最后防线
- 重要容器单独配置Docker日志参数
- 关键业务应用实现自己的日志管理
六、遇到问题怎么排查?
如果配置后日志还是疯涨,可以这样排查:
- 先找大文件:
sudo du -h /var/lib/docker | sort -rh | head -n 20
- 检查logrotate是否正常执行:
# 查看最后一次执行时间
grep docker /var/lib/logrotate/status
- 检查容器日志驱动:
docker inspect --format='{{.HostConfig.LogConfig.Type}}' 容器名
记住,好的日志管理就像定期打扫房间,既不能完全不管,也不必过度清洁。找到适合你业务节奏的平衡点最重要。
评论