写点什么

苏宁私有云 SR-IOV 虚拟网络性能优化

  • 2018-11-09
  • 本文字数:4122 字

    阅读完需:约 14 分钟

苏宁私有云SR-IOV虚拟网络性能优化

1. SR-IOV 介绍

SR-IOV 技术是一种基于硬件的虚拟化解决方案,可提高网络性能和可伸缩性。SR-IOV 标准允许在虚拟机之间高效共享 PCIe(Peripheral Component Interconnect Express,快速外设组件互连)设备,并且它是在硬件中实现的,可以获得能够与本机性能媲美的 I/O 性能。SR-IOV 规范定义了新的标准,根据该标准,创建的新设备可允许将虚拟机直接连接到 I/O 设备。


单个 I/O 资源可由许多虚拟机共享。共享的设备将提供专用的资源,并且还使用共享的通用资源。这样,每个虚拟机都可访问唯一的资源。因此,启用了 SR-IOV 并且具有适当的硬件和 OS 支持的 PCIe 设备(例如以太网端口)可以显示为多个单独的物理设备,每个都具有自己的 PCIe 配置空间。


下图展示了针对 PCIe 硬件的 SR-IOV 技术体系示意图。



图 1 SR-IOV 技术体系架构


支持 SR-IOV 的网卡主要功能模块分为:


  • 物理功能 (Physical Function, PF)

  • 支持 SR-IOV 的管理。可以创建 VF,对于网卡,理论上可以创建 256 个 VF。一般情况下, 千兆网卡能支持达 7 个 VF, 万兆网卡能支持达 63 个 VF。

  • 虚拟功能 (Virtual Function, VF)

  • VF 可以理解为一个虚拟网卡,拥有独立内存空间、中断和 Direct Memory Access (DMA)流。VF 是 PF 虚拟出的一个实例,以一个独立的网卡形式展现。VF 是一种轻量级 PCIe 功能,可以与 PF 以及其创建的所有 VF 共享一个或多个物理资源。

  • 交换功能(Layer 2 Classifier/Sorter switch)

  • 这个交换机其实是物理网卡内置的。流量进入物理网卡后,经过这个交换机然后分发到不同的 VF 上。


使用 SR-IOV 技术的主要优点是:


  • 提高虚拟机包转发效率

  • 减少报文在主机内部的传输延时以及延时抖动


由于绕过了主机的协议栈以及 VMM(Virtual Machine Manager),减少了主机在网络报文收发中的资源消耗


同时,由于 SR-IOV 技术使虚拟机通过 PCI-passthrough 的方式直接使用 VF,绕过了主机的内核协议栈以及 VMM,故存在以下局限:


  • Host 无法监控 VF 的状态

  • 安全组无法应用

  • 虚拟机热迁移无法实现,迁移的支持能力不够灵活

  • 对 HA 的支持不太高

  • sriov 不支持 vxlan

2. SR-IOV 性能

本测试对比测试万兆网络中 SRIOV 虚拟机和 OVS 虚拟机在网络负载较高情况下的虚拟网络表现,总结分析,同时为以后 SRIOV 虚拟机和其它类型的虚拟机做对比给出参考。

2.1 测试性能指标

主要对以下几个网络性能指标进行测试:


  1. 负载(OfferedLoad):网络流量负荷百分比,当前流量占端口速率的比例(百分比)

  2. 包速(Frame Per-second):数据包每秒的收/发个数

  3. 平均时延(Average Latency):数据包传输的平均延迟(毫秒,ms)

2.2 测试拓扑图

SR-IOV 测试环境网络拓扑:



Openvswitch 测试环境网络拓扑:


2.3 测试结果









可以看出 SR-IOV 各方面性能都要优于 Openvswitch。

3. SR-IOV 高可用方案

因为采用 SR-IOV,虚拟机流量不经过宿主机操作系统,所以不能在宿主机操作系统层面做高可用,必须在虚拟机内部做高可用。SR-IOV 高可用方案如下图:



(1) vm 挂载不同 pf 的 vf,在 vm 内部配置网卡 bond,可以根据需求选择 balance-rr、active-backup 或者 balance-xor 策略。


(2) vm 挂载的 vf 的 mac 地址必须设置成一样。这样在虚拟机配置网卡 bond 的情况下,仍然可以使用 vf 的 mac spoofing check 功能。


(3) pf 配置 lacp bond,交换机侧配置动态链路聚合,实现聚合带宽的动态调整。

4. OpenStack 创建 SR-IOV 虚拟机过程

Openstack 默认不支持 SR-IOV 的高可用,neutron 中一个逻辑的 port 对应一个 vf 口。所以我们需要对 openstack 进行改造,总体思路是,通过在调用 Neutron Create Port 的 api 时候,对 Port 打上 bond 标签,Nova 在创建虚机的时候通过读取到对应 port 的 bond 标签,为该 port 分配两个 VF 口,并且在分配 VF 口的 pci 资源的时候,默认的把两个 vf 分配在不同的 pf 上。对应在 port 的 binding:profile 上需要展示使用的两个 vf 口的 pci 信息。

