虚拟机迁移
虚拟机迁移也就是把一台虚拟机从原计算节点迁移到一个新的计算节点,并且能够保证虚拟机在新的计算节点可以正常工作,
虚拟机的迁移根据虚拟机的运行状态可以分为两种1、动态迁移;2、静态迁移
虚拟机动态迁移
虚拟机的动态迁移又被称之为热迁移,或者被称之为在线迁移。
虚拟机的动态迁移,便是在虚拟机处于运行中的状态下,在保证虚拟机业务不中断的情况下,将虚拟机从源计算节点迁移到目标计算节点,整个过程对用户来说没有较大影响,用户的业务工作正常进行。
迁移过程中,主要处理的是虚拟机的数据在线迁移,而虚拟机的数据主要包含三个方面
- 虚拟机内存数据
虚拟机在开机运行状态,内存会保留系统运行中的所有所需数据,所有程序的运行都是在内存中进行的,因此内存的数据对虚拟机的影响非常大。 - 虚拟机设备状态
及虚拟机运行过程中的所有相关设备的状态标记,例如CPU寄存器、显存等。 - 虚拟机磁盘文件
虚拟机的磁盘文件,便是虚拟机的系统文件,相当于PC的硬盘。是虚拟机所有数据的保存地方。
动态迁移根据虚拟机的系统盘磁盘文件是否在共享存储上分为基于共享存储的动态迁移和基于本地存储的块迁移。
基于共享存储的动态迁移
基于共享存储的动态迁移,也就是虚拟机的磁盘文件在共享存储上,并没有存放在虚拟机所在的计算节点上,而是通过一定的协议(网络协议、iscsi协议)关联到计算节点上并提供给虚拟机使用。
所以该类型的迁移不需要迁移磁盘文件信息,只需要将虚拟机的内存数据和设备状态迁移到目标计算节点上即可。
基于本地存储的块迁移
该类型的迁移和共享存储迁移相比,就是虚拟机的磁盘文件在本地,和虚拟机在同一个计算节点上,一般都是file的形式存在,以文件形式存储提供给虚拟机使用。
这样我们在迁移虚拟机时,就需要将虚拟机的数据中内存、设备状态、磁盘文件拷贝到目标计算节点以供使用。
而磁盘文件的拷贝是一个漫长的过程,迁移时间较长,一般都不太考虑。
静态迁移
静态迁移,也成为虚拟机的离线迁移,就是在关机状态下将虚拟机从一个计算节点迁移到新的计算节点。由于虚拟机是关机状态,所以不会存在虚拟机运行中的数据,即不存在内存数据和设备状态,这样迁移过程中,只需要拷贝虚拟机虚拟磁盘文件与配置文件到目标虚拟主机中,实现的迁移。
如果虚拟机磁盘文件在共享存储,可以迅速完成迁移。如果在本地存储,便需要迁移较大文件的磁盘文件。
上述是虚拟机迁移的相关技术,而本文重点关注的是虚拟机动态迁移,研究动态迁移过程中的工作流程和原理。
虚拟机动态迁移研究
虚拟机的迁移是一个复杂的过程,需要多方面的协助。本文根据OpenStack云平台和KVM虚拟化技术对虚拟机的迁移过程进行梳理,查看核心迁移过程以及所必需的协助工作。具体的迁移过程如下。
目标节点检查
在迁移之前,我们需要在迁移的目标节点进行校验,主要检查目标节点的资源是否足够、处理器的类型是否相同。不同型号类型处理器的计算节点之间是不允许进行迁移的。
目标节点准备工作
平台对目标计算节点完成相关检查后,在迁移之前还需要做一系列的准备工作。
- 创建虚拟机文件路径
在对应的路径下创建要迁移的虚拟机的目录文件,以接收迁移的虚拟机配置文件,如果是本地存储虚拟机,还需要接收磁盘文件数据. - 检查镜像
根据虚拟机的镜像检查目标计算节点是否已经下载过改镜像。如果没有需要重新下载镜像到本地。 - 迁移拷贝文件
将虚拟机的配置文件或者磁盘文件从源计算节点拷贝到目标节点的指定路径。 - 建立网络端口
在目标计算节点的虚拟交换机上(openvswitch或者linuxbridge)创建该虚拟机所需要使用到的网络端口。 - 建立和存储的关联关系
如果虚拟机使用到其他存储,需要建立本地计算服务和存储服务之间的关系。
迁移过程
在完成上节所提到的所有准备工作,就可以触发虚拟机的迁移。虚拟化管理层Libvirt给虚拟机对应的qemu进程发送一个迁移的命令(migrateToURI),并指定相关参数,例如是否需要迁移块设备、最大停机时间、迁移带宽。
这样虚拟机就开始进行了迁移,剩下就是等待迁移完成。在迁移过程中,因为虚拟机是运行状态,这样内存数据一直处于更新中,设备状态和IO也是不断变化中。那么什么时候才能算迁移完成,内存不断刷新新数据,出现大量脏数据,导致虚拟机一直无法完成迁移。这个问题的解决详见内存数据一致性校验章节介绍。
迁移后续操作
在对虚拟机完成迁移后,平台需要对虚拟机进行后续的完善工作。这些完善工作在源计算节点和目标计算节点都需要进行。
源计算节点
在源计算节点,依然残留虚拟机的部分数据。所以需要做一下几个处理工作
1、 关闭虚拟机
2、 删除网络连接
3、 删除存储连接
目标计算节点
1、 启动虚拟机
2、 建立网络连接,连接到虚拟机交换机。
网络切换
网络切换是虚拟机迁移的一个重要工作,相当于把网线从一台PC上拔下插到另一台PC上。这个时候的处理就是发送一个arp广播,告知虚拟机的mac地址已经变更到另外一台虚拟交换机的某个端口,建立到新的端口的网络连接。由于这种arp广播的网络切换时间很短,用户几乎不会感知到网络的短暂终端。
内存数据一致性校验
在虚拟机迁移任务启动后,虚拟机便一直在迁移相关数据,剩下的挑战是如何保证数据迁移的一致性,因为此时VM处于运行状态,里面时刻发生内存更新、磁盘io操作和设备状态变更,而VM是paused状态,只通过一个线程接收VM进程发过来的数据。
为此,在迁移过程中各种数据如何有序迁移?首先,Libvirt会发送qmp_dirve_mirror命令来通知Qemu进行虚拟机磁盘数据迁移,从而在源端和目标端直接同步磁盘数据。然后,Libvirt会再次发送qmp_migrate命令通知Qemu进行虚拟机内存数据迁移,进一步完成虚拟机主要数据的迁移。最后,由于设备状态对应的数据量很少,在迁移最后阶段会通过一次性同步,将Qemu里每个设备注册的状态同步到目标端。
另外,迁移过程中发生变更的数据如何迁移?如果不迁移变更的数据,那数据必然不一致,也表明迁移还不能结束,因此Qemu一般通过数据迁移准备、数据迁移、数据迁移收尾三个步骤来完成。
循环调用磁盘和内存迁移函数也是按阶段来分别调用的。首先,循环调用磁盘和内存迁移函数的迁移数据准备功能,即前期准备工作,例如把磁盘按block为单位组织成一个数组,并设置记录脏块机制;把内存所有页全部设置为脏页,并发送开始迁移的标志到VM’的进程。
紧接着,需要进行真正的数据迁移,Qemu在这个阶段调用磁盘和内存迁移函数的第二步骤功能,并且要求必须等磁盘数据迁移完成后才会执行内存数据迁移。如上图所示,Qemu首先会进行磁盘(内存)的全量数据迁移,依次将每个block(页)迁移到目标端DestHost。
然后再通过多次迭代,将迁移过程中虚拟机产生的新数据迁移到目标端DestHost(如上图所示)。这一迭代过程是收敛的,收敛依据与之前设置的带宽、最大停机时间有关。同时,在迭代过程中,Qemu将边迁移边记录剩下的脏数据大小,并与停机时间进行比较,如果这个值比停机时间大,那么继续迁移,如果比停机时间小,那么源端Qemu进程就会暂停,从而避免产生新的脏数据,以便进行迁移收尾工作。
在虚拟机暂停之后,进入第三步迁移收尾工作,源端Qemu进程会把磁盘、内存脏数据和设备状态一次性同步到目标端,完成时VM和VM’的数据将会一致。这时,上层管理软件会把VM关闭,并把VM’的vcpu恢复运行状态,整个虚拟机的数据迁移就完成了。