Ubuntu24.04 将 Docker 完整迁移到数据盘

我爱海鲸 2026-09-20 14:43:42 暂无标签

简介docker、迁移

文章适配: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

高频原因:

  1. daemon.json JSON 语法错误,多逗号、有注释(docker 不支持 json 注释);
  2. rsync 复制时没有带‑a参数,文件权限丢失;
  3. 目标目录所在磁盘没有挂载,重启服务器目录消失。

问题 2:docker info 显示 Docker Root Dir 依旧是 /var/lib/docker

  1. daemon.json 写错参数名,旧参数graph;新版本必须用data‑root
  2. 修改配置后忘记执行systemctl daemon‑reload
  3. 存在 systemd override 配置覆盖 data‑root 参数,检查目录/etc/systemd/system/docker.service.d/下是否有配置文件强制指定路径。

问题 3:重启服务器之后 docker 又切回旧路径

确认两件事:

  1. /data对应磁盘分区已经写入/etc/fstab实现开机自动挂载;
  2. 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.tomlroot =配置项,再迁移/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

总结

  1. Docker 新版本使用data‑root参数指定存储根目录,不要使用废弃graph参数;
  2. 迁移前必须停止全套 docker 服务,rsync 是迁移首选,保证文件权限完整
  3. 修改daemon.json注意 JSON 语法,不允许注释;如果已有镜像加速器配置,只追加字段;
  4. 迁移完成先完整验证镜像容器业务,再删除原系统盘目录,保留备份方便回滚;
  5. 务必确认数据盘已经写入/etc/fstab开机自动挂载,防止重启失效。

你好:我的2025

上一篇:待看的书