购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

5.3 在OpenStack项目中开发PCI SR-IOV新功能实战

曾经听说,OpenStack的最初代码是运维人员写的,是运维人员在运营云基础设施时,发现有很多地方可以改进和脚本归纳,从而不得已将运维变成开发,就出现了早期的OpenStack。在OpenStack中,DevOps被体现得淋漓尽致。随着OpenStack子项目的增加,代码量也随之增加且复杂度升高,但是经过若干年的发展,OpenStack已有一套成熟、高效的体系来保证代码的质量与项目的稳步推进。

第一是编码规范。对于达到百万行代码量级的 OpenStack 来说,它有自己的一套编码规范来约束及预防众多开发者将自己的创造力用于构建一个蓬勃发展的开源云项目。

目前,与OpenStack息息相关的Python代码静态检查工具主要有Pylint、Pep8、Pyflakes、Flake8等。其中,Flake8是Pyflakes、Pep8及NedBatchelder's McCabe script(关注 Python 代码复杂度的静态分析)三个工具的集大成者,综合封装了三者的功能,在简化操作的同时还提供了扩展开发接口。OpenStack使用的代码静态检查工具正是Flake8,并实现了通过一组扩展的Flake8插件来满足OpenStack的特殊需求,这组插件被单独作为一个子项目存在,就是Hacking。Hacking在注释、异常、文档、兼容性等编码规范方面,实现了近30个Flake8插件。

第二是代码评审。对于 OpenStack 来说,为了保证代码评审的有效进行,首先需要做的是把分散在全球各地的 OpenStack 开发者联合起来,借用一个联结的平台Gerrit,让他们发表自己的意见和看法。OpenStack也将 Gerrit 引入自己的代码管理中,且使用Jenkins完成自动化测试。

代码提交审核流程是,首先在本地代码仓库中做出自己的修改,然后通过 git命令(或git-review封装)将自己的代码push到Gerrit下的Git版本库中。Jenkins会对提交的代码进行自动化测试并给出反馈,其他开发者也能使用 Gerrit 对提交的代码给出他们的注释与反馈,其中,项目的Core Developer反馈权重最高(+2),如果Patch能够得到两个“+2”,则表明该Patch将会被合并到OpenStack的源码树中。

由于所有注释、质疑、反馈、变更等代码评审的工作都通过Web界面来完成,因此Web服务器是Gerrit的重要组件,Gerrit通过Web服务器实现对整个评审工作流程的控制。

第三是单元测试。概括来说,OpenStack的单元测试追求的是速度、隔离及可移植性。对于速度,要求测试代码不能与数据库和文件系统交互,也不能进行网络通信。另外,单元测试的颗粒度要足够小,一旦测试失败,确保能够很容易迅速地找到问题的根源。可移植性是指测试代码不依赖于特定的硬件资源,能够让开发者在任意平台上运行。

单元测试的代码位于每个项目源码树的〈project〉/tests/目录下,遵循oslo.test库提供的基础框架规范。通常单元测试的代码需要专注在对核心实现逻辑的测试上,如果需要测试的代码引入了其他依赖,比如依赖某个特定的环境,那么我们在编写单元测试代码的过程中就必须花费相当一部分时间来隔离这些依赖,否则即使测试失败,也很难定位问题。

SUT(System Under Test,被测试系统)完成隔离的基本原则是引入测试替身,用测试替身来替代测试中的每一个依赖。测试替身有多种类型,如Mock对象、Fake对象等,它们都可以作为数据库、I/O(Input/Output,输入/输出)、网络等对象的替身,并将相应的操作隔离。在测试运行过程中,当执行到这些操作时,不会深入方法内部执行,而是直接返回我们假设的值。

执行单元测试的途径有两种:Tox和项目源码树根目录下的run_tests.sh脚本,通常使用的是Tox。Tox是一个标准的virtualenv管理器和命令行测试工具,可以用于检查软件包能否在不同的Python版本或解释器下正常安装,以及能否在不同的环境中运行测试代码,可作为持续集成服务器的前端,大大减少测试时间。

