一次 Docker 磁盘占用排查与迁移的完整复盘
本文记录了一次 Docker 磁盘占用排查与迁移的完整复盘。
一、问题背景
服务器磁盘分布大致如下:
- 系统盘:
/dev/vda1,40G,挂载/ - 数据盘:
/dev/vdb1,493G,挂载/data
初始现象是:
/分区使用率偏高/var/lib/docker/overlay2显示挂载在根分区- 怀疑 Docker 镜像或容器占用了大量系统盘空间
二、Docker 磁盘占用的正确查看方式
1. 系统层面(df)
bash
df -h
如果看到类似:
text
overlay 40G 20G 18G 54% /var/lib/docker/overlay2/.../merged
不要误判 :
这并不是 Docker 独占 40G,而是 overlayfs 映射了宿主机根分区。
2. Docker 视角(关键命令)
基础统计
bash
docker system df
详细拆分(强烈推荐)
bash
docker system df -v
你可以精确看到:
-
每个镜像的:
- SIZE
- SHARED SIZE
- UNIQUE SIZE
- 是否被容器使用
-
构建缓存(Build Cache)的真实占用
-
容器自身的写层大小
三、为什么会看到大量 <none> 镜像?
示例:
text
<none> <none> 554MB
<none> <none> 554MB
...
这些并不是"异常镜像",而是悬空镜像(dangling images)。
产生原因总结
- 多次
docker build,旧镜像标签被新镜像覆盖 - 构建中间层未被任何镜像引用
- CI / 自动构建未做清理策略
本质上:
Docker 很保守,不会自动删除历史构建产物
四、Docker 构建缓存(Build Cache)才是"隐形大户"
在一次排查中发现:
text
Build cache usage: 11.56GB
而镜像 + 容器加起来不到 1GB。
这类缓存来自:
docker build- BuildKit
- 多阶段构建的中间层
清理方式
bash
docker builder prune
如果你想彻底清:
bash
docker system prune -a
⚠️ 注意:
这会删除所有未被容器使用的镜像。
五、Docker 数据目录迁移的正确姿势(简版)
以下步骤在 Docker 已停止 的前提下进行
1. 停止 Docker
bash
systemctl stop docker
2. 拷贝数据(推荐 rsync)
bash
rsync -a /var/lib/docker/ /data/docker/
3. 修改配置
bash
vim /etc/docker/daemon.json
json
{
"data-root": "/data/docker"
}
4. 启动 Docker
bash
systemctl start docker
5. 验证
bash
docker info | grep "Docker Root Dir"
参考资料
-
Docker 官方文档 · 磁盘使用分析(docker system df)
Docker 官方对镜像、容器、卷、构建缓存磁盘占用的说明。
https://docs.docker.com/engine/reference/commandline/system_df/ -
Docker 官方文档 · 清理未使用资源(prune)
详细说明
docker image prune、docker builder prune、docker system prune的行为差异与风险。
https://docs.docker.com/engine/reference/commandline/system_prune/ -
Docker 官方文档 · BuildKit 与构建缓存
解释 Build Cache 的来源、生命周期以及为何会大量占用磁盘。
https://docs.docker.com/build/cache/ -
Docker 官方文档 · daemon.json 配置项说明
包含
data-root(Docker 数据目录迁移)的官方定义与示例。
https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
