文章适配:Ubuntu22.04 / Ubuntu24.04,Docker‑CE 新版本;目标路径:/data/opt/docker‑var,数据盘已完成挂载。 场景说明:apt 默认安装 Docker 所有镜像、容器、卷、网络数据全部存放在/var/lib/docker系统盘目录,系统盘磁盘打满,需要整体迁移到已经挂载好的数据盘目录/data/opt/docker‑var,保留原有镜像、容器、数据卷,业务不丢失。
前言
通过 apt 安装 Docker 后,Docker 所有运行数据(镜像 overlay2 层、容器文件、volumes 数据卷、网络、构建缓存)全部默认存储在/var/lib/docker目录下,该目录位于系统盘。 当镜像和容器越来越多,很容易把系统根分区占满,导致服务器报错、无法写入、容器异常。 本文完整实操,把 Docker 全部存储迁移至已挂载的数据盘路径 /data/opt/docker‑var,迁移后所有新拉取镜像、容器、卷全部写入数据盘,原有数据完整保留,不需要重新 pull 镜像重建容器。
重要提醒:迁移过程 Docker 服务会停止,业务会短暂中断,请选择业务低峰期操作。操作前建议做好重要业务数据备份。
前置检查
1、确认数据盘挂载正常
目标目录/data/opt/docker‑var所在磁盘已经挂载成功,确认磁盘空间充足:
df -h
看/data对应分区容量,确认不是系统盘。
2、查看 Docker 当前存储位置
docker info | grep "Docker Root Dir"
输出:Docker Root Dir: /var/lib/docker,这是 Docker 默认根目录。
3、查看原有数据占用大小
sudo du -sh /var/lib/docker
步骤 1:停止 Docker 全部相关服务
必须完全停止 docker、docker.socket、containerd,禁止在运行状态复制数据,会造成镜像 / 容器文件损坏。
# 先停止正在运行的所有容器(可选,更稳妥)
sudo docker stop $(sudo docker ps -q) 2>/dev/null
# 停止docker全套服务
sudo systemctl stop docker
sudo systemctl stop docker.socket
sudo systemctl stop containerd
确认状态全部为 inactive:
sudo systemctl status docker docker.socket containerd
步骤 2:创建目标存储目录
sudo mkdir -p /data/opt/docker-var
步骤 3:rsync 同步原有全部 Docker 数据(保留权限、属主、软链接)
不要用 cp 命令,大目录容易丢失文件权限属性,迁移后会出现镜像看不到、容器启动失败。优先 rsync。 注意源路径末尾
/不能漏掉,代表复制目录内部全部内容,而不是把 docker 文件夹嵌套进去。
sudo rsync -aHAX --numeric-ids --info=progress2 /var/lib/docker/ /data/opt/docker-var/
参数说明:
-a:归档模式,权限、时间、属主全部保留-HAX:保留硬链接、ACL 访问控制、扩展属性(Docker overlay2 存储依赖)--numeric-ids:原样复制 uid/gid 数字 ID,不解析用户名,避免权限错乱--info=progress2:显示整体复制进度,大目录方便观察复制状态
等待复制完成,数据越大耗时越久。复制完成可以简单对比两边目录大小:
sudo du -sh /var/lib/docker
sudo du -sh /data/opt/docker-var
两边总大小应该基本一致。
步骤 4:修改 docker 配置 daemon.json,指定 data-root
编辑 docker 守护进程配置/etc/docker/daemon.json,设置data-root指向新路径/data/opt/docker‑var。
如果你之前配置过国内镜像加速器,daemon.json 已经存在,不要直接覆盖文件,只添加
"data-root"字段到 json 对象中。json 语法严格,不能写注释,逗号不能多不能少。
场景 A:原来 daemon.json 已经配置国内镜像源(沿用之前博客配置)
sudo vim /etc/docker/daemon.json
完整内容示例(融合镜像加速器 + 迁移路径):
{
"data-root": "/data/opt/docker-var",
"registry-mirrors": [
"https://docker.1panel.live",
"https://docker.m.daocloud.io",
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.aliyuncs.com"
],
"dns": ["223.5.5.5", "223.6.6.6"],
"iptables": true
}
场景 B:daemon.json 文件不存在(全新)
直接执行命令生成配置文件:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
{
"data-root": "/data/opt/docker-var"
}
EOF
注意:旧版本 docker 使用
graph参数,新版 docker‑ce(20.10 以后)废弃 graph,统一使用data‑root,不要混用。
步骤 5:重载 systemd 配置,启动 docker 服务
sudo systemctl daemon-reload
sudo systemctl start docker
# 设置开机自启(默认一般已开启,确认一次)
sudo systemctl enable docker
检查 docker 状态,必须是active(running)
sudo systemctl status docker
步骤 6:验证迁移是否真正生效
①确认 Docker 根目录已经变更
docker info | grep "Docker Root Dir"
成功输出:Docker Root Dir: /data/opt/docker-var
②校验原有镜像、容器、数据卷全部存在
# 查看镜像列表,应该显示迁移前所有镜像
sudo docker images
# 查看全部容器(包含停止的),原有容器全部存在
sudo docker ps -a
# 查看数据卷
sudo docker volume ls
③运行 hello‑world 测试新建容器正常写入新盘
sudo docker run --rm hello-world
能正常输出 hello from docker 代表 docker 读写完全正常。 此时去看目录/data/opt/docker‑var下面已经生成 overlay2、containers、volumes 子目录。
步骤 7:确认一切正常后,处理旧目录(谨慎!)
不要立刻删除 /var/lib/docker!建议保留 2‑3 天确认业务全部稳定运行后清理,作为回滚备份。
方案 1:重命名备份(推荐)
sudo mv /var/lib/docker /var/lib/docker.old.bak
后续确认完全没问题,再执行删除释放系统盘空间:
# 确认业务无异常再执行
sudo rm -rf /var/lib/docker.old.bak
如果迁移后出问题回滚方法:停止 docker,删除 daemon.json 里面的 data‑root 配置,再把
docker.old.bak改回/var/lib/docker,重启 docker 即可回退。
常见踩坑问题汇总
问题 1:docker 启动失败,status 看到报错
排查日志:
sudo journalctl -u docker -f
高频原因:
- daemon.json JSON 语法错误,多逗号、有注释(docker 不支持 json 注释);
- rsync 复制时没有带
‑a参数,文件权限丢失; - 目标目录所在磁盘没有挂载,重启服务器目录消失。
问题 2:docker info 显示 Docker Root Dir 依旧是 /var/lib/docker
- daemon.json 写错参数名,旧参数
graph;新版本必须用data‑root; - 修改配置后忘记执行
systemctl daemon‑reload; - 存在 systemd override 配置覆盖 data‑root 参数,检查目录
/etc/systemd/system/docker.service.d/下是否有配置文件强制指定路径。
问题 3:重启服务器之后 docker 又切回旧路径
确认两件事:
/data对应磁盘分区已经写入/etc/fstab实现开机自动挂载;- fstab 配置无语法错误,校验:
sudo mount -a,无报错才算 fstab 正确。
如果数据盘没有写 fstab,重启后
/data/opt/docker‑var是空目录,docker 会自动新建/var/lib/docker回退到系统盘。
问题 4:迁移完容器启动报错
大概率 rsync 复制的时候 docker 服务没完全停止,复制过程文件损坏,需要回滚备份重新完整 rsync 同步。
补充:containerd 存储说明(新版本注意)
新版本 docker 使用 containerd 镜像存储模式时,除了 docker 的data‑root,containerd 自己数据目录默认/var/lib/containerd,如果 containerd 数据也很大,想要一并迁移,需要修改/etc/containerd/config.toml的root =配置项,再迁移/var/lib/containerd目录。普通场景只迁移 docker 的 data‑root 即可满足绝大多数需求。
快速命令速查表(复制即用)
# 停止服务
sudo docker stop $(sudo docker ps -q) 2>/dev/null
sudo systemctl stop docker docker.socket containerd
# 创建目录同步数据
sudo mkdir -p /data/opt/docker-var
sudo rsync -aHAX --numeric-ids --info=progress2 /var/lib/docker/ /data/opt/docker-var/
# 修改daemon.json添加data-root,重启
sudo systemctl daemon-reload
sudo systemctl start docker
# 验证
docker info | grep "Docker Root Dir"
sudo docker images
sudo docker ps -a
总结
- Docker 新版本使用
data‑root参数指定存储根目录,不要使用废弃graph参数; - 迁移前必须停止全套 docker 服务,rsync 是迁移首选,保证文件权限完整;
- 修改
daemon.json注意 JSON 语法,不允许注释;如果已有镜像加速器配置,只追加字段; - 迁移完成先完整验证镜像容器业务,再删除原系统盘目录,保留备份方便回滚;
- 务必确认数据盘已经写入
/etc/fstab开机自动挂载,防止重启失效。