Docker镜像存储路径与containerd踩坑总结
背景
在一台磁盘结构如下的机器上:
|
|
目标是让 Docker 的镜像、构建缓存等全部存储到大盘 `/data/disk`,避免占满系统盘。
已经配置:
|
|
但实际现象:
- docker load 后 / 仍然暴涨
- 删除镜像后 / 又恢复
说明:Docker 仍然在往系统盘写数据
结论(核心)
Docker 的 data-root 并不能覆盖全部数据路径。 在新版本架构中,containerd 仍然默认写入 /var/lib/containerd。
Docker 存储架构拆解
Docker 29 之后实际涉及三层:
| 组件 | 默认路径 | 是否受 data-root 控制 |
|---|---|---|
| Docker 元数据 | /data-root | yes |
| 镜像 layer | overlayfs / snapshotter | warning(部分受控) |
| containerd | /var/lib/containerd | no |
关键点:
- docker load 实际写入 containerd content store
- containerd 默认路径在 /var/lib/containerd
- 导致系统盘被占满
问题复现过程
|
|
现象:
- / 使用率飙升(40G → 90%)
- /data/disk 几乎不变
根因分析
docker load 流程:
- 解压 tar
- 写入 containerd content store
- 解压 layer(snapshot)
- Docker 记录 metadata
其中:
|
|
该路径不受 Docker data-root 控制。
解决方案
方案一:迁移 containerd(推荐)
- 停止服务
|
|
- 迁移数据
|
|
- 生成配置
|
|
- 修改路径(可用 sed)
|
|
- 启动服务
|
|
验证
|
|
应输出:
|
|
再次执行:
|
|
预期:
- / 不再增长
- /data/disk 增长
常见坑
1. sed 误修改
错误写法:
|
|
正确写法:
|
|
2. 未停止服务直接修改
会导致:
- 配置不生效
- 数据不一致
3. Docker 内置 containerd
部分环境中 Docker 使用内置 containerd,可能忽略外部配置。
可检查:
|
|
4. 旧数据未清理
|
|
最佳实践(推荐结构)
|
|
总结
Docker data-root 只控制 Docker 本身的数据路径, containerd 需要单独配置,否则仍会占用系统盘。
一句话:
docker load 占满 / 的真正原因,不是 Docker,而是 containerd 默认路径。