先定位:确认是容器日志而不是镜像占空间
磁盘告警时别急着删镜像,先确认空间到底被谁吃了。Docker 默认用 json-file 日志驱动,单个容器的日志写在 /var/lib/docker/containers/<容器ID>/<容器ID>-json.log,容器跑得久、输出多,这个文件能涨到几十 GB。
# 看磁盘整体占用
df -h
# 按大小列出所有容器日志文件
sudo du -sh /var/lib/docker/containers/*/*-json.log | sort -rh | head -20
# 查看某个容器日志的实时大小
sudo ls -lh /var/lib/docker/containers/<容器ID>/*-json.log
如果上面这条 du 命令输出不大,但 df 显示已满,那多半是“空间被删了但文件句柄没释放”,常见于日志被 rm 掉而进程还开着文件。用 lsof +L1 查一下被删除但仍占用的文件,这种情况要重启对应容器或进程才真正释放。
应急清理:三种方式按需选
最快的办法是直接清空日志文件内容,而不是删文件。删文件会让 Docker 继续往已删除的 inode 写,du 看不到、df 不下降,反而更难排查。
# 方式一:清空单个容器日志(推荐,立刻回收空间)
sudo truncate -s 0 /var/lib/docker/containers/<容器ID>/<容器ID>-json.log
# 方式二:批量清空所有容器日志
sudo find /var/lib/docker/containers/ -name "*-json.log" -exec truncate -s 0 {} ;
# 方式三:用 docker 命令清(部分版本支持)
docker container logs --tail 0 <容器名> 2>/dev/null
注意:清空日志会丢失历史排查信息,生产环境建议先确认问题已定位或已备份关键片段。批量清空命令要慎重,最好先加 -print 预览命中的文件。
根治:给日志加上大小与数量上限
临时清空只能撑几天,真正的解法是配置日志轮转。Docker 支持在 daemon 级别和容器级别设置 max-size 与 max-file,超过上限自动切割并删除旧文件。
全局配置:编辑 /etc/docker/daemon.json,加入以下内容后重启 Docker。
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
sudo systemctl restart docker
全局配置只对新建容器生效,已有容器需要重建,或者在 docker run / compose 中单独指定:
# docker run 方式
docker run --log-opt max-size=100m --log-opt max-file=3 ...
# docker-compose.yml 方式
services:
app:
image: nginx
logging:
driver: json-file
options:
max-size: "100m"
max-file: "3"
100m × 3 意味着单容器日志最多占 300MB,对大多数业务足够。日志量特别大的服务可以调小到 50m,或改用 local 日志驱动,它在轮转和压缩上更省空间。
清理后的检查清单
- 用
df -h确认根分区或 /var 分区已释放空间; - 用
docker ps确认容器都正常运行,重启 Docker 会短暂中断服务; - 检查 daemon.json 语法,配置写错会导致 Docker 起不来,改前先备份;
- 给磁盘和容器日志加监控,比如定时跑 du 统计并告警,别等写满才发现;
- 如果业务本身日志量大,考虑接入集中式日志系统,把容器日志外送,本地只留少量缓冲。
一句话总结:先 truncate 应急,再用 max-size/max-file 兜底,最后把日志外送和监控补上,才算真正解决。




