虚拟机迁移
虚拟机迁移是一项非常酷的技术,迁移(migration)包括系统整体的迁移和某个工作负载的迁移,系统整体迁移是将系统上的所有软件,包括操作系统,完全复制到另一台物理硬件机器上,而工作负载迁移仅仅迁移特定的工作负载。
虚拟化技术的出现,丰富了迁移技术的内涵和实践,在传统的应用环境中,没有虚拟化技术的支持,系统整体迁移主要是静态迁移,静态迁移主要考系统备份和恢复技术,将系统的软件完全复制到另一台机器上,可以通过先做出来系统的镜像文件,然后复制到其他机器上,或者直接使用硬盘复制达到迁移的目的。早些年网吧常用的GHOST备份恢复技术,就是这种类型的迁移。
在虚拟化环境中的迁移,又分为静态迁移和动态迁移,或者冷迁移和热迁移,也可以叫离线迁移和在线迁移。静态迁移和动态迁移最大的区别就是,静态迁移有一段明显的时间客户机中的服务不可用,而动态迁移则没有明显的服务暂停时间。
虚拟化中的静态迁移也可以分为两种,一种是关闭客户机后,将其硬盘镜像复制到另一台宿主机上然后恢复启动,这种迁移不能保留客户机中运行的工作负载,另一种是两台宿主机共享存储系统,只需在暂停(不是完全关闭)客户机后,复制其内存镜像到另一台宿主机中恢复启动即可,这种迁移可以保持客户机迁移前的内存状态和系统的系统运行的工作负载。
动态迁移是指在保证客户机上应用服务正常运行的同时,让客户机在不同的宿主机之间进行迁移,为了保证迁移过程中客户机服务的可用性,迁移过程仅有非常短暂的停机时间,动态迁移允许系统管理员将客户机在不同的物理机上迁移,同时不会断开访问客户机中服务的客户端或应用程序的连接。迁移后保证客户机的内存,硬盘存储,网络连接在迁移到目标的主机后依然保持不变,而且迁移过程的服务暂停时间较短。
另外,虚拟化的底层技术有多种,比如常见的kvm, virtualbox, Xen等,对于虚拟化环境的迁移,不仅包括相同Hypervisor之间的客户机迁移,比如KVM迁移到KVM, Xen迁移到Xen,还包括不同的Hypervisor之间客户机的迁移,比如Xen迁移到KVM,VMware迁移到KVM等等。
不同的迁移技术可以总结如下图表示:
KVM静态迁移实践
step1:启动源虚拟机
$ sudo qemu-system-x86_64 -m 4096 -smp 4 --enable-kvm -drive file=./ps.img -monitor stdio
这一步需要注意两点:
1.启动QEMU虚拟机中不能不能带有透传的PCIE设备,如果虚拟机安装的时候包含PCIE设备的透传,则需要将透传参数删掉后再启动虚拟机。
2.最好运行一个负载应用,比如top程序,以便迁移后检测负载是否正常运行。
step2:备份虚拟机
在qemu的monitor控制台中,输入如下命令保存完整的虚拟机快照:
savevm czl.vm.tag
这里的"savem"命令保存的完整客户机状态包括CPU,内存,设备状态,磁盘内容等。这种方法需要使用qcow2格式的磁盘映像文件,目前只有这种格式的文件才支持快照特性。
然后关闭源虚拟机,同时将虚拟机安装镜像(本例中是ps.img)通过网络或者离线磁盘拷贝到目标机器环境下。
step3:在目标机恢复虚拟机快照
在目标机中,首先用源主机一样的命令启动拷贝过来的虚拟机镜像(本例是上一步拷贝过来的ps.img)
sudo qemu-system-x86_64 -m 4096 -smp 4 --enable-kvm -drive file=/media/zlcao/7CC840FCC840B5E4/out/ps.img -monitor stdio
然后在qemu monitor中,用如下命令恢复上一步保存下来的快照。即可完全加载保存快照时保存的客户机状态,在快照恢复的瞬间,虚拟机界面将从上图转换为下图,显示的恰好是我们保存快照时,虚拟机TOP副在运行时刻的状态。
loadvm czl.vm.tag
KVM动态迁移实践
动态迁移原理如下,为了方便实现操作系统镜像的共享,避免不必要的复制,使用一台独立的PC提供NFS服务。
在不考虑磁盘存储复制的情况下(基于共享存储系统),KVM动态迁移的过程为:在客户机动态迁移开始后客户机依然在源宿主机上运行,与此同时客户机的内存页被传输到了目的主机上,QEMU/KVM会监控并记录下迁移过程中所有已被传输的内存页的任何修改,并在所有的内存页都被传输完成后立即开始传输在前面过程中的更改内容。QEMU/KVM也会估计迁移过程中的传输速度,当剩余的内存数据量能够在一个可设定的迁移停机时间内传输完成时,QEMU/KVM将会关闭源宿主机上的客户机,在将剩余的数据量传输到目的机上去。最后传输过来的内存内容在目的宿主机上恢复客户机的运行状态。至此,KVM的动态迁移操作就完成了。
除非是一些硬件或者配置差异,否则迁移后的目标虚拟机尽可能与迁移前一致。
下面开始实践:
step1:
第一步参考如下两篇博客搭建NFS服务器和在源主机上安装QEMU KVM虚拟机:
Homebrew NFS Network File Sharing Environment-CSDN博客
ubuntu18.04下pass-through直通realteck PCI设备到qemu-kvm虚拟机实践_kvm网卡直通_papaofdoudou的博客-CSDN博客
step2:
在源主机上挂在NFS上GUEST OS镜像,并启动客户机,命令行操作如下:
sudo mount -t nfs 192.168.2.35:/var/nfs/gernel /mnt
启动虚拟机:
sudo qemu-system-x86_64 -m 4096 -smp 4 --enable-kvm -drive file=/mnt/ps.img -monitor stdio
需要注意的是,基于同样的原因,需要在源机中启动虚拟机后,在虚拟机中运行一个TOP负载程序,以验证热迁移下保证负载运行的效果。
step3:
在目标宿主机上也挂在NFS上的客户机镜像目录,并且启动一个guest os用于接收动态迁移过来的内存内容等等,操作如下:
sudo mount -t nfs 192.168.2.35:/var/nfs/gernel /mnt
启动接受GUEST OS:
sudo qemu-system-x86_64 -m 4096 -smp 4 --enable-kvm -drive file=/mnt/ps.img -monitor stdio -incoming tcp:0:6670
在这一步中,目的宿主机上的操作有两个值得注意的地方,一是NFS的挂载目录必须与源宿主机上保持完全一致,二是启动GUEST OS的命令与源宿主机上的启动命令一致,但是要增加 "-incoming"选项。
这里在启动客户机的QEMU命令中增加了"-incoming tcp:0:6670"参数,它表示在本地目标机的端口6670上建立一个TCP SOCKET连接,用来接收来自源主机的动态迁移过来的内容,其中"0"表示允许来自任何主机的连接,incoming参数使得QEMU进程进入迁移监听模式,而不是真正以命令行中的镜像运行客户机。从图形界面中看到,GUEST OS目前还是黑色的,没有像普通GUEST OS那样启动,实际上,这是QEMU进程在等待动态迁移的连接请求。
下一步就要到源主机端发送这个迁移请求了。
step4:
在源宿主机的guest os的qemu monitor中(通过启动参数 -monitor stdio开启,或者ctrl+alt+2打开)使用命令
migrate tcp:IP:6670
即可发起动态迁移的过程,这里的IP和端口6670都是目标主机的IP和端口地址,端口号必须和上异步设置的端口号相同,而源主机端则会随即分配一个幸运端口号负责和目标主机的数据传输。
(qemu) migrate tcp:192.168.2.28:6670
此时,迁移过程已经开始,依据当前系统负载和网络情况,迁移可以在数分钟到数个小时内完成。
此时在源端查看TCP连接状态,发现一个从本地56924端口到远程目标机的6670端口的TCP连接,连接状态为已建立。
同样的连接在目标主机端也能看到,只是收发角色恰好进行了交换。
qemu monitor中迁移命令行处于阻塞执行状态时表示迁移正在进行,当迁移结束后,qemu monitor才会进入可交互状态。