当前,云计算技术的飞速发展对企业降低 IT 投入成本、减少系统运维开销、加速业务交付速度、动态调整业务规模以及保障业务可靠性具有重要意义。
目前,云计算带来的这些好处依赖于底层虚拟化技术将服务器资源虚拟出多份可供用户使用的计算资源,从而方便云计算提供商为企业用户提供高效、弹性、高可靠和可维护的底层 IT 基础架构。其中,虚拟机在线迁移技术正是构建虚拟机技术上述优点的重要组成部分,该技术可以简化系统维护复杂度、实现业务负载均衡、优化服务器能源消耗并增强云计算可靠性。
作为国内领先的公有云服务提供商,UCloud 对其云平台在线迁移方案进行了深入的优化,通过实践证明这些优化能够很好的应对线上各种迁移场景,为用户业务的稳定与可靠提供了重要保障。
原理
在线迁移技术的本质就是在虚拟机不停机的情况下,不同物理机之间进行在线跨机迁移。首先是在目标物理机建立相同配置的虚拟机,然后进行各类数据迁移,最终快速切换到目标端新虚拟机。由于整个迁移过程中,绝大多数时间内用户虚拟机都能保持正常运行,且最后阶段的切换过程非常短暂,不会造成用户业务中断,对用户运行在虚拟机中的业务几乎没有影响,因此在线迁移技术在实现云平台资源动态调整以及故障处理方面具有重要意义。
因为云计算平台除了核心的底层虚拟化技术外,还包括 SDN 网络、分布式存储和运维管理系统等,所以在线迁移方案不仅要包括跨机迁移技术本身,还包括迁移前后虚拟机的管理信息以及网络和磁盘配置信息的切换等工作。为此,本文将在线迁移过程划分为三个阶段:准备阶段、迁移阶段和切换阶段。
考虑到 UCloud 云计算平台采用 KVM 虚拟化技术实现虚拟化底层方案,同时共享存储的在线迁移仅是非共享存储的一个特例,因此本节将以非共享存储为例,详细介绍 UCloud 底层 KVM 虚拟化技术如何进行虚拟机的在线迁移。其中,迁移环境为虚拟化底层 KVM+Qemu、虚拟化管理 Libvirt、虚拟化网络 Openvswitch。
假设将源物理机 SourceHost 的一个虚拟机 VM 迁移到目标物理机 DestHost,非共享存储虚拟机在线迁移过程的具体步骤如下:
准备阶段
Step.1 选择一台具有足够磁盘和内存资源的物理机 DestHost,并在 DestHost 上创建 VM 对应的系统盘和数据盘,同时选定接收迁移数据的 tcp 端口(如图 1 所示),这两个磁盘在 DestHost 和 SourceHost 上的路径必须完全一致。不同的是,DestHost 上初始创建的只是空盘,上面没有真实数据。
图 1 在目标端新建虚拟机镜像
Step.2 通过虚拟化管理软件 Libvirt 在 DestHost 上创建一个和 VM 同样配置的虚拟机 VM’,系统盘和数据盘使用 Step.1 中创建的系统盘和数据盘(如图 2 所示)。VM’当前是 paused 状态,虚拟机 VM’的 vcpu 处于暂停状态,同时虚拟机 VM’会通过监听一个内网的 tcp 端口来接收迁移数据。
图 2 在目标端创建新虚拟机
迁移阶段
Step.3 虚拟化管理层 Libvirt 给 VM 对应的 Qemu 进程发出一个迁移指令,并指定参数,例如指定 DestHost 为目标、需要迁移块设备、最大停机时间、迁移带宽限制等,然后迁移数据就会通过指定 tcp 链路传输给 DestHost 上的 VM’。需要注意,迁移数据的网络包不是经过 vswitch,而是直接从 SourceHost 的 ethx 网卡出,进到 DestHost 的 ethx,因为 VM’对应 Qemu 进程正作为 DestHost 一个用户态进程,监听在 ethx 对应的内网 ip(如图 3 所示)。
图 3 虚拟机迁移数据
Step.4 经过前面三步,虚拟机的数据就正式开始迁移,剩下的挑战是如何保证数据迁移的一致性,因为此时 VM 处于运行状态,里面时刻发生内存更新、磁盘 io 操作和设备状态变更,而 VM’是 paused 状态,只通过一个线程接收 VM 进程发过来的数据。
为此,在迁移过程中各种数据如何有序迁移?首先,Libvirt 会发送 qmp_dirve_mirror 命令来通知 Qemu 进行虚拟机磁盘数据迁移,从而在源端和目标端直接同步磁盘数据。然后,Libvirt 会再次发送 qmp_migrate 命令通知 Qemu 进行虚拟机内存数据迁移,进一步完成虚拟机主要数据的迁移。最后,由于设备状态对应的数据量很少,在迁移最后阶段会通过一次性同步,将 Qemu 里每个设备注册的状态同步到目标端。
另外,迁移过程中发生变更的数据如何迁移?如果不迁移变更的数据,那数据必然不一致,也表明迁移还不能结束,因此 Qemu 一般通过数据迁移准备、数据迁移、数据迁移收尾三个步骤来完成。
循环调用磁盘和内存迁移函数也是按阶段来分别调用的。 首先,循环调用磁盘和内存迁移函数的迁移数据准备功能,即前期准备工作,例如把磁盘按 block 为单位组织成一个数组,并设置记录脏块机制;把内存所有页全部设置为脏页,并发送开始迁移的标志到 VM’的进程。
图 4 全量数据迁移示意图
紧接着,需要进行真正的数据迁移,Qemu 在这个阶段调用磁盘和内存迁移函数的第二步骤功能,并且要求必须等磁盘数据迁移完成后才会执行内存数据迁移。如图 4 所示,Qemu 首先会进行磁盘(内存)的全量数据迁移,依次将每个 block(页)迁移到目标端 DestHost。
图 5 增量数据迁移示意图
然后再通过多次迭代,将迁移过程中虚拟机产生的新数据迁移到目标端 DestHost(如图 5 所示)。这一迭代过程是收敛的,收敛依据与之前设置的带宽、最大停机时间有关。同时,在迭代过程中,Qemu 将边迁移边记录剩下的脏数据大小,并与停机时间进行比较,如果这个值比停机时间大,那么继续迁移,如果比停机时间小,那么源端 Qemu 进程就会暂停,从而避免产生新的脏数据,以便进行迁移收尾工作。
在虚拟机暂停之后,进入第三步迁移收尾工作,源端 Qemu 进程会把磁盘、内存脏数据和设备状态一次性同步到目标端,完成时 VM 和 VM’的数据将会一致。这时,上层管理软件会把 VM 关闭,并把 VM’的 vcpu 恢复运行状态,整个虚拟机的数据迁移就完成了。
切换阶段
Step.5 数据迁移完成后,VM 关闭,VM’作为它的一个完全拷贝,在 DestHost 上运行着,但网络还是不通的(如图 2 所示)。VM’通过 DestHost 的 vswitch 连接到物理机网卡,vswitch 相当于一个虚拟交换机,而 VM 从 SourceHost 迁移到 DestHost,在网络上相当于把网线从一个交换机拔下插到另一个交换机上,此时就需要一次 arp 广播,告知 VM 的 mac 地址已经变更到另外一台交换机的某个端口。
这就是迁移完成后的网络切换,由于切换时间很短,少于 tcp 的超时重传时间,因此对于原 VM 上跑着网络服务程序几乎是无感知的。此后(如图 6 所示)目标端 DestHost 虚拟机就具备和用户直接进行交互的能力,而源端 SourceHost 虚拟机此时就可以删除。
图 6 完成虚拟机迁移示意图
总结
通过以上迁移步骤,可以在 KVM 虚拟化平台上实现虚拟机的跨越迁移,进而方便实现云平台负载均衡与系统运维,并确保用户虚拟机性能的可靠性。同时,从用户角度来看,这个过程并不需要关心虚拟机在源端 SourceHost 还是目标端 DestHost,但可以持续与虚拟机进行交互,整个迁移过程对用户来说是透明的。
虽然,当前 KVM 虚拟化在线迁移能够满足大多数情况下的用户虚拟机迁移,但还存在以下问题:
在磁盘和内存负载高的情况下,存在迁移无法完成的情况;
跨机迁移存在网络中断时间长的问题;
跨存储类型的场景下如何进行迁移;
如何应用迁移进行虚拟机组件的更新。
后面的文章我们会更加深入介绍 UCloud 对各种在线迁移场景的优化和实践。
本文转载自公众号 UCloud 技术(ID:ucloud_tech)。
原文链接:
https://mp.weixin.qq.com/s/nwbVNpQD8yCkfpR96piPpw
活动推荐:
2023年9月3-5日,「QCon全球软件开发大会·北京站」 将在北京•富力万丽酒店举办。此次大会以「启航·AIGC软件工程变革」为主题,策划了大前端融合提效、大模型应用落地、面向 AI 的存储、AIGC 浪潮下的研发效能提升、LLMOps、异构算力、微服务架构治理、业务安全技术、构建未来软件的编程语言、FinOps 等近30个精彩专题。咨询购票可联系票务经理 18514549229(微信同手机号)。
评论