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
相关推荐
张忠琳2 小时前
【k3s】AutoK3s v0.9.3 Part 1 入口与 CLI 命令模块 — 超深度逐行分析之三
云原生·容器·kubernetes·k3s·autok3s
apgk17 小时前
基于Canal实现mysql数据同步到消息队列(RabbitMQ/Kafka)详细操作教程
docker·kafka·rabbitmq
fatcoder8 小时前
玩转Docker 06 — 容器网络
前端·后端·docker
xiaoxiangsiyan9 小时前
企业日常运维高频应用服务全解
运维·网络·云原生·容器·dns
AR_xsy9 小时前
docker--资源配额 配置
运维·docker·容器
国际云,接待9 小时前
Docker 容器突然退出、服务莫名重启:从 OOMKilled 到内存泄漏的生产排查手册
运维·docker·容器
橙-极纪元10 小时前
把docker的镜像文件从一台服务器中,迁移至另一台服务器
服务器·docker·容器
RobinDevNotes12 小时前
K8s+Ray+vLLM打穿大模型全生命周期(有实践步骤)
人工智能·云原生·容器·kubernetes·生活·vllm
雨声不在12 小时前
docker-android 重启后镜像起不来
android·docker·容器
AR_xsy13 小时前
k8s随笔-cordon排水
云原生·容器·kubernetes