Docker 存储目录迁移:解决 No space left on device
一、问题背景
在使用 Docker 构建镜像时,出现以下错误:
chmod: changing permissions of './shooting': No space left on device
查看磁盘使用情况:
bash
$ df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 50G 50G 59M 100% /
/dev/mapper/centos-home 418G 652M 418G 1% /home
根因分析 :Docker 默认数据目录 /var/lib/docker/ 位于根分区(centos-root),该分区已 100% 占满;而 /home 分区(centos-home)有 418G 空闲空间几乎未使用。
解决方案 :将 Docker 数据目录从 /var/lib/docker/ 迁移到 /home/docker/,利用 home 分区的大容量空间。
二、迁移前准备
1. 确认当前 Docker 数据目录
bash
docker info | grep "Docker Root Dir"
# 输出:Docker Root Dir: /var/lib/docker
2. 查看当前 Docker 占用空间
bash
du -sh /var/lib/docker/
# 输出:64G
3. 确认目标分区空间充足
bash
df -h /home
# 确保 /home 分区可用空间 > Docker 数据目录大小
三、迁移步骤
第一步:停止所有容器和 Docker 服务
bash
# 停止所有运行中的容器
docker stop $(docker ps -q)
# 停止 Docker socket(防止自动激活)
systemctl stop docker.socket
# 停止 Docker 服务
systemctl stop docker
# 停止 containerd
systemctl stop containerd
# 确认都已停止
systemctl status docker
systemctl status docker.socket
# 验证没有 Docker 进程残留
ps aux | grep docker | grep -v grep
注意 :必须先停止
docker.socket再停止docker,否则 socket 可能会自动重新激活 Docker 服务。如果ps aux仍有 Docker 进程残留,使用kill手动终止。
第二步:迁移数据并创建软链接(可选)
bash
# 移动现有的 Docker 数据到新位置
mv /var/lib/docker /home/docker
# 创建软链接,确保兼容性(可选)
# 软链接方案:Docker 仍通过原路径访问,实际数据存储在 /home 分区,无需修改 daemon.json
ln -s /home/docker /var/lib/docker
# 验证软链接创建成功
ls -la /var/lib/docker
# 期望输出:/var/lib/docker -> /home/docker
说明:
- 使用
mv直接移动目录,相比rsync/cp更简洁,移动完成后原目录自动消失,无需额外清理- 由于
/var/lib/docker和/home位于不同分区,mv会自动执行跨分区复制+删除操作- 软链接方案(推荐) :创建软链接后,Docker 仍通过
/var/lib/docker路径访问数据,无需修改daemon.json配置,兼容性更好,对 Docker 完全透明- 不创建软链接方案 :需在下一步修改
daemon.json配置data-root: "/home/docker",Docker 直接从新路径读取数据- 迁移时间取决于数据量,64G 数据可能需要几分钟到十几分钟,请耐心等待
第三步:验证数据迁移完整性
bash
# 验证软链接指向正确
ls -la /var/lib/docker
# 期望输出:/var/lib/docker -> /home/docker
# 确认新目录数据完整
du -sh /home/docker/
确认软链接正确且数据目录大小正常后,继续下一步。
第四步:重启 Docker 服务
bash
systemctl start docker
第五步:验证迁移结果
bash
# 确认 Docker 数据目录(软链接方式下仍显示原路径,实际已存储在 /home 分区)
docker info | grep "Docker Root Dir"
# 期望输出:Docker Root Dir: /var/lib/docker
# 确认实际数据已存储在 /home 分区
df -h /home/docker/
# 确认镜像和容器是否正常
docker images
docker ps -a
四、迁移后验证
重新执行之前失败的 Docker 构建命令:
bash
cd /home/shooting/ && docker build -t shooting .
查看磁盘空间变化:
bash
df -h
# 根分区使用率应明显下降
# /home 分区使用率相应上升
五、补充优化:清理 Docker 无用资源
如果迁移后根分区空间仍不够,可以清理 Docker 的无用资源:
bash
# 清理所有未使用的镜像、容器、网络和构建缓存
docker system prune -a
# 查看各部分占用空间
docker system df
六、注意事项
-
迁移前确保目标分区空间充足,至少预留 Docker 当前数据 1.2 倍的空间用于后续增长
-
迁移过程中必须停止 Docker 服务,否则可能导致数据不一致
-
软链接方式无需修改 Docker 配置,兼容性好,对 Docker 透明
-
SELinux 环境 下如遇权限问题,可能需要执行:
bashchcon -Rt svirt_sandbox_file_t /home/docker -
迁移完成后,建议在
/home/docker所在分区设置磁盘使用告警,避免再次出现空间不足
七、回滚方案
如果迁移后出现问题,可以快速回滚:
bash
# 停止 Docker
systemctl stop docker
# 删除软链接
rm /var/lib/docker
# 将数据移回原位置
mv /home/docker /var/lib/docker
# 重启 Docker
systemctl start docker