场景说明
我的服务器环境说明:Debian11,Docker 数据目录 /var/lib/docker,磁盘已满;目标分区 /tzdata(已提前挂载,空间充足)。
⚠️重要前提:Docker 不能不停机直接迁移。运行状态拷贝文件一定会造成容器文件损坏、数据库数据丢失。只能:在线先预同步 → 短时停机增量同步 → 切换目录,最大限度缩短业务中断窗口。
纠正:不要直接软链接(线上长期运行容易出现 overlay2 文件锁、网络 / 卷异常),优先使用标准
daemon.json修改data-root方案。
0、前置检查(必须先做)
# 确认挂载
df -h
# 确认docker根目录
docker info | grep "Docker Root Dir"
# 预估docker占用大小
du -sh /var/lib/docker
# 确认剩余空间 > /var/lib/docker大小
在 /tzdata 创建 docker 目录:
mkdir -p /tzdata/docker
方案完整步骤(低中断窗口,生产推荐)
阶段 1:容器正常运行,第一次全量 rsync 预同步(业务不中断)
磁盘已满,拷贝会比较吃 IO,避开业务高峰;rsync 参数必须带 HAX,保留 docker 镜像硬链接,否则拷贝后镜像膨胀几倍!
# root执行
rsync -aHAXvP --numeric-ids /var/lib/docker/ /tzdata/docker/
参数解释:
-a:归档,权限、属主、时间、软链接-H:关键!保留硬链接(overlay2 镜像层依赖)-A:ACL 权限-X:扩展属性-P:进度 + 断点续传--numeric-ids:不解析用户名,直接 UID/GID,避免权限错乱
路径末尾
/不要漏!代表复制目录内部所有文件,不是把 docker 目录嵌套进去。
阶段 2:停机窗口期(正式切换,业务短暂中断)
停止 docker 全套服务
systemctl stop docker.socket
systemctl stop docker
# 确认无残留容器进程
ps aux | grep -E "docker|containerd-shim"
增量同步(只同步第一次同步后新变更的数据,大幅缩短停机时间)
rsync -aHAXvP --numeric-ids --delete /var/lib/docker/ /tzdata/docker/
--delete:保证两边文件完全一致(源删除的文件目标也删除)
备份原目录(不要立刻删除!验证成功再删)
mv /var/lib/docker /var/lib/docker.bak
修改 docker 配置,指定新数据根目录
# 创建/编辑daemon.json
vim /etc/docker/daemon.json
写入配置:
{
"data-root": "/tzdata/docker"
}
如果文件已有镜像加速、log 配置,逗号追加,示例:
{
"data-root": "/tzdata/docker",
"registry-mirrors": ["https://xxx.mirror.aliyuncs.com"]
}
重载 systemd、启动 docker
systemctl daemon-reload
systemctl start docker.socket
systemctl start docker
阶段 3:全面验证(重中之重)
# 校验docker根目录是否切换成功
docker info | grep "Docker Root Dir"
# 查看所有容器,状态是否和迁移前一致
docker ps -a
# 查看镜像完整存在
docker images
# 进入业务容器测试读写、数据库连通性
docker exec -it 容器名 bash
重点测试:
数据库容器能否正常读写(mysql/postgres/redis)
持久化卷数据完整
容器网络互通、端口访问正常
✅ 全部业务运行稳定 持续观察 1~3 天,确认无异常后,再清理旧目录释放空间:
# 确认无误再执行!
rm -rf /var/lib/docker.bak
备选方案:软链接方案(应急临时方案,不建议长期使用)
如果你暂时不想修改 daemon.json,仅应急切换:
风险提示:部分版本 docker overlay2、网络驱动对软链接兼容性差,后期可能出现各种诡异问题,只适合临时过渡。
# 停机同步同上
mv /var/lib/docker /var/lib/docker.bak
ln -s /tzdata/docker /var/lib/docker
systemctl start docker
⚠️ 针对【挂载 磁盘已满】的额外坑点
磁盘满的时候第一次 rsync 容易失败
如果执行 rsync 直接报错磁盘空间不足:
优先临时清理 docker 垃圾释放少量空间(不要删业务数据卷)
# 清理停止的容器、悬空镜像(谨慎执行)
docker container prune
docker image prune
腾出几个 GB 空间让 rsync 能够正常启动。
绝对禁止:docker 运行中直接 mv/cp 目录
容器持续写入文件,拷贝出来的数据必然损坏,数据库大概率崩溃。
文件系统注意
/tzdata 文件系统推荐 ext4/xfs;不要使用 NTFS,权限会完全错乱导致 docker 无法启动。
回滚方案(迁移失败一键恢复)
一旦启动异常,立刻回滚:
systemctl stop docker
# 删除软链接/新目录配置
rm -f /etc/docker/daemon.json
# 恢复旧目录
rm -rf /tzdata/docker
mv /var/lib/docker.bak /var/lib/docker
systemctl daemon-reload
systemctl start docker