Docker 数据目录迁移完整指南:从 /var/lib/docker 迁移到自定义路径
前言
在 Docker 的使用过程中,默认的数据目录 /var/lib/docker 会存储所有核心数据,包括镜像、容器、卷等。随着业务的增长,默认路径所在的 /var 分区可能会因空间不足而面临扩容压力。此时,迁移 Docker 数据目录到更大容量的分区(如本文中的 /data2/docker/data)是一种有效的解决方案。本文将详细介绍从准备工作到数据复制、配置修改、问题排查的完整迁移过程,包含实操命令和避坑指南,适用于 Ubuntu 及其他 Linux 发行版。
一、迁移前准备
1. 环境确认
- 操作系统:Ubuntu 22.04.1 LTS
- Docker 版本:28.2.2(客户端与服务端版本一致)
- 源数据目录:/var/lib/docker(通过
docker info | grep "Docker Root Dir"确认) - 目标数据目录:/data/docker(确保目标分区有足够空间,本文迁移数据量约 260GB)
2. 核心工具与命令
systemctl:管理 Docker 服务启动与停止cp -a:完整复制目录(保留权限、隐藏文件、元数据)nano:编辑 Docker 配置文件journalctl:查看 Docker 启动日志(排查错误)
3. 关键前提
- 迁移前必须停止 Docker 服务及相关进程,避免数据写入导致复制不完整。
- 目标目录需提前创建并配置正确权限,确保 Docker 可读写。
二、详细迁移步骤
步骤 1:停止 Docker 服务(关键!)
Docker 会持续读写数据目录,因此在迁移前需要完全停止服务,并停止 docker.socket 防止其自动激活。
# 停止 Docker 服务
sudo systemctl stop docker
# 停止 docker.socket(避免服务被自动激活)
sudo systemctl stop docker.socket
# 验证状态(均显示 inactive (dead) 即为成功)
sudo systemctl status docker
sudo systemctl status docker.socket
步骤 2:创建目标目录并配置权限
目标目录应归属 root 用户(Docker 运行用户),并且权限设置为 701,与默认目录的权限一致。
# 创建目标目录(-p 确保父目录递归创建)
sudo mkdir -p /data/docker
# 配置所有者为 root:root
sudo chown -R root:root /data/docker
# 配置权限(保证 root 读写权限,其他用户可执行)
sudo chmod -R 701 /data/docker
步骤 3:完整复制数据到目标目录
使用 cp -a 命令复制数据,确保保留所有文件属性和隐藏内容(Docker 依赖大量隐藏元数据文件)。
# 关键命令:复制源目录下所有内容(包括隐藏文件和子目录)
sudo cp -a /var/lib/docker/. /data/docker/
命令说明:
- 源路径使用
/var/lib/docker/.而非/*:*会忽略隐藏文件(如overlay2存储驱动的.lower元文件),导致数据不完整;/.会复制目录下所有内容,包括隐藏文件和嵌套子目录。 -a选项等价于-dR --preserve=all,递归复制,保留符号链接、权限、所有者、时间戳,确保数据完整性。
步骤 4:修改 Docker 配置文件(指定新数据目录)
Docker 通过 /etc/docker/daemon.json 配置数据目录,需要添加 data-root 字段指定新路径。
# 编辑配置文件(不存在则自动创建)
sudo nano /etc/docker/daemon.json
正确配置内容(JSON 格式严格!):
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.ccs.tencentyun.com",
"https://dockerproxy.com"
],
"ipv6": false,
"dns": ["x.x.x.x", "xxx.xxx.xxx.xxx"],
"data-root": "/data/docker" // 核心:指定新数据目录
}
配置注意事项:
- JSON 格式必须严格:键值对用逗号分隔,最后一个键值对后无多余逗号。
- 字符串不能包含换行符或多余的引号,否则会导致 Docker 解析失败。
- 若原有配置包含镜像源、DNS 等,可直接新增
data-root字段,无需修改其他配置。
步骤 5:启动 Docker 服务并验证
启动 Docker 服务并验证新数据目录是否生效。
# 启动 Docker 服务(自动拉起 docker.socket)
sudo systemctl start docker
# 验证服务状态(显示 active (running) 即为成功)
sudo systemctl status docker
# 验证新数据目录是否生效
docker info | grep "Docker Root Dir"
预期输出:
Docker Root Dir: /data2/docker/data
三、迁移过程中遇到的问题与解决方案
问题 1:误触回车键是否影响复制?
现象:执行 sudo cp -a /var/lib/docker/. /data2/docker/data/ 后,误触回车键。
结论:完全不影响!
cp复制进程已启动,不受后续空输入干扰。- 后续回车仅向终端输入空行,终端会忽略无意义输入。
验证方法:
# 查看 cp 进程是否正在运行
ps aux | grep cp
# 查看 IO 负载,确认数据传输中
sudo apt install -y iotop
sudo iotop -o # 显示正在进行 IO 操作的进程
问题 2:Docker 启动失败,日志提示 invalid character '\n' in string literal
现象:执行 sudo systemctl start docker 失败,日志显示配置文件解析错误。
原因:/etc/docker/daemon.json 存在 JSON 语法错误,可能是多余的逗号或非法换行符。
解决方案:修正配置文件语法,删除多余字符,确保 JSON 格式规范。
问题 3:启动提示 "Start request repeated too quickly"
现象:Docker 启动后立即失败,系统反复重试后放弃,日志显示该提示。
原因:Docker 守护进程启动时解析配置文件失败或权限不足,导致启动流程中断。
排查步骤:
# 查看详细日志定位错误
sudo journalctl -u docker.service --since "10 minutes ago"
解决方案:优先检查 daemon.json 格式,确保没有错误;其次检查目标目录权限。
问题 4:复制数据时提示“没有那个文件或目录”
现象:执行 sudo cp -a /var/lib/docker/* /data2/docker/data/ 时提示文件不存在。
原因:* 仅匹配非隐藏的顶层文件/目录,Docker 核心数据存储在子目录中,且可能包含隐藏元文件。
解决方案:改用 sudo cp -a /var/lib/docker/. /data2/docker/data/,确保复制所有内容。
四、迁移后验证与收尾
1. 数据完整性验证
迁移成功后,需确认镜像、容器、卷等数据完整。
# 查看镜像(应与迁移前一致)
docker images
# 查看所有容器(运行中/停止状态均需正常显示)
docker ps -a
# 启动任意旧容器,验证运行状态
docker start <容器ID/名称>
# 查看容器日志,确认无异常
docker logs <容器ID/名称>
# 对比源目录与目标目录大小(应基本一致)
sudo du -sh /var/lib/docker
sudo du -sh /data2/docker/data
2. 清理旧数据(可选)
确认迁移后 Docker 运行正常,且目标目录数据完整后,可删除旧目录释放空间。
# 谨慎操作!仅在验证无误后执行
sudo rm -rf /var/lib/docker
3. 长期维护建议
- 定期监控目标目录磁盘空间,避免再次出现空间不足问题。
- 备份
daemon.json配置文件:sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak - 若需再次迁移,可复用本文流程,
- 本文标签: docker
- 本文链接: https://code.itptg.com/article/139
- 版权声明: 本文由老魏原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权