Docker 存储目录迁移:解决 No space left on device

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

六、注意事项

  1. 迁移前确保目标分区空间充足,至少预留 Docker 当前数据 1.2 倍的空间用于后续增长

  2. 迁移过程中必须停止 Docker 服务,否则可能导致数据不一致

  3. 软链接方式无需修改 Docker 配置,兼容性好,对 Docker 透明

  4. SELinux 环境 下如遇权限问题,可能需要执行:

    bash 复制代码
    chcon -Rt svirt_sandbox_file_t /home/docker
  5. 迁移完成后,建议在 /home/docker 所在分区设置磁盘使用告警,避免再次出现空间不足

七、回滚方案

如果迁移后出现问题,可以快速回滚:

bash 复制代码
# 停止 Docker
systemctl stop docker

# 删除软链接
rm /var/lib/docker

# 将数据移回原位置
mv /home/docker /var/lib/docker

# 重启 Docker
systemctl start docker
相关推荐
张忠琳9 小时前
【NVIDIA】 NVIDIA Container Toolkit v1.19.1 — OCI 模块超深度分析之三
云原生·容器·架构·kubernetes·nvidia
Elastic 中国社区官方博客11 小时前
将你的 Grafana Kubernetes 仪表板迁移到 Elastic Observability:相同的 PromQL,30 倍更快的查询
大数据·人工智能·elasticsearch·搜索引擎·容器·kubernetes·grafana
风曦Kisaki13 小时前
#企业级docker私有仓库构建:harbor仓库与阿里云镜像仓库
阿里云·docker·容器
期待着201313 小时前
docker 安装 ,在centos7.9
运维·docker·容器
骑上单车去旅行16 小时前
Docker Compose 命令完全指南:从构建到运维
docker·容器·eureka
前端Baymax17 小时前
K8s PodCrashLoopBackOff假阳性排查
云原生·容器·kubernetes
spider_xcxc17 小时前
K8s 部署学习笔记
docker·容器·kubernetes·云计算·k8s
java_logo17 小时前
Docker Compose 部署 Apache Superset:轻松搭建开源 BI 平台
docker·开源·apache·superset·轩辕镜像·superset部署方案·docker superset
zy happy17 小时前
VMware虚拟机添加新的硬盘
java·linux·jvm·docker
阿标在干嘛1 天前
从物理机到K8s:政策快报平台的容器化部署实践
云原生·容器·kubernetes