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