第四是持续集成工具Jenkins。通俗地说,持续集成需要对每一次提交的代码进行从代码集成到打包发布的完整流程,以判断提交的代码对整个流程带来的影响。而这个过程中所使用的手法严重依赖于团队成员的多少、目标平台、配置等因素。例如,只有一个人面向一个平台,那么当每次有一个 Commit 时,通过手工测试就能基本知道结果,完全不需要其他更为复杂的工具与手段。

但是,对于 OpenStack 这样的项目,显然没有这么简单,它涉及一个由版本控制软件维护的代码仓库、自动的构建过程,以及一个持续集成服务器,其中自动构建过程包括自动编译、测试、部署等。OpenStack使用Jenkins搭建持续集成服务器。对于一般的小研发团队,通常可能会先提交代码再运行CI,而OpenStack则不同,它通过Gerrit对每次提交的内容进行Review,这时,Jenkins会执行整个CI的过程,通过标记“+1”,否则标记“-1”。

Jenkins需要依托大量的单元测试及集成测试代码,单元测试的代码位于各个项目的源码树中,而OpenStack的集成测试则使用Tempest作为框架。

在我们提交代码到Gerrit后,Jenkins会执行包括集成测试在内的各项测试,但有时候仍然需要我们在本地执行集成测试。比如,针对新功能Patch引发的Tempest使某些测试用例执行失败,我们需要修改 Tempest 代码(通常的做法是注释掉这个失败的测试用例,并将修改提交给Tempest,等Tempest接受后,原来的Patch集成测试会成功通过,等到它们被相应的项目接受后再修改Tempest代码并提交)。

最后,在Jenkins系统中,还存在第三方CI系统。Jenkins是OpenStack的官方CI系统,每一个Patch在最终合并前都必须通过Jenkins的测试。除此之外,还有第三方提供的许多自动化测试系统可用于验证和测试特定的Patch,这些由第三方提供的自动化测试系统被统称为第三方CI系统。第三方CI系统也是通过Gerrit系统接入OpenStack开发流程的。每提交一个Patch,Gerrit就会发布一个事件,Jenkins就会通过监听Gerrit事件启动Patch测试或者Gate(将代码合入主干)流程。第三方CI系统一般都只关注某个官方项目,测试专门的代码。

第三方CI系统基本上都基于成熟的Jenkins测试系统,最基本的配置包括一个Jenkins Master和几个测试端,以及一个用于发布测试日志开放的Web/FTP服务器,测试日志至少要保留几个月。OpenStack 基础设施团队对Jenkins和Web Server的设置都有具体的规定和指导。Jenkins官方提供了Gerrit trigger插件,第三方CI系统安装这个插件后,可以通过它连接到OpenStack Jenkins上接收官方Gerrit事件,并在Gerrit trigger插件内过滤出感兴趣的变化,触发Jenkins具体的测试。在测试完成后,需要将测试日志发布到公开的Log Server上,并根据测试将结果反馈给Gerrit,同时将日志链接一并发回给Gerrit。之后开发者就能看到测试结果并访问测试日志了。

根据OpenStack的官方要求,第三方CI系统都需要申请一个专用的OpenStack账号,用于接入官方CI系统。申请人需要确保第三方CI系统能反馈给社区有意义的结果,并保证7×24小时运行,对出现的问题要及时处理,确保OpenStack基础设施团队可以联系到维护人员。

下面以PCI SR-IOV功能为例,简单介绍其在OpenStack软件中的开发过程。

