Linux / Docker 磁盘空间排查 SOP

一、发现磁盘空间不足

首先查看文件系统整体使用情况:

1
df -h

重点关注:

1
2
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3 20G 16G 4.0G 80% /

各列含义:

字段 含义
Filesystem 文件系统 / 分区
Size 总容量
Used 已使用
Avail 可用空间
Use% 使用率
Mounted on 挂载目录

通常重点关注 /

1
/dev/sda3  20G  16G  4G  80% /

表示根文件系统总共 20G,已经使用 16G,还剩 4G。


二、找到哪个目录占空间

df 只能告诉我们:

磁盘快满了。

接下来需要使用 du 找出:

到底是谁占了空间。

执行:

1
du -xh --max-depth=1 / 2>/dev/null | sort -h

例如:

1
2
3
4
5
500M    /root
1.2G /home
2.0G /usr
7.0G /var
12G /

从大的目录开始继续向下排查。

例如 /var 最大:

1
du -xh --max-depth=1 /var 2>/dev/null | sort -h

然后继续:

1
du -xh --max-depth=1 /var/lib 2>/dev/null | sort -h

基本原则:

哪个目录大,就进入哪个目录继续查。


三、如果发现 Docker 占用较大

Docker 默认的数据目录通常是:

1
/var/lib/docker

查看:

1
du -xh --max-depth=1 /var/lib/docker 2>/dev/null | sort -h

可能看到:

1
2
3
50M     /var/lib/docker/volumes
2.5G /var/lib/docker/containers
3.0G /var/lib/docker

如果 containers 很大,需要重点检查 Docker 日志。


四、检查 Docker 日志

Docker 使用 json-file 日志驱动时,容器日志通常位于:

1
/var/lib/docker/containers/

检查所有容器日志大小:

1
find /var/lib/docker/containers/ -name "*-json.log" -exec du -h {} + | sort -h

例如:

1
2
3
4
8.0K    xxx-json.log
20K xxx-json.log
150M xxx-json.log
2.5G xxx-json.log

如果某个日志达到几百 MB、几个 GB:

基本可以确定它是磁盘空间的重要来源。


五、找到日志对应的容器

先查看容器:

1
docker ps --no-trunc --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}'

如果已经知道容器 ID,也可以:

1
docker inspect 容器ID --format '{{.Name}}'

例如:

1
docker inspect abcdef123456 --format '{{.Name}}'

六、查看容器最近日志

确认是哪个服务后:

1
docker logs --tail 100 容器名

或者:

1
docker logs --tail 200 容器名

检查是否存在:

  • 大量重复日志
  • 高频 ERROR
  • 连接不断重试
  • DEBUG 日志过多
  • 某个异常持续刷屏

如果日志本身没有异常,只是长期积累,也应该配置日志轮转。


七、临时清理超大的 Docker 日志

确认日志不需要保留后,可以清空日志文件:

1
truncate -s 0 /var/lib/docker/containers/容器ID/容器ID-json.log

然后重新检查:

1
df -h

为什么使用 truncate

推荐:

1
truncate -s 0 xxx-json.log

不推荐直接:

1
rm xxx-json.log

因为 Docker 进程可能仍然持有这个日志文件。

truncate 的作用是:

保留文件本身,只把文件内容清空。

这是处理正在使用中的日志文件更稳妥的方式。


八、根本解决:配置 Docker 日志轮转

仅仅清空日志只是临时解决。

如果不限制日志大小,以后还会重新增长。

docker-compose.yml 中可以配置:

1
2
3
4
5
6
7
8
services:
app:
image: example/image
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

含义:

1
max-size: 10m

单个日志文件最大 10MB。

1
max-file: 3

最多保留 3 个日志文件。

这样可以避免:

某个容器日志无限增长 → 最终把整个 VPS 磁盘塞满。

修改 Compose 后重新创建容器:

1
docker compose up -d --force-recreate

九、检查 Docker 镜像、容器、Volume

使用:

1
docker system df

例如:

1
2
3
4
5
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images 6 6 3.2GB 0B
Containers 6 6 50MB 0B
Local Volumes 10 2 500MB 400MB
Build Cache 0 0 0B 0B

重点看:

Images

如果:

1
2
3
6 个镜像
6 个正在使用
0B 可回收

说明这些镜像目前都在使用。

不要为了释放空间强行删除。

Volumes

如果存在大量:

1
RECLAIMABLE

可以进一步检查未使用的 Volume。

Build Cache

如果 Build Cache 很大,可以考虑清理。


十、Docker 清理命令

查看情况后,再决定是否清理。

清理无用容器:

1
docker container prune

清理无用镜像:

1
docker image prune

清理无用网络:

1
docker network prune

清理无用 Volume:

1
docker volume prune

综合清理:

1
docker system prune

注意

不要上来就:

1
docker system prune -a

更不要直接删除:

1
/var/lib/docker

清理前先确认哪些资源正在使用。


十一、注意 overlay

执行:

1
df -h

Docker 环境中可能出现很多:

1
2
3
overlay    20G   16G   4G   80%   /var/lib/docker/...
overlay 20G 16G 4G 80% /var/lib/docker/...
overlay 20G 16G 4G 80% /var/lib/docker/...

不要认为:

1
3 个 overlay × 16G = 48G

这是错误的。

这些 overlay 通常共享同一个底层文件系统。

真正的磁盘仍然是:

1
/dev/sda3

所以:

df 中出现多个 overlay,不代表磁盘被重复占用。


十二、dfdu 的区别

这是最值得记住的一组命令。

df

1
df -h

回答:

文件系统还有多少空间?

du

1
du -xh --max-depth=1 /

回答:

哪些目录占用了空间?

Docker

1
docker system df

回答:

Docker 的镜像、容器、Volume、Build Cache 各占多少?

可以记成:

1
2
3
4
5
6
7
8
9
10
11
df

磁盘还有多少?

du

谁占了这些空间?

docker system df

Docker 自己占了多少?

十三、完整排查流程

以后遇到:

VPS 磁盘快满了

直接按照下面顺序执行。

① 看整体

1
df -h

② 找一级大目录

1
du -xh --max-depth=1 / 2>/dev/null | sort -h

③ 对最大的目录继续查

1
du -xh --max-depth=1 /某个大目录 2>/dev/null | sort -h

④ 如果 Docker 较大

1
du -xh --max-depth=1 /var/lib/docker 2>/dev/null | sort -h

⑤ 如果 containers 较大

1
find /var/lib/docker/containers/ -name "*-json.log" -exec du -h {} + | sort -h

⑥ 找到对应容器

1
docker ps --no-trunc --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}'

⑦ 检查日志

1
docker logs --tail 100 容器名

⑧ 必要时清理日志

1
truncate -s 0 /var/lib/docker/containers/容器ID/容器ID-json.log

⑨ 检查 Docker 垃圾

1
docker system df

⑩ 最后确认

1
df -h

十四、一句话记忆

磁盘满了先 df,找到谁大用 du,发现 Docker 再查 docker system df,Docker 的 containers 大就查 json.log

最核心的四条:

1
2
3
4
5
6
7
df -h

du -xh --max-depth=1 / 2>/dev/null | sort -h

docker system df

find /var/lib/docker/containers/ -name "*-json.log" -exec du -h {} + | sort -h

遇到磁盘空间问题,不要猜,按“整体 → 目录 → Docker → 日志”的路径一层层定位。