Docker 容器日志占满磁盘的解决办法
上周一台跑了三个月的机器突然告警,SSH 上去一看:df -h 根分区 100%。du -sh /* 一路查下来,元凶是 /var/lib/docker/containers/ —— 某个容器的 json 日志文件涨到了 40 多 GB。
根因:json-file 默认无限制
Docker 默认的日志驱动是 json-file,而且默认不做轮转。容器只要不停地打日志(尤其是开了 debug 的应用),这个文件就会无限增长,直到把宿主机磁盘吃光。更坑的是,删文件都没用——进程还 holding 着句柄,得重启容器才释放。
先应急,找出罪魁祸首:
du -sh /var/lib/docker/containers/*/*-json.log | sort -rh | head -5
解法一:全局配置日志轮转(推荐)
改 /etc/docker/daemon.json,对所有新容器生效:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "3"
}
}
意思是单个日志文件最大 50MB,保留 3 个轮转文件,一个容器最多占 150MB。改完 systemctl restart docker 生效(会重启所有容器,挑业务低峰操作)。
解法二:单个容器指定
如果不想动全局配置(比如宿主机上还有别人的容器),起容器时单独指定:
docker run -d \
--log-driver json-file \
--log-opt max-size=50m \
--log-opt max-file=3 \
--name myapp myimage
docker-compose 也一样,在 service 下加:
logging:
driver: json-file
options:
max-size: "50m"
max-file: "3"
已经爆了的怎么清理
先别直接 rm 日志文件(句柄问题)。正确姿势:
# 1. 先把解法一或二配上
# 2. 重启出问题的容器,旧的大日志文件会被轮转机制接管
docker restart <container_id>
# 3. 确认
du -sh /var/lib/docker/containers/*/*-json.log | sort -rh | head -3
教训:任何长期运行的 Docker 宿主机,daemon.json 里都应该有 log-opts。这是装机必备项,和换 apt 源一个优先级。
进阶:根本不想存本地日志
如果用了 ELK / Loki,直接把 log-driver 换成对应的驱动,日志根本不落本地盘。这属于架构升级了,本文不展开。
总结一句话:Docker 日志默认无上限,生产环境必须配 max-size。别等磁盘满了才想起来。