4.1 调用 neutron api 创建 sriov 的 port

调用 neutron 接口创建 sriov port,在 profile 中对 Port 打上 bond 标签,这里无需赘述。命令如下:


neutron port-create --binding:vnic_type=direct --binding:profile type=dict bond=true
复制代码

4.2 调用 nova api 创建虚拟机

入口为 nova/api/openstack/compute/servers 的 create 方法,检查一系列参数和 policy,然后调用 compute_api 的 create 方法:



compute_api 是 nova/compute/api.py 模块,在该文件中找到 create 方法,该方法接着调用_create_instance 方法,在_create_instance 方法中调用_validate_and_build_base_options 方法对所有的输入参数和策略做检查,并且封装 pci 请求。封装 pci 请求的方法是 nova/network/neutronv2/api.py 的 create_pci_requests_for_sriov_ports 方法,该方法会先调用 neutron api 获取 port 的 vnic_type、phynet_name、bond 属性,根据 bond 属性确定 vf 的数量(bond 为 true,vf 的数量是 2,否则 vf 数量是 1)。



返回到 nova/compute/api.py 的_create_instance 方法,该方法接着调用 compute_task_api 的 schedule_and_build_instances 方法:



compute_task_api 是 nova/conductor/api.py 模块。这里没有执行什么操作,直接调用了 conductor_compute_rpcapi 的 schedule_and_build_instances 方法:



该方法远程过程调用 api,即 nova/conductor/rpcapi.py 模块,该方法会对版本进行检查,然后调用 RPC:



cast 表示异步调用,schedule_and_build_instances 是远程调用的方法,kw 是传递的参数。现在 nova-api 任务完成,此时会响应用户请求,虚拟机状态为 building。

4.3 nova conductor

nova-api 向 nova-conductor 发起 RPC 调用,进程跳到 nova-conductor 服务,入口为 nova/conductor/manager.py 的 schedule_and_build_instances 方法,该方法首先调用了_schedule_instances 方法,在_schedule_instances 方法中调用了 scheduler_client 的 select_destinations 方法:



这个方法最终调用到 nova/scheduler/client/query.py 下的 select_destinations 方法,执行 RPC 的调用。



RPC 封装同样是在 scheduler 的 rpcapi 中实现。该方法 RPC 调用代码如下:



Call 表示同步调用,此时 nova-conductor 并不会退出,而是堵塞等待直到 nova-scheduler 返回。因此当前状态为 nova-conductor 为 blocked 状态,等待 nova-scheduler 返回,nova-scheduler 接管任务。

4.4 nova scheduler

nova scheduler 中入口为 nova/scheduler/manager.py 模块的 select_destinations 方法,该方法会调用 driver 的 select_destinations 方法,这里的 driver 是调度算法实现,通过 filters 过滤掉不满足条件的计算节点,剩下的节点通过 weigh 方法计算权值,最后选择权值高的作为候选计算节点返回。最后 nova-scheduler 返回调度结果的 hosts 集合,任务结束,返回到 nova-conductor 服务。


nova/scheduler/manager.py



nova/scheduler/driver.py



nova/scheduler/filter_scheduler.py


4.5 nova condutor

回到 nova-conductor 的 schedule_and_build_instances 方法,nova-conductor 等待 nova-scheduler 返回后,拿到调度的计算节点列表。因为可能同时启动多个虚拟机,因此循环调用了 compute_rpcapi 的 build_and_run_instance 方法。



Compute_rpcpai 位于 nova/compute/rpcapi 模块,该方法向 nova-compute 发起 RPC 请求:



发起的是异步 RPC,因此 nova-conductor 任务结束,进入 nova-compute 服务。

4.6 nova compute

入口是 nova/compute/manager.py 的 build_and_run_instance 方法,该方法会调用_do_build_and_run_instance 方法,该方法会更新虚拟机状态,然后调用_build_and_run_instance 方法,该方法会预先声明占用计算节点的资源。



其中在 instance_claim 方法中会处理 pci 的请求,instance_claim→claim_instance(nova/pci/manager.py)→_claim_instance →consume_requests(nova/pci/stats.py),在 nova/pci/stats.py 中会根据不同的网卡把 pci 资源分为不同的 pool。



在 consume_requests 方法中会具体分配 pci 资源也就是 vf,



先根据剩余可用的 vf 的数量将 pool 进行排序,如果 port 的 bond 属性为 false,则 count 数量为 1,则从可用 vf 数量最多的 pool 中分配一个 vf,这样使不同网卡的负载尽量均衡。如果 port 的 bond 属性为 true,则 count 数量为 2,则从两个 pool 中各分配一个 vf,达到高可用的目的。


回到 nova/compute/manager.py 的 build_and_run_instance 方法,这个方法接下来会调用 spawn_n 方法,开始真正创建虚拟机。这里不同的虚拟机技术对应不同的 driver,其中 libvrit 的 driver 对应 nova/virt/libvirt/driver.py。从 spawn 方法开始,会先获取 instance 的磁盘、镜像、网络等信息,然后生成 instance 的 xml 文件。