传统的 I/O 虚拟化方法主要有“设备模拟”和“类虚拟化”两种。前者通用性强,但性能不理想;后者性能不错,却缺乏通用性。如果要兼顾通用性和高性能,最好的方法就是让虚拟机直接使用真实的硬件设备。这样,虚拟机的 I/O 操作路径几乎和没有虚拟机时相同,从而获得与没有虚拟机环境几乎一样的性能。因为这些是真实存在的硬件设备,虚拟机可以使用自带的驱动程序发现并使用它们,通用性的问题也得以解决。但是,虚拟机直接操作硬件设备需要解决两个问题,即如何让虚拟机直接访问硬件设备真实的 I/O 空间,以及在硬件设备进行 DMA(Direct Memory Access,直接存储器访问)操作时如何访问到虚拟机的内存空间。

Intel的VTx技术已经能够解决第一个问题,允许虚拟机直接访问物理的I/O空间。Intel的VTd技术可用于解决第二个问题,它提供了DMA重映射技术,以帮助虚拟机管理软件的实现者达到目标。在网卡虚拟化中,VTd 技术可以直接将一个网卡分配给虚拟机使用,从而达到和物理机一样的性能,但是它的可扩展性比较差,因为一个物理网卡只能分配给一个虚拟机,而且服务器能够支持的最多PCI设备数是有限的,远远不能满足越来越多的虚拟机数量。

因此,SR-IOV被引入来解决这个问题。SR-IOV是PCIe(PCI express)规范的一个扩展,定义了可以共享的新型设备。它允许PCIe设备(通常是网卡)为每个与其连接的虚拟机复制一份资源(如内存空间、中断和DMA数据流),使数据处理可以不再依赖虚拟机管理软件。SR-IOV功能对云计算中的网络工作负载十分有效,它除了可以支持将物理网卡虚拟成多个虚拟设备,满足越来越多虚拟机的要求,也可以利用硬件设备加速虚拟网卡的网络处理,大大提高工作负载的网络性能,这在由运营商主导的网络功能虚拟化(Network Function Virtualization,NFV)场景中非常有用。

从技术上讲,SR-IOV是一种硬件虚拟化技术,允许多个虚拟机共享一块物理网络适配器(即网卡),而且每个虚拟机可以获得自己独立的虚拟网络适配器。

在OpenStack中,PCI SR-IOV可以帮助用户提高虚拟机的网络性能和吞吐量,降低网络延迟。诚然,由于具体的性能对比数据会受到多种因素的影响,如硬件配置、网络负载、应用负载等,因此不同的场景下性能对比数据可能会有所不同,但通过下面简单的数据对比,可以看到PCI SR-IOV的优势。例如,传统虚拟化技术中使用的虚拟交换机可以实现每秒约250 000个数据包的处理能力;而使用 PCI SR-IOV可以实现每秒约4 000 000个数据包的处理能力,性能提升达到16倍。在基于OpenStack的云环境中,使用PCI SR-IOV可以将虚拟机的网络吞吐量提高到10 Gbps 以上,而传统的虚拟化技术则只能实现约 1 Gbps 的网络吞吐量。另外,PCI SR-IOV还可以减少虚拟机对物理主机CPU的占用,从而降低虚拟机的CPU消耗和响应延迟。

该功能涉及设备资源管理和虚拟网卡,我们需要对OpenStack的Nova和Neutron进行相应的代码修改,如图5-1所示。

其中,系统由Nova负责,虚拟网络端由Neutron负责。用户通过Nova CLI发起启动虚拟机VM(Virtual Machine)的请求,在该请求里用户标注需分配SR-IOV VF(Virtual Function)网卡。Nova调度器中含有专门的PCI调度器,负责查询后台数据库发现的 SR-IOV 资源和具有该资源的物理主机,并与用户需求匹配。在找到对应物理主机和 SR-IOV 资源之后,使用哪种网络虚拟化技术及如何分配给VM,由Neutron负责提供信息。在Nova负责给VM分配和设置SR-IOV VF之后,由PCI跟踪器记录状态和管理设备资源的使用信息。

图5-1 OpenStack中PCI SR-IOV的实现

