移动云操作系统改造技术实践分享,跨操作系统云主机迁移优化(一)

近年来,Linux 操作系统在技术、社区和商业化方案均取得了快速发展,移动云先后发布了新一代天元操作系统和易行迁移工具,保障了移动云全场景业务高效迁移。在移动云 CentOS 迁移实践过程中,跨操作系统虚机迁移是改造中的一个重要环节,现网环境错综复杂,如何保证客户业务在虚机迁移过程不中断,确保迁移后的虚机在 Linux 操作系统上平稳运行,在底层虚拟化侧面临诸多技术挑战。

关键挑战

虚拟化组件同源异构

新的虚拟化组件需要在多款 Linux 操作系统上稳定运行,在不同操作系统和 CPU 架构上共用同一份源码,因此首先需要解决同源异构难题。

OS 兼容适配

计算、存储、SDN 等核心业务需要在 OS 之上相互兼容,在新的平台上需要在中间层即虚拟化层解决一些业务兼容适配问题。

跨 OS 不停服热迁移

跨操作系统、跨虚拟化组件大版本的迁移,可能因虚机 cpu 能力、内存布局、设备结构体等差异,导致迁移失败影响业务连续性,这是虚机跨操作系统迁移过程中的一大难题。

虚拟化组件同源异构

同源异构可以屏蔽不同系统、不同架构的差异,收缩现网版本,减小代码维护的压力。实现"一份代码,一次编译,处处运行"。在同源异构改造过程中我们解决了诸多问题,如:不同系统、不同架构其编译安装依赖包会有差异,需要在 spec 文件中根据不同系统、架构指定相应的依赖。新旧虚拟化组件软件包安装时存在冲突,需利用 rpm 的 Obsoletes 机制删除对应安装包,实现组件的平滑升级。另外由于新旧虚拟化组件差异大,导致旧版补丁回合后函数调用失败,需要根据代码差异重新设计实现部分功能。

OS 兼容适配

为了保证虚机能在 OS 上平稳运行,需要解决一些计算、存储、SDN 同虚拟化组件在平台上适配存在的问题,并做一些优化。

Python2 版本的兼容

随着 Python2 的生命周期结束,libvirt-python 自 6.0.0 就停止了对 Python2 的支持,但由于部分产品改造周期长,需要暂时维持使用 Python2 环境作为过渡,虚拟化作为底层组件,需要构建一个基于 Python2 的 libvirt-python 组件包。我们从 Python3 和 Python2 间语法差异、接口改变、模块变化等方面入手,对适配 OS 上的 libvirt-python 代码做了修改,包括:

  • 针对数据类型、类的定义等语法差异上做了对应修改。
  • 针对异常捕获、输入输出、迭代器等 API 使用差异部分做了对应修改。
  • 针对 Python3 和 Python2 间名称变化或废弃的模块做了对应修改。

在修改了 50 多个文件,上千行代码后,最终得到了一个基于 Python2 的稳定可靠的 libvirt-python。

OVS-dpdk 与 QEMU 的适配

SDN 的稳定性和可靠性直接影响到用户虚机的网络服务质量,为了保证 SDN 能在新平台上平稳运行,我们积极推动各 SDN 厂商在 OS 上的适配工作,解决了多个适配问题。SDN 适配时发现当 QEMU 作为 server 时,重启 ovs,虚机可能会 crash。查看 QEMU 的 coredump 文件,定位到如下代码触发了 crash。当 QEMU 作为 server 端时,一旦 ovs 重启,按照上面代码逻辑 QEMU 会主动尝试进行 reconnect,过程中会改变网卡设备 tcp 状态字为 TCP_CHARDEV_STATE_DISCONNECTED,此时会造成处理逻辑 bug,使得 QEMU 发生 crash(实际上 QEMU 作为 server 端时,不应进行 reconnect 操作,而是由作为 client 端的 ovs 进行 reconnect)。具体触发 crash 的流程如下:解决方案是只有当 QEMU 作为 client,重启 ovs,QEMU 才做 reconnect,问题得到修复。除上述问题外,我们还解决了一些其他问题,包括 ovs 热升级后 windows 虚机网络不通、海光平台执行 testpmd 测试程序虚机卡住等多个问题。

卷迁移操作的效率优化

分布式存储为云平台提供基础存储服务,在使用中往往伴随着一些卷迁移和容量查询的操作,但这些操作实际执行效率并不高,需要做一些优化。在 QEMU 原生版本实现 Ceph 卷迁移功能时,迁移前将 bitmap 每位都置脏,首轮迁移时会将源盘所有数据迁往目的盘(未写入数据的部分以 0 写入),导致迁移数据量增多,时间变长。我们对 ceph 卷迁移做了优化,减少了首轮迁移的数据量,效率得到大幅提升(尤其是源盘空间较大数据量较少时),具体步骤:

  1. 修改 QEMU 组件的 rbd 驱动,增加获取后端集群 Ceph 卷已使用空间分布的接口。
  2. 迁移开始时,利用接口初始化卷迁移的 dirty bitmap。
  3. 迁移过程中,如果虚机新增 IO,将对应 dirty bitmap 置脏。不断迭代清理 dirty bitmap,只对有数据的存储块进行迁移拷贝,无数据的块直接跳过。
  4. 当 dirty bitmap 全部清理时卷热迁移完成。

此外还有一些其他优化:

  1. 优化 ceph 卷容量查询,调用新的接口,其查询效率提升 30%+。
  2. QEMU 支持 ceph 卷 snapshot 迁移功能,迁移后依然保有源卷的快照信息。

