# Linux 系统盘空间不足将 Docker 镜像和容器数据迁移到数据盘 > 将 Docker 的数据(镜像、容器、卷、网络配置等)从系统盘迁移到数据盘是解决空间不足的常用方法。以下是详细步骤: ## 核心思路: 1. **停止 Docker 服务:** 确保没有容器在运行,数据处于静止状态。 2. **备份现有数据 (可选但强烈推荐):** 防止迁移过程中出现意外。 3. **复制数据:** 将 `/var/lib/docker`目录完整地复制到数据盘的目标位置。 4. **修改 Docker 配置:** 告诉 Docker 以后使用新的数据存储路径。 5. **重启 Docker 服务:** 应用新配置并验证。 6. **清理旧数据 (可选):** 确认新位置工作正常后,删除旧数据释放空间。 **详细步骤:** ## 1. 准备工作 - **确定数据盘挂载点:** 假设你的数据盘已经挂载到了 `/mnt/data`(请根据实际情况替换为你自己的挂载点,如 `/data`, `/home/data`等)。 - **创建目标目录:** 在数据盘上创建一个目录来存放 Docker 数据。 ```bash sudo mkdir -p /mnt/data/docker ``` *(将 `/mnt/data`替换为你的实际挂载点)* ## 2. 停止 Docker 服务 ```bash sudo systemctl stop docker sudo systemctl stop docker.socket # 如果存在且需要停止 # 或者使用 service 命令 (适用于较旧系统) # sudo service docker stop ``` **重要:** 确保所有容器都已停止。可以使用 `docker ps -a`查看,如果有容器在运行,先 `docker stop
`停止它们。 ## 3. 备份现有数据 (强烈推荐) ```bash sudo tar -czvf /tmp/docker-backup-$(date +%Y%m%d).tar.gz -C /var/lib docker ``` - 这会在 `/tmp`目录下创建一个压缩备份文件,文件名包含日期。请妥善保管此备份或将其移动到其他安全位置。 ## 4. 复制数据到新位置 使用 `rsync`或 `cp`命令复制数据。**推荐使用 `rsync`,因为它能更好地保留权限、所有权和时间戳,并且在中断后可以恢复。** ```bash # 使用 rsync (推荐) sudo rsync -avxP /var/lib/docker/ /mnt/data/docker/ # 或者使用 cp (确保保留属性) sudo cp -rp /var/lib/docker/* /mnt/data/docker/ ``` - `-a`: 归档模式 (递归、保留权限、时间戳、符号链接等) - `-v`: 详细输出 - `-x`: 保持在同一文件系统内 (避免复制挂载点) - `-P`: 显示进度和部分传输的文件 (等同于 `--partial --progress`) - `-r`: 递归复制 (`cp`时使用) **等待复制完成。** 这个过程可能需要一些时间,取决于 `/var/lib/docker`的大小。 ## 5. 备份并修改 Docker 配置文件 Docker 的主配置文件通常是 `/etc/docker/daemon.json`。如果该文件不存在,你需要创建它。 - **备份原配置 (如果存在):** ```bash sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak # 如果存在 ``` - **编辑或创建 daemon.json:** ```bash sudo nano /etc/docker/daemon.json ``` 添加或修改 `data-root`选项,指向新的 Docker 数据目录: ```bash { "data-root": "/mnt/data/docker" } ``` - **注意:** - 如果文件已存在且包含其他配置 (如镜像加速器 `registry-mirrors`),**务必保留原有配置**,只添加 `"data-root"`这一行。例如: ```bash { "registry-mirrors": ["https://your.mirror.url"], "data-root": "/mnt/data/docker" } ``` - 确保 JSON 格式正确,**最后一个键值对后面不能有逗号**。 - 旧版本的 Docker (大约 < 17.06) 可能使用 `"graph"`而不是 `"data-root"`。如果你的 Docker 版本较旧,请查阅对应文档或使用 `"graph"`。建议使用较新的 Docker 版本并优先使用 `"data-root"`。可以通过 `docker --version`查看版本。 ## 6. 重新加载 systemd 配置并启动 Docker (如果使用 systemd) ```bash sudo systemctl daemon-reload sudo systemctl start docker ``` ## 7. 验证迁移是否成功 - **检查 Docker 信息:** ```bash docker info | grep "Docker Root Dir" ``` 输出应该显示新的路径:`Docker Root Dir: /mnt/data/docker` - **运行测试容器:** ```bash docker run --rm hello-world ``` 如果能成功下载并运行 hello-world 容器,说明基本功能正常。 - **检查现有容器和镜像 (如果迁移前有):** ```bash docker images docker ps -a ``` 你应该能看到之前存在的镜像和容器列表(状态可能是 Exited)。尝试启动一个原有的容器,看是否能正常运行。 ## 8. 清理旧数据 (确认无误后) **只有在确认 Docker 在新位置完全正常工作后,才执行此步骤!** ```bash sudo rm -rf /var/lib/docker ``` 这会删除系统盘上的旧 Docker 数据,释放宝贵的空间。 ## 9. (可选) 设置开机自动挂载数据盘 确保你的数据盘在 `/etc/fstab`中有正确的条目,以便在系统启动时自动挂载到 `/mnt/data`(或你使用的挂载点)。这是保证 Docker 服务能正常启动的关键。检查 `/etc/fstab`文件或使用 `mount`命令查看当前挂载情况。 **注意事项:** 1. **权限:** 确保新目录 `/mnt/data/docker`的所有者和组是 `root:root`(或 Docker 守护进程运行的用户/组,通常是 `root`),并且权限设置正确 (通常是 `711`或 `700`)。`rsync -a`或 `cp -p`通常会保留原始权限。 2. **SELinux/AppArmor:** 如果你的系统启用了 SELinux 或 AppArmor,直接复制数据可能导致权限问题。你可能需要: - 在复制后使用 `chcon`命令调整新目录的安全上下文 (SELinux)。 - 或者,在复制前临时禁用 SELinux (`setenforce 0`),复制后再启用 (`setenforce 1`) 并修复上下文。更简单的方法是使用 `rsync`的 `-X`选项 (如果支持) 或明确设置上下文。对于 AppArmor,可能需要调整策略。如果遇到权限拒绝错误,这是首要怀疑对象。 3. **磁盘空间:** 确保数据盘有足够的空间容纳所有 Docker 数据。 4. **符号链接 (替代方案):** 另一种方法是删除 `/var/lib/docker`目录,然后创建一个指向新位置的**符号链接**: ```bash sudo systemctl stop docker sudo mv /var/lib/docker /var/lib/docker.bak # 备份或重命名 sudo ln -s /mnt/data/docker /var/lib/docker sudo systemctl start docker ``` **注意:** 这种方法在某些系统或特定配置下可能不如修改 `daemon.json`可靠,特别是当 Docker 服务启动脚本有特殊处理时。修改 `daemon.json`是官方推荐的方式。 5. **绑定挂载 (Bind Mount):** 也可以考虑将 `/var/lib/docker`本身作为一个绑定挂载点挂载到数据盘的一个目录上。但这通常需要更复杂的配置,不如直接修改 `data-root`清晰。 按照这些步骤操作,你应该能够安全地将 Docker 的数据存储迁移到数据盘,解决系统盘空间不足的问题。记得在操作前备份重要数据! ## 快照 - https://i.788910.xyz/t/26/03/mdGIe8mQsO.jpg - https://i3.wp.com/i.788910.xyz/t/26/03/mdGIe8mQsO.jpg - https://788910.xyz/api/snapshot?p=f8a4d6f03e193a04887698c7e31e5e94&u=https://i.788910.xyz/t/26/03/mdGIe8mQsO.jpg