服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-10-10 简米科技 3,820 字 9 分钟阅读

虚拟机docker迁移,如何避免服务中断与数据丢失?,docker迁移注意什么

导读虚拟机docker迁移想做到不中断业务、不丢数据,核心就一条:先把状态冻结,再平滑搬移,最后灰度切换,听起来有点绕,但拆开看其实不复杂,很多朋友把迁移想成了“拷文件”,结果要么容器起不来,要么数据库丢了一大截,今天这篇就把虚拟机里docker迁移的全流程讲透,重点说清楚怎么保数据、怎么减中断,迁移前必须搞清楚的……

虚拟机docker迁移想做到不中断业务、不丢数据,核心就一条:先把状态冻结,再平滑搬移,最后灰度切换。听起来有点绕,但拆开看其实不复杂,很多朋友把迁移想成了“拷文件”,结果要么容器起不来,要么数据库丢了一大截,今天这篇就把虚拟机里docker迁移的全流程讲透,重点说清楚怎么保数据、怎么减中断。

迁移前必须搞清楚的三个问题

你搬的是“容器”还是“数据”

docker迁移这个词太宽泛了,有人只是想换个宿主机,把镜像拉过去就行;有人是把整个虚拟机从A平台搬到B平台,比如从VMware迁到KVM,这两种情况的处理方式完全不同,前者只要搞定镜像和容器配置,后者还得考虑操作系统层、网络、存储的适配。

迁移前先问自己三个问题:

  • 容器内的应用是无状态的还是有状态的?
  • 数据是存在容器可写层、数据卷里,还是宿主机目录里?
  • 迁移期间业务能接受多久的不可用?

这三个问题决定了后续所有操作策略,无状态服务怎么迁都行,有状态服务比如MySQL、Redis、ES这类,核心全在数据一致性上。

目标机器的环境是否就绪

很多迁移失败不是迁移本身的问题,而是目标机器环境没准备好,docker版本、内核参数、存储驱动、网络模式,这四样但凡有一样对不上,容器起来就是各种奇奇怪怪的报错。

动手迁移之前,先把目标机器的环境清单列出来:

  • docker版本和源机器保持一致,或者至少兼容
  • 检查overlay2存储驱动是否启用
  • 确认需要映射的端口没有被占用
  • 如果有自定义网络,提前在目标机器上建好

迁移方案的选择依据

行业共识认为,没有一套方案能同时满足“零中断”和“零丢失”,关键在于取舍,纯离线迁移简单可靠,但业务会有一段时间完全不可用;在线迁移能缩短中断时间,但复杂度成倍上升。

选择方案时主要看两点:业务对连续性的要求有多高,以及数据量有多大,几十GB的数据和几个TB的数据,策略完全不在一个量级上。

最稳妥的离线迁移流程:慢但不出错

第一步:用docker commit保存容器状态

对于运行中的容器,执行docker commit命令可以生成一个镜像文件,这个命令的含义是把当前容器的文件系统状态,连同运行时的环境变量、启动命令等一起固化为镜像。

虚拟机docker迁移,如何避免服务中断与数据丢失?,docker迁移注意什么

docker commit -m "backup before migration" -a "ops" 容器ID myapp:backup

这里有一个关键细节:commit出来的镜像包含了容器可写层的数据,但不包含通过-v或--mount挂载的数据卷内容,这是个极其常见的坑,后面会专门说。

第二步:镜像导出与传输

commit完成后,用save命令把镜像导出为tar包:

docker save -o /backup/myapp.tar myapp:backup

传输到目标机器的工具有很多,内网用scp,外网用rsync,都行,数据量大的时候可以考虑先压缩再传输:

tar -czf myapp.tar.gz myapp.tar

传输完成后在目标机器上执行加载:

docker load -i myapp.tar

第三步:容器重建与参数还原

镜像加载成功只是第一步,还需要用原来的参数重新创建容器,这里建议提前把所有容器的配置信息导出备份:

docker inspect 容器ID > container_info.json

创建新容器时,重点检查三块:端口映射的-p参数、环境变量的-e参数、数据卷挂载的-v参数,这些信息都在inspect输出里,对着抄就行了。

docker数据卷迁移:最容易丢数据的一环

为什么数据卷不能靠commit搞定

前面说了,docker commit不管数据卷,原因是数据卷的设计理念就是解耦的,它不属于镜像的文件系统,很多朋友在迁移时只打了镜像包,结果数据库数据全丢,就是这个原因。

数据卷的迁移需要单独处理,主要用docker run --volumes-from配合tar命令完成,这个操作被称为“数据卷备份三连”:

docker run --rm --volumes-from 容器名 -v $(pwd):/backup ubuntu tar cvf /backup/data.tar 数据卷路径

在目标机器上恢复:

docker run --rm --volumes-from 新容器名 -v $(pwd):/backup ubuntu tar xvf /backup/data.tar

