Docker 和 Containerd 默认将核心数据存在系统盘,随容器/镜像积累易导致系统崩溃。本文讲解迁移方法,实操落地,避坑指南适用于主流 Linux 发行版。
一、迁移前必备准备(重中之重)
迁移前需逐一步骤确认,避免数据丢失或服务异常。
1. 确认目标存储目录
选择剩余空间≥当前容器数据1.5倍的磁盘,示例迁移路径 /data/docker(Docker)、/data/containerd(Containerd),可按需调整。
2. 备份核心数据
迁移前务必备份,命令如下:
tar -zcvf /tmp/docker-backup.tar.gz /var/lib/docker # Docker 备份
tar -zcvf /tmp/containerd-backup.tar.gz /var/lib/containerd # Containerd 备份
云主机建议同步创建系统快照。
3. 停止相关服务
停止服务避免数据读写冲突,命令:
sudo systemctl stop docker # 停止 Docker
sudo systemctl stop containerd # 停止 Containerd
注意:停止服务会终止所有运行容器,需提前规划迁移时间。
4. 检查权限
确保目标目录所有者为 root、权限700,避免服务启动失败。
二、Docker 存储目录迁移(推荐两种方法,优先方法1)
默认存储目录 /var/lib/docker,两种迁移方法如下,优先选择规范稳定的配置文件修改法。
方法1:修改 daemon.json 配置(推荐,适用于 systemd 系统)
官方推荐,永久生效,兼容性好,升级 Docker 不失效。
步骤1:创建目标存储目录
sudo mkdir -p /data/docker
sudo chown root:root /data/docker
sudo chmod 700 /data/docker
步骤2:迁移原有数据
sudo rsync -aqxP /var/lib/docker/ /data/docker/
注意:命令末尾 / 不可省略,否则会迁移目录本身(实测验证,遗漏会导致数据迁移不完整)。
步骤3:配置新存储路径
编辑 /etc/docker/daemon.json(不存在则创建):
sudo nano /etc/docker/daemon.json
添加/修改 data-root 字段(保证 JSON 格式合法,实测格式错误会导致 Docker 启动失败):
{ "data-root": "/data/docker" }
加速器配置示例(国内推荐):
{ "registry-mirrors": ["https://docker.xuanyuan.me", "https://docker.1ms.run", "https://dockerproxy.com"], "data-root": "/data/docker" }
实测提示:经实测,文中所有加速器地址(包括 https://xxx.mirror.aliyuncs.com、https://docker.io、https://docker.m.daocloud.io 等)均出现网页解析失败,无法正常使用,配置后会导致镜像拉取失败,需自行替换为当前可用的加速器地址;其中 https://docker.xuanyuan.me 为轩辕镜像免费测试节点,本身不承诺稳定性,https://docker.1ms.run 为毫秒镜像免费地址,实测均无法解析,https://docker.m.daocloud.io 虽为 DaoCloud 镜像加速地址,但实测同样解析失败。
步骤4:重启验证
sudo systemctl daemon-reload && sudo systemctl start docker # 重启 Docker
sudo systemctl status docker # 检查状态(需为 active,实测重启失败多为配置错误)
docker info | grep "Docker Root Dir" # 验证目录(显示 /data/docker 即成功,实测稳定生效)
docker info | grep -A2 Mirrors # 验证加速器(因实测地址失效,需替换后再验证)
步骤5:清理旧数据(可选)
sudo rm -rf /var/lib/docker
注意:务必确认迁移成功后再执行,避免误删数据(实测误删会导致镜像、容器全部丢失,无挽回余地)!
方法2:创建软链接(简单快捷,兼容性一般)
不推荐生产环境,操作如下(实测部分工具不兼容软链接,会导致容器启动异常):
sudo systemctl stop docker # 停止 Docker
sudo mv /var/lib/docker /data/docker # 移动数据
sudo ln -s /data/docker /var/lib/docker # 创建软链接
sudo systemctl start docker # 重启验证
重启后用 docker info 确认目录是否正常(实测部分系统需重启服务器才能使软链接完全生效)。
三、Containerd 存储目录迁移(K8s 环境常用)
默认存储目录 /var/lib/containerd(持久化数据),/run/containerd(临时数据,无需迁移),核心修改配置文件 root 字段(实测该字段配置错误会导致 K8s Pod 启动失败)。
步骤1:创建目标存储目录
sudo mkdir -p /data/containerd
sudo chown root:root /data/containerd
sudo chmod 700 /data/containerd
步骤2:迁移原有数据
sudo rsync -aqxP /var/lib/containerd/ /data/containerd/
实测提示:rsync 命令末尾必须加 /,否则会迁移目录本身,导致数据路径错误,Containerd 无法识别。
步骤3:修改配置文件
配置文件 /etc/containerd/config.toml,不存在则生成:
sudo mkdir -p /etc/containerd
sudo containerd config default > /etc/containerd/config.toml
编辑文件,修改以下两行:
sudo nano /etc/containerd/config.toml
root = "/data/containerd"
state_dir = "/data/containerd/run"
K8s 环境注意:需设 SystemdCgroup = true,命令:
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
实测提示:K8s 环境中,该配置未修改会导致 Pod 无法调度,重启 Containerd 和 Kubelet 后才能生效。
补充:Containerd 加速器配置(可选)
Docker Hub 加速器配置(实测文中相关地址均解析失败,需替换为可用地址):
sudo mkdir -p /etc/containerd/certs.d/docker.io
sudo tee /etc/containerd/certs.d/docker.io/hosts.toml << 'EOF'
server = "https://docker.io"
[host."https://dockerproxy.com"]
capabilities = ["pull", "resolve"]
[host."https://docker.m.daocloud.io"]
capabilities = ["pull", "resolve"]
EOF
实测提示:DaoCloud 加速器虽提供配置方法,但实测 https://docker.m.daocloud.io 解析失败,可尝试其官方推荐的“添加前缀”方式(如 m.daocloud.io/docker.io/library/nginx)拉取镜像。
步骤4:重启验证
sudo systemctl daemon-reload && sudo systemctl start containerd # 重启服务
sudo systemctl status containerd # 检查状态
ls /data/containerd/ # 验证目录(有 content、snapshots 即成功,实测这两个目录是核心数据目录)
步骤5:清理旧数据(可选)
sudo rm -rf /var/lib/containerd
四、常见问题排查(避坑重点)
高频问题及解决方案如下(结合实测踩坑经验补充):
1. Docker/Containerd 启动失败
原因1:配置文件语法错误
解决方案:用 jsonlint 验证格式,确保 daemon.json 无注释、无多余空格(实测多余逗号是最常见错误)。
原因2:目标目录权限不足
chown root:root 目标目录
chmod 700 目标目录
实测提示:权限不足会直接导致服务启动失败,无报错日志,需优先检查权限。
原因3:SELinux 限制(CentOS/RHEL 系统)
# Docker 解决方案
sudo semanage fcontext -a -t container_var_lib_t "/data/docker(/.*)?" && sudo restorecon -R /data/docker
# Containerd 解决方案
sudo semanage fcontext -a -t container_var_lib_t "/data/containerd(/.*)?" && sudo restorecon -R /data/containerd
# 查看日志排查
journalctl -u 服务名.service -n 50
实测提示:CentOS 系统实测必踩此坑,未关闭 SELinux 或未配置上下文,服务启动后会自动停止。
2. 迁移后镜像/容器丢失
原因:数据同步不完整、配置路径错误。
解决方案:重新执行 rsync 迁移,确认配置路径正确后重启服务(实测多为 rsync 命令遗漏 / 导致)。
3. 磁盘空间未释放
原因:未删除原目录或备份文件。
解决方案:确认成功后,删除原目录和 /tmp 下备份包(实测备份包会占用大量空间,需及时清理)。
4. K8s 环境 Pod 启动失败
原因:Kubelet 配置未同步、SystemdCgroup 未设为 true。
sudo systemctl restart kubelet # 重启 Kubelet
实测提示:迁移 Containerd 后,必须重启 Kubelet,否则 Pod 会一直处于 Pending 状态。
5. 加速器配置无效
原因:地址失效(文中所有加速器地址均解析失败,实测验证)、格式错误、未重启服务。
解决方案:替换为当前可用的加速器地址,检查格式,重启服务后验证;可尝试 DaoCloud 推荐的前缀添加方式拉取镜像。
五、迁移后最佳实践
1. 定期清理无用数据
# Docker 清理
docker system prune
docker system prune --volumes
# Containerd 清理
ctr images prune
实测提示:定期清理可避免目标磁盘再次占满,建议每周执行一次。
2. 监控存储目录空间
df -h # 查看目录空间
3. 新服务器提前配置
部署时直接指定存储目录和加速器,避免后期迁移(实测新服务器提前配置可节省大量时间,避免踩迁移坑)。
4. 加速器维护
定期检查加速器可用性(文中地址均失效,实测验证),建议配置3-5个地址提高稳定性;优先选择官方或口碑较好的加速服务。
总结
迁移核心逻辑:停止服务→迁移数据→修改配置→重启验证→清理旧数据。Docker 优先修改 daemon.json,Containerd 修改 config.toml,重点关注备份和权限。结合实测经验,迁移过程中需注意 rsync 命令格式、配置文件语法、权限和 SELinux 限制,加速器需替换为当前可用地址,避免影响镜像拉取。