SR-IOV在OpenStack中的工作流程是这样的。首先,在物理主机上配置SR-IOV物理网络适配器,并将其划分为多个VF;接下来,在节点上安装和配置SR-IOV驱动程序,以支持VF的分配和管理。在Nova中,用户可以通过配置Flavor和Image等参数来指定虚拟机所需的VF数量和类型。而Nova分配VF,首先要发现系统中可用的PCI信息,包括VF,然后给VM调度分配合适的VF,最后将这些VF分配给虚拟机。当Nova启动VM时,会根据与VM关联的网络或者Neutron端口信息通过Neutron查询端口类型,如果是Macvtap或者Direct,就意味着需要给VM分配一个VF。这个过程有一个天然的限制条件,就是VF对应的PF必须接入Neutron虚拟网络对应的物理网络中,这需要Neutron和Nova的配置互相协调。一旦获得了这些信息,在调度VM之前Nova就拥有了分配和配置VF接口的所有信息,Nova调度器就可以根据这些信息寻找合适的物理主机,并在启动VM时通知虚拟机管理软件配置VF给VM。一旦VF被分配给虚拟机,Neutron就会为每个VF创建一个虚拟网络适配器,并为其分配IP地址等网络参数。用户可以通过配置Neutron网络和子网等参数来控制VF的网络连接方式和流量管理。

由于涉及Nova和Neutron两个项目的代码修改,因此还需要专门设置一套第三方CI/CD系统,以确保新的代码修改不会对PCI SR-IOV功能产生破坏。当新的代码被提交到OpenStack上时,Jenkins会触发CI/CD系统运行,并向其他子系统发送事件。PCI SR-IOV子系统(Intel PCI CI)也会收到该事件,从而触发PCI SR-IOV的CI/CD子系统运行,并将运行一切正常的结果汇报给Jenkins,或报错以引起新代码作者的注意。

Intel PCI第三方CI系统也是通过Gerrit系统接入OpenStack开发流程的。Intel PCI Test只接受Nova Patch Set Create事件,启动针对PCI子系统的测试,并将测试结果通过Gerrit反馈给 OpenStack社区,在该Patch相应Gerrit评审页面的Reviewer一栏能看到Intel PCI Test的测试结果,如图5-2所示。

图5-2 Intel PCI Test界面的测试结果

第三方CI系统的基本架构,如图5-3所示。

图5-3 第三方CI系统的基本架构

OpenStack官方对第三方CI系统,包括Intel PCI CI,最重要的要求如下。

(1)及时处理问题,更新CI状态。

(2)积极参与基础设施团队的IRC会议。

(3)及时处理CI出现的各种问题。

许多企业和组织都在使用OpenStack的PCI SR-IOV功能。例如,AT&T、华为、Rackspace等均通过使用OpenStack和PCI SR-IOV来提供高性能、低延迟的云计算服务,以支持其业务和网络服务。SR-IOV在OpenStack中的应用可以为用户提供更高的网络性能、更低的网络延迟、更好的网络隔离、更灵活的网络配置等,具体如下。

● 更高的网络性能:使用PCI SR-IOV技术可以让虚拟机获得更高的网络性能,因为每个虚拟机都可以独立访问物理网络适配器,避免了传统的虚拟化技术中存在的虚拟交换机等网络设备的性能瓶颈。

● 更低的网络延迟:由于PCI SR-IOV可以避免虚拟交换机等网络设备的性能瓶颈,因此可以降低虚拟机访问网络的延迟,提高应用程序的响应速度。

● 更好的网络隔离:使用PCI SR-IOV可以为每个虚拟机分配独立的虚拟网络适配器,从而实现更好的网络隔离,保障虚拟机之间的安全性和隐私性。

● 更灵活的网络配置:使用PCI SR-IOV可以为虚拟机提供更灵活的网络配置选项,例如可以通过配置不同的虚拟网卡来连接不同的网络,或者使用不同的网络传输协议等。 k7h5q8usFwuRAxyzWq4f5t9RnBMdXJCJ77ltvuizfcyFaagqoTmcsyzWx35t/dLp

点击中间区域
呼出菜单
上一章
目录
下一章
×