数据量大于100GB时的处理建议

数据量大时,tar打包再传输的方式效率很低,业内专家指出,这类场景下用rsync做增量同步比一次性tar更实用,具体做法是先全量同步一次,再根据数据变化情况做增量同步,最后在停机窗口做最后一次增量,然后把数据卷挂载到新容器上。

虚拟机docker迁移,如何避免服务中断与数据丢失?,docker迁移注意什么

数据库类应用的迁移,强烈建议使用自带工具,比如MySQL用mysqldump或xtrabackup,PostgreSQL用pg_dump,Redis用持久化文件加AOF重放,用文件级备份去迁数据库,在数据一致性上始终存在风险。

减少服务中断时间:在线迁移思路

先扩容再缩容的滚动策略

如果业务架构允许,一种非常实用的做法是在目标机器上先把新容器跑起来,然后通过负载均衡把流量逐步切过去,这个方案不需要修改任何docker数据,纯粹是应用层的流量调度,中断时间几乎为零。

具体操作路径:

  1. 在目标机器上完整部署一套环境,导入数据
  2. 用负载均衡配置新后端,权重设低
  3. 观察运行状态正常后逐步调整权重
  4. 旧容器全部摘除后回收资源

这套方案适合无状态或做了主从复制的应用,对单机有状态服务不适用,因为同一份数据不能同时被两个实例写。

停机窗口内的“伪实时”迁移法

对于无法在线迁移的场景,只能用最短的停机窗口完成操作,流程是:先同步数据,再停服务,做最终增量同步,然后启动新机器。

比如迁一个docker里的MySQL:

  1. 先用mysqldump全量导出,传到目标机器并导入
  2. 开启binlog记录,记录导出后的binlog位置
  3. 停机窗口内,将新增binlog同步到目标机器
  4. 确认数据一致后启动新服务,切换流量

这种方案的中断时长取决于增量数据的大小,通常能控制在分钟级,对多数中小业务来说,已经是可接受的范围了。

网络配置与IP地址的迁移陷阱

docker默认网络模式的影响

docker安装时会创建三个默认网络:bridge、host、none,默认情况下容器跑在bridge网络,IP是由docker自动分配的,这个IP在容器重建后会变化,如果应用里写死了旧IP,迁移后就会出问题。

更严重的是,如果用了docker自带的overlay网络或者自定义网络,迁移后需要重建网络,容器IP大概率会变,应用间的相互调用最好用的方式是用容器名或服务名来访问,而不是IP,这样迁移后不会受影响。

虚拟机docker迁移,如何避免服务中断与数据丢失?,docker迁移注意什么

需要保持固定IP的场景怎么办

有些老应用不方便改配置,必须保持固定的容器IP,这种情况下,在目标机器上需要先创建自定义网络,然后在启动容器时指定静态IP:

docker network create --subnet=172.20.0.0/24 mynet
docker run --network mynet --ip 172.20.0.10 myapp:backup

虚拟机层面如果用的是桥接网络,容器IP会直接绑定在宿主机网络上,这种情况下还要注意目标机器的物理网卡配置、网关设置是否一致。

端口冲突与防火墙策略

目标机器上如果还有其他服务在用同一个宿主机端口,容器启动时就会报端口冲突,迁移前用ss -lntp检查一下端口占用情况,比启动失败再排查高效得多。

防火墙是另一个容易被忽视的环节,尤其是云服务器,安全组策略不放开端口,新机器上的服务外部根本访问不了,迁移前把端口放行规则完整梳理一遍,别让配置问题变成了“迁移失败”的替罪羊。

迁移后的完整性验证清单

启动级的验证项

容器启动只是开始,启动成功不代表迁移成功,要验证的方面包括:

  • 容器状态是否为Up,重启策略是否生效
  • 日志里有没有error或exception记录
  • 端口监听是否正常,所需端口都能telnet通
  • 容器内进程数是否和迁移前一致

数据层面的校验方法

数据完整性校验是迁移质量的核心,最直接的方式是对比迁移前后数据库行数、关键表的总记录数,如果是文件类数据,可以对比文件数量和总大小。

业务允许的情况下,可以做一次全链路演练,模拟一次用户请求,看从入口到存储的完整服务链路是否工作正常,这一步能发现很多单点验证时发现不了的问题。

回滚预案不能省

再严谨的迁移也有失败的可能,迁移前务必保留源机器上的所有数据,确认新环境稳定运行一段时间后再清理,这个时间周期建议至少是7天,如果业务流量有明显周期性,最好跨过一个完整周期再清理。

docker迁移的复杂度取决于你对自身业务状态的掌握程度,无状态应用轻松迁,有状态应用谨慎迁,数据库应用专业迁,把镜像、数据卷、网络三件事分开处理,按流程走,你会发现迁移没那么可怕。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