如何安全地迁移Docker数据根目录到新磁盘?

来源:Java编程网作者:高永康头衔:资深程序员
导读:本期聚焦于高永康创作的《如何安全地迁移Docker数据根目录到新磁盘?》,敬请观看详情。Docker 默认把镜像、容器、卷等数据全部放在 /var/lib/docker,一旦系统盘空间告警,把这个目录整体迁走是最直接的办法。迁移并不是简单复制一下,还要处理 overlay2 文件系统、正在运行的容器状态和后续存储驱动加载。本文围绕停止服务、同步文件、修改 data-root 配置、重启验证这条主线,说明如何将 Docker 数据根目录迁移到新磁盘或新分区,同时给出软链接方案作为备选。整个过程会涉及权限、文件属主、SELinux 和磁盘挂载选项,读者可以先备份重要数据,再按步骤操作,避免因路径配置错误导致容器无法启动或镜像丢失。

Docker 的镜像、容器层、卷、网络等状态默认都存储在 /var/lib/docker。很多服务器系统盘只划分几十 GB,当镜像和容器数量增加后,系统盘很容易被打满。删除不用的镜像只能暂时缓解,真正彻底的办法是把 Docker 数据根目录迁移到一块容量更大的数据盘。迁移的重点不是简单的文件复制,而是要保证 overlay2 存储驱动的目录结构、文件权限和时间戳不被破坏,同时让 Docker 服务在重启后能准确找到新位置。下面将按照停服、同步、改配置、重启验证的顺序详细说明。

如何安全地迁移Docker数据根目录到新磁盘?

一、迁移前先确认当前数据根目录和磁盘状态

执行任何迁移操作之前,第一步是确认当前 Docker 实际使用的数据根目录。Docker 不同版本、不同安装方式可能会把数据放在不同位置,不能只凭经验判断。使用 docker info 可以查看 Docker Root Dir,它会明确指出当前存储路径。

sudo docker info | grep "Docker Root Dir"
sudo du -sh /var/lib/docker
df -h /var/lib/docker
lsblk

上面几条命令分别用来确认数据根目录路径、估算目录总大小、查看当前所在分区的剩余空间,以及列出磁盘和分区。如果新磁盘还没有分区和格式化,需要先完成这些操作。以一块新盘 /dev/sdb1 为例,可以格式化为 ext4 或 xfs,然后挂载到 /mnt/docker-data。对于 overlay2 存储驱动来说,ext4 和 xfs 都是稳定的选择,其中 xfs 还需要确认 ftype=1,否则 Docker 会拒绝启动。

确认目标路径之后,要确保该目录的权限和属主符合 Docker 运行要求。Docker 服务通常以 root 身份运行,目标目录也需要 root 所有。如果使用了 SELinux,还要注意新目录的上下文是否允许容器访问。迁移前最好记录当前 /var/lib/docker 的属主和权限,便于后续对照。

二、通过 daemon.json 修改 data-root 完成迁移

这是最推荐也是长期维护成本最低的方式。核心思路是先把旧数据完整复制到新目录,再告诉 Docker 引擎新的数据根目录在哪里。Docker 的守护进程配置通常位于 /etc/docker/daemon.json,通过其中的 data-root 字段可以指定新的存储位置。

首先需要停止 Docker 服务以及 socket,避免复制过程中有新的写入。停止服务后,原来的容器也会停止运行,因此建议在业务低峰期操作。接着创建目标目录,使用 rsync 保留权限、属主和时间戳进行同步。

sudo systemctl stop docker docker.socket
sudo mkdir -p /mnt/docker-data
sudo rsync -aP /var/lib/docker/ /mnt/docker-data/

注意源路径 /var/lib/docker/ 结尾带有斜杠,表示复制目录下的内容,而不是把整个 docker 目录复制成 /mnt/docker-data/docker。复制完成后可以先对比一下新旧目录的大小和文件数量。如果数据量很大,第一次复制可以先用 rsync -aP 完成全量同步,正式切换前再停止服务执行一次增量同步,减少停机时间。

接下来编辑 /etc/docker/daemon.json,加入 data-root 字段。如果文件已经存在,要保留原有配置,只新增或修改这个字段。下面是一个最小配置示例。