跨 OS 不停服热迁移

解决了同其他核心产品适配的各种问题后,我们工作重点转向了跨 OS 的迁移适配上来。我们与 openEuler 社区的 Virt SIG 成员进行了深度协同联创,解决了跨 OS 迁移需要考虑 Guest 的 CPU 能力、设备状态等多个方面的问题。

目的端主板类型不兼容迁移失败

从 BC-Linux7 系列系统往 BC-Linux For Euler 系列系统迁移时会有"unsupported machine type"的报错,对比两个操作系统 QEMU 组件支持的 machine type,发现 BC-Linux7 的虚拟化组件裁剪了 QEMU 社区原生的 Machine Type,完全自定义了私有的主板类型,无法正常热迁移到 openEuler 上。由于 machine type 在迁移时不能被改变,要想迁移成功,就必须在 BC-Linux For Euler 系统上的高版本 QEMU 兼容低版本的 machine type。为此,我们梳理低版本 QEMU 中每种 machine type 支持的设备,并在高版本 QEMU 上移植相应的 machine type,这样迁移时便不会出现主板类型不支持的问题。

设备结构体差异引起迁移失败

QEMU 使用 VMStateDescription(VMSD)数据结构来对设备状态进行描述和管理,迁移时 VMSD 的 fields 和 subsections 会被发送到目的端。要想虚机迁移成功,如果源端设备结构体字段多于目的端,则目的端 vmstate_load_state 加载设备状态时,需要将多出来的字段 disable 掉,反之则需将缺少的字段跳过加载。测试时我们发下虚机从 BC-Linux For Euler 系列系统往 BC-Linux7 系列系统回迁时,对端无法成功接收键盘的设备状态。对比键盘的 VMSD,高版 QEMU 增加了 kbd_extended_state 字段的发送,目的端因缺失该字段导致迁移失败。kbd_extended_state_needed 是判断是否将 kbd_extended_state 字段发送的函数(默认 True)。为了保证虚机不会因为 kbd_extended_state 而导致回迁失败,回迁时须将多出的 kbd_extended_state 字段不发送。此外我们还比较了其他设备,尤其是 virtio 和 vhost_user 设备的 VMSD 在高低 QEMU 版本间的差异,对有差异的地方做了修改。

cpu feature 不兼容热迁移失败

虚机 CPU 有 3 种模式:custom(指令集最少但热迁移兼容性最好)、host-passthrough(指令集最多但热迁移兼容性最差)和 host-model(介于两者之间),但虚机 cpu features 不仅和虚拟化配置有关,还与宿主机的 CPU 型号、操作系统内核等有关。即使是在 custom 或 host-model 模式下,我们也遇到一些因目的端缺失 cpu features 而导致的迁移失败的问题。

case1:目的端缺失 arch-facilities 特性

由于高版本 libvirt 将同一 cpu feature 名称由 arch-facilities 变为了 arch-capabilities,目的端不识别 arch-facilities,导致热迁移失败。需要在源端的 cpu_map.xml 中将其修改为 arch-capabilities 才能通过 cpu feature 兼容性检查。

case2:目的端缺失 spec_ctrl 特性

BC-Linux7 系列系统上使用的 3.10 内核需要使能 spec_ctrl 来避免"幽灵漏洞",但 BC-Linux For Euler 系列系统使用的 4.19 内核通过其他方式避免了该漏洞,关闭了 spec_ctrl,需要更新微码才能在目的端使能 spec_ctrl 特性。

case3:目的端缺失 hle/rtm 特性

配置 host-model 的模式虚机因目的端缺失 hle/rtm 特性导致热迁移失败。需要在目的节点的内核的启动参数增加"tsx=on"来使能相关指令集。

总结

我们做了虚拟化组件的同源异构、对 OS 兼容适配,并与 openEuler 社区进行深度联创,实现跨 OS 不停服热迁移优化,从原理和实践两个方面,保障了 CentOS 的迁移改造任务得以高效进行。然而移动云现网有海量的节点需要做迁移,这对迁移的效率与成功率有了更高的要求,在下期的分享中,我们将带来对热迁移性能提升优化做的技术分享,敬请期待!

相关推荐
爱瑞瑞1 小时前
🐧深入浅出的认识 Linux 指令
linux·shell
ajassi20001 小时前
开源 java android app 开发(十一)调试、发布
android·java·linux·开源
小李飞刀李寻欢1 小时前
使用kubeadm部署Kubernetes(k8s)集群的步骤
linux·服务器·ubuntu·kubernetes·k8s
运维成长记2 小时前
阿里云实践创建实例步骤
linux·运维·服务器·阿里云·云计算
THe CHallEnge of THe BrAve2 小时前
Linux检验库是否安装成功
linux·运维·服务器
why1512 小时前
6.12 操作系统面试题 进程管理
面试·操作系统
算家计算3 小时前
告别复杂文档解析噩梦!MonkeyOCR 本地部署教程:支持公式/表格多元素结构化
linux·人工智能·开源
曹勖之3 小时前
ROS2 工作空间中, CMakeLists.txt, setup.py和 package.xml的作用分别是?
xml·linux·服务器·ros2
企鹅侠客4 小时前
ttyd:安全地通过网络共享您的 Linux 终端
linux·运维·ttyd
饭碗、碗碗香5 小时前
【开发常用命令】:服务器与本地之间的数据传输
linux·运维·服务器·笔记·学习