在_get_guest_xml 方法中会调用_get_guest_config 方法,其中 sriov 网卡的部分如下:



这里如果 port 的 bond 为 true,则会将两块网卡的信息写入 xml 文件中。


回到 spawn 方法,接下来会调用_create_domain_and_network 方法,该方法会调用 plug_vifs 方法创建 qbr 和 qvo,接着创建虚拟机,虚拟机状态为 pause。然后等待 neutron-server 的消息,如果等到消息后将虚拟机状态改为 running,否则超时没有等到,则将虚拟机销毁。


4.7 neutron sriov agent

在 neutron/plugins/ml2/drivers/mech_sriov/agent/sriov_nic_agent.py 中 daemon_loop 方法会定时检测 vf 的状态变化,如果有 vf 发生变化,进入 process_network_devices 方法,在该方法中,会根据 vf 的状态是添加更改删除做不同的处理。



其中在 treat_devices_added_updated 方法中,如果 port 的 bond 为 true,需要更新两个 vf 的状态:



然后会调用 rpc,通知 neutron-server 更新状态。



这里是同步调用,neutron-server 接收到消息后,会向 nova 发送更新 port 的消息,接着 nova compute 会 resume 状态是 pause 的虚拟机。


至此,带有 sriov 高可用网卡的虚拟机创建完成。


作者


李伟杰,苏宁云网络架构师,长期从事云计算的研发工作,在云计算虚拟网络和 SDN 网络方面有专业的研究,现在负责苏宁云虚拟网络产品设计及研发。


陈玮,苏宁云高级研发工程师,有多年云计算网络研发经验,现在负责苏宁云网络产品的研发。


2018-11-09 18:002666

评论

发布
暂无评论
发现更多内容

物联网场景中灵活实施对设备的控制管理

亚马逊云科技 (Amazon Web Services)

黑客技能:xss攻击入门

喀拉峻

黑客 网络安全 XSS 渗透测试

KubeMeet 直播 | 现场直击大规模集群、混合环境下的云原生应用交付难题

阿里巴巴云原生

阿里云 云原生 KubeMeet 交付 直播活动

13 Prometheus之云时代的监控目标及挑战

穿过生命散发芬芳

运维 监控 Prometheus 1月月更

转换匹配患者记录,看Amazon Lake Formation FindMatches显神通!

亚马逊云科技 (Amazon Web Services)

analytics

【架构实战营】模块九作业

Geek_99eefd

架构实战营 「架构实战营」

腾讯云原生实时数仓建设实践

腾讯云大数据

flink window 流计算 Oceanus

如何使团队的git log更优雅

阿呆

#GitLab

Flink 实践教程-进阶(6):CEP 复杂事件处理

腾讯云大数据

流计算 Oceanus

模块9作业

Asha

VuePress 博客优化之开启 Gzip 压缩

冴羽

nginx 前端 后端 博客 vuepress

深入理解MySQL的binlog

JavaEdge

1月月更

2021年12月券商App行情刷新及交易体验评测报告

博睿数据

失去了SDK,云计算将会怎样?

亚马逊云科技 (Amazon Web Services)

计算

【网络安全】手把手给大家演练红队渗透项目

H

网络安全 渗透测试·

混沌工程之ChaosBlade-Operator 使用之模拟 POD 丢包场景

zuozewei

性能测试 混沌工程 ChaosBlade 1月月更

呼叫医生云! Amazon HealthLake 现已正式上线

亚马逊云科技 (Amazon Web Services)

AI ML

腾讯云 AI 视觉产品基于流计算 Oceanus(Flink)的计费数据去重尝试

腾讯云大数据

AI flink window

首届LoongArch生态创新大会成功召开,筑巢引凤共建信息产业命运共同体

OpenAnolis小助手

开源 芯片 白皮书

边缘网络 eBPF 超能力:eBPF map 原理与性能解析

火山引擎边缘云

Mycat 作为代理服务端的小知识点

CRMEB

代码审计思路之PHP代码审计

网络安全学海

网络安全 信息安全 渗透测试 安全漏洞 代码审计

雷霆传奇H5光柱版游戏详细图文架设教程

echeverra

游戏

聊聊Netty那些事儿之Reactor在Netty中的实现(创建篇)

bin的技术小屋

网络编程 socket nio netty java 编程

小白都能吃透Java IOl流,最骚最全笔记,没有之一!1️⃣

XiaoLin_Java

Java io 基础 1月月更

百度APP浏览内核资源加载优化实践 -- ResourceScheduler 调优机制

百度开发者中心

百度app

圆桌对话:云时代下,企业运维面临的挑战与机遇

阿里云弹性计算

运维峰会 圆桌对话

吐槽一下网站

你?

工业生产中的“主动刹车”,是怎么实现的?

脑极体

苏宁私有云SR-IOV虚拟网络性能优化_服务革新_李伟杰_InfoQ精选文章