{
  "data-root": "/mnt/docker-data",
  "storage-driver": "overlay2"
}

保存后启动 Docker,再用 docker info 检查路径是否已经改变。确认新路径生效后,可以运行一个测试容器验证镜像拉取、容器启动和删除流程是否正常。生产环境建议先在单台机器验证完整流程,再批量迁移其他节点。

sudo systemctl start docker
sudo docker info | grep "Docker Root Dir"
sudo docker run --rm hello-world

如果启动失败,先检查 daemon.json 是否是合法的 JSON 格式,再查看 journalctl -u docker.service 的日志。常见错误包括路径不存在、目标目录权限不足、SELinux 阻止访问等。对于 SELinux 环境,可以执行 sudo restorecon -Rv /mnt/docker-data 恢复上下文,或者使用 semanage 为新路径添加规则。

三、软链接方案:不修改配置的快速迁移

某些场景下不方便修改 daemon.json,例如使用了外部编排平台、监控脚本固定读取 /var/lib/docker,或者希望迁移过程对 Docker 配置保持透明。此时可以使用符号链接方案,把原路径指向新磁盘上的真实目录。Docker 依然访问 /var/lib/docker,但实际读写发生在新的存储位置。

软链接迁移也需要先停止 Docker 服务。先把旧的 /var/lib/docker 改名为备份目录,再把备份内容同步到新位置,最后创建符号链接。这样无论 Docker 还是其他工具,看到 /var/lib/docker 仍然存在。

sudo systemctl stop docker docker.socket
sudo mv /var/lib/docker /var/lib/docker.bak
sudo mkdir -p /mnt/docker-data
sudo rsync -aP /var/lib/docker.bak/ /mnt/docker-data/
sudo ln -s /mnt/docker-data /var/lib/docker
sudo systemctl start docker

这种方式实施速度快,路径变化对上层应用透明,但它依赖一个符号链接指向新目录。如果后续维护人员不熟悉,可能会误认为 /var/lib/docker 是真实目录,或者出现重复挂载、删除软链接等误操作。同时,个别监控或备份程序如果使用 find 默认不跟随符号链接,可能看不到真实数据。总体而言,软链接适合临时迁移或无法修改 Docker 配置的环境,长期维护还是建议采用 data-root 方案。

四、迁移后验证与常见问题处理

迁移完成后的验证不能只看 docker info。需要从镜像、容器、数据卷三个维度确认数据完整性。首先运行 docker images 和 docker ps -a,确认镜像列表和容器记录没有丢失。然后启动一个已有的容器,检查它的运行状态和网络配置是否正常。如果使用了命名卷,也要确保卷中的数据仍然可读。

sudo docker images
sudo docker ps -a
sudo docker volume ls
sudo ls -lah /mnt/docker-data

建议迁移后保留旧目录一段时间,不要立刻删除。可以把旧目录改名为 docker.bak,观察业务运行几天后再清理。这样可以提供回滚机会。如果使用的是 data-root 方案,回滚只需要把 daemon.json 中的路径改回原值并重启;如果使用的是软链接方案,则可以删除链接并移回旧目录。

常见问题之一是 daemon.json 格式错误,导致 Docker 无法启动。JSON 不允许尾随逗号,也不允许使用单引号。另一个问题是复制后文件属主发生变化,尤其是使用 cp 而不是 rsync -a 时,可能会出现 root 之外的属主,导致权限错误。还有一类问题与挂载有关:如果新目录只是临时挂载而没有写入 /etc/fstab,服务器重启后挂载消失,Docker 将无法找到数据。因此迁移后应确认新挂载点在重启后仍然存在。

如果迁移后容器可以启动但个别容器出现异常,可以查看容器日志,并检查是否有绝对路径依赖旧目录。Docker 本身对 data-root 的感知是全局的,只要路径设置正确,镜像和容器通常可以正常工作。迁移操作本身不会改变镜像 ID、容器 ID 或网络名称,因此对应用层基本透明。

Docker数据目录数据根目录迁移Docker存储修改时间:2026-10-05 10:49:44

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/1005/65963.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。