虚拟网络演进之路

这篇具有很好参考价值的文章主要介绍了虚拟网络演进之路。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本篇文章将带领大家了解以下网络设备虚拟化的演进之路,以及网络设备虚拟化发展的原因。本文是从全虚拟化->virtio->vhost->vfio->vdpa->vduse演进详细分析一下网络虚拟化的干货。

序言

设备虚拟化技术,云计算领域的核心之一。虚拟机里面的形形色色的设备,比如:网卡,磁盘,键盘,鼠标等,都是利用这项技术实现的,本文将从linux网络设备虚拟化的演进角度来看看,这发展的轨迹,网络虚拟化大体上分为三类,全虚拟化,半虚拟化,IO透传。全虚拟化场景下虚拟机操作系统不感知自己是虚拟机,半虚拟化虚拟机能感知自己是虚拟机

虚拟网络演进之路

PART 01 【全虚拟化】

Trap-and-emulate,

在最早期阶段,设备虚拟化常常和机器模拟器技术,比如:QEMU,绑定在一起。在最开始时候,可以利用QEMU模拟真实的网络设备,模拟设备上的所有寄存器布局,操作。当 QEMU 虚拟机里面设备驱动需要访问该虚拟设备的寄存器时,宿主机截获客户机对I/O设备的访问请求,这条访问指令会被 trap 到 QEMU,由 QEMU 来进行处理,然后通过软件模拟真实的硬件。这种方式对客户机而言非常透明,无需考虑底层硬件的情况,不需要修改操作系统。一切都是这么的完美。

下图为qemu模拟的指令

虚拟网络演进之路

PART 02  【Virtio】

通过上述这种 trap-and-emulate 的全虚拟化的方式来模拟设备,虽然不需要对真实设备驱动进行变更,但是设备访问过程中,对所有模拟I/O的设备访问都会造成VM-exit,这对虚拟机的使用造成了很大的性能影响。因此,virtio 这类半虚拟化技术应运而生。

相较于I/O全虚拟化的这种方式,Virtio 不再拘泥于依赖已有的设备驱动,而是定义了一套全新的专用于虚拟设备的驱动框架。设备驱动清楚自己是在操作虚拟设备,因此,在真正的I/O路径上规避了大量可能导致vm-exit的 mmio/pio 操作,从而提高了性能。虚机里面的 Virtio 后端驱动和 QEMU 模拟的 Virtio 设备的前端驱动进行数据交互,本质上是一套基于共享内存 + 环形队列的通信机制。核心数据结构(split virtqueue)包括:两个 ringbuffer (avail ring, used ring) 和一个 descriptor table。工作机制类似 DMA,虚机内 virtio 驱动首先会将一个需要传输的buffer 的地址、长度组成一个个描述符写入到 descriptor table 中,然后将这些描述符对应的 descriptor table 上的 index 写入到 avail ring 中,并通过 eventfd 机制通知到宿主机上的 virtio backend。由于这些 ringbuffer、descriptor table 以及 buffer 都在共享内存中(虚机本质上是一个用户态进程,因此虚机内存是由用户态申请和分配,并可以 share 给其他进程,如:SPDK,DPDK-OVS 等),因此,Virtio Backend 可以直接访问并获取到 buffer 的地址、长度,进而直接存取这些buffer。当处理完请求之后,Virtio Backend 将数据填充到相应的 buffer,并将对应的 descriptor table index 写入 used ring 中,并通过 eventfd 机制注入中断通知虚机内 virtio 驱动。

虚拟网络演进之路

我们结合qemu场景来分析,virtio backend后端驱动的最基本要素是虚拟队列机制、消息通知机制、中断机制。虚拟队列机制连接着客户机和宿主机的数据交互。消息通知机制主要用于从客户机到宿主机的消息通知。中断机制主要用于从宿主机到客户机的中断请求和处理。

虚拟网络演进之路

虚拟网络演进之路

上图是virtio-net后端模块进行报文处理的系统架构图。其中KVM负责为程序提供虚拟化硬件的内核模块,qemu利用KVM来模拟整个系统的运行环境,tap是内核中的虚拟以太网设备。当客户机发送报文时候,它会利用消息通知机制通知KVM,并推出到用户空间qemu进程,然后由qemu开始对tap设备进行读写。tap->qemu->guest。

从上述virtio技术提出以后,上述模型存在问题如下:

(1)宿主机、客户机、qemu之间的上下文频繁切换带来了多次数据拷贝和cpu特权级的切换,导致了virtio-net性能不如人意。

(2)消息通知机制是当报文到达tap设备时候,内核发出并送到qemu的通知消息,然后qemu利用IOCTL向KVM请求中断,KVM发送中断到客户机,这样的路径带来了不必要的开销。

PART 03 【Vhost-net】

为了对上述报文收发性能瓶颈进行优化,通过卸载virtuo-net模块在报文收发处理上的工作,使得qemu从virtio-net的虚拟队列工作中解放出来,减少上下文切换和数据包拷贝,进而提高报文收发性能,并且宿主机上的vhost-net模块还需要承担报文到达和发送时候的消息通知以及中断的工作,这样 virtio 通信机制从原本的 QEMU 用户态 I/O 线程和虚机驱动(QEMU 用户态 vcpu 线程)通信直接变成了 vhost 内核 I/O 线程和虚机驱动(QEMU 用户态 vcpu 线程)通信。vhost 内核 I/O 线程拿到数据包之后,直接走内核协议栈和网卡驱动进行处理,从而优化掉了 QEMU 到内核态的额外开销。

虚拟网络演进之路

虚拟网络演进之路

虚拟网络演进之路

上图展现了加入linux内核vhost-net模块后virtio-net模块进行报文处理的系统架构图。报文接收仍然包括数据通路和消息通知路径两个方面:

(1)数据通路是从tap设备接收数据报文,通过vhost-net模块把该数据报文,通过vhost-net模块把报文拷贝到虚拟队列中的数据区,从而使得客户机接收报文。

(2)消息通路是当报文从tap设备到达vhost-net时候,通过kvm模块向虚拟机发送中断,通知客户机接收报文。

PART 04【 Vhost-user】

上述vhost-net模块需要在内核态完成报文拷贝和消息处理,这样会给报文处理带来一定的性能损失。因此用户态vhost应运而生。由于 QEMU 和 vhost 的线程模型对 I/O 性能的优化并不友好,而且由每个虚机单独分出线程来处理 I/O 这种方式从系统全局角度来看可能也并不是最优的,因此,vhost-user 提出了一种新的方式,即将 virtio 设备的数据面 offload 到另一个专用进程来处理。这样,由于是专用进程,线程模型不再受传统 QEMU 和 vhost 线程模型制约,可以任意优化,同时,还可以以 1:M 的方式同时处理多个虚机的 I/O 请求,而且相较于 vhost 这种内核线程方式,用户进程在运维方面更加具备灵活性,vhost-user 框架在提出之初,就受到广泛关注,并引申出了 SPDK 和 OVS-DPDK 这类以 polling + 用户态驱动为核心的新的虚机 I/O 服务模型。由于vhost采用内存共享技术,通过共享的虚拟队列完成数据报文的传输和控制,大大降低了vhost和virtio-net之间的数据传输成本。

vhost其实现原理与linux内核态vhost-net类似,它实现用户态API卸载qemu在virtio-net上所承担的虚拟队列功能,同样基于qemu共享内存空间布局、虚拟化队列的访问地址和事件文件描述符给用户态的vhost,使得vhost能进行报文处理以及客户机的通信,由于报文拷贝在用户态,linux内核得到了负担减轻。

虚拟网络演进之路

PART 05【 VFIO】

随着云计算规模的不断扩大,用户一方面不再满足于 Virtio 这类半虚拟化设备带来的性能体验,另一方面 GPU 这类很难进行 virtio 化的设备应用场景与日俱增。在这种背景下,VFIO 这项技术被提出。

UIO的作用是把一个设备的IO和中断能力暴露给用户态,从而实现在用户态对硬件的直接访问。它的基本实现方法是,当我们probe一个设备的时候,通过uio_register_device()注册为一个字符设备/dev/uioN,用户程序通过对这个设备mmap访问它的IO空间,通过read/select等接口等待中断。

UIO的缺点在于,用户态的虚拟地址无法直接用于做设备的DMA地址(因为在用户态无法知道DMA内存的物理地址),这样限制了UIO的使用范围。基本上UIO现在只能用于做工控卡这种IO量不大,可以直接把内存地址拷贝到IO空间的场景(相当于不做DMA)。我们有人通过UIO设备自己的ioctl来提供求物理地址的机制,从而实现DMA,但这种方案是有风险的,因为你做ioctl求得的物理地址,可能因为swap而被放弃,就算你做gup,但gup只保证物理内存不被释放,不能保证vma还指向这个物理页。

VFIO通过IOMMU的能力来解决这个问题。IOMMU可以为设备直接翻译虚拟地址,这样我们在提供虚拟地址给设备前,把地址映射提供给VFIO,VFIO就可以为这个设备提供页表映射,从而实现用户程序的DMA操作。

背负提供DMA操作这个使命,VFIO要解决一个更大的问题,就是要把设备隔离掉。在Linux的概念中,内核是可信任的,用户程序是不可信任的,如果我们允许用户程序对设备做DMA,那么设备也是不可信任的,我们不能允许设备访问程序的全部地址空间(这会包括内核),所以,每个设备,针对每个应用,必须有独立的页表。这个页表,通过iommu_group承载(iommu_group.domain),和进程的页表相互独立。进程必须主动做DMA映射,才能把对应的地址映射写进去。

虚拟网络演进之路

如上图所示,通过 VFIO,QEMU 能够直接将自己虚拟出的一个 PCI 设备和一个物理 PCI 设备的数据链路直接打通,当虚拟机里面的设备驱动访问虚拟 PCI 设备的 bar 空间时,通过 EPT 机制,这次 mmio 访问会被重定向到真实物理设备相应的 bar 空间位置,而不再需要 trap 到 QEMU。这样,虚机驱动就相当于可以以接近零消耗的方式直接访问真实物理设备,性能可以达到最佳。同时,VFIO 驱动利用 IOMMU 实现了设备 DMA 和中断的重映射,一方面起到隔离作用,即某个虚机无法操作 VFIO 直通设备向同一宿主机上的其他虚机发起 DMA 和中断,一方面也保证了设备进行 DMA 时通过给定的虚机物理地址能够直接访问到正确的物理内存。

这个逻辑空间其实是有破绽的,IOMMU是基于设备来创建的,一个设备有一个IOMMU(或者如果这个设备和其他设备共享同一个IOMMU硬件,是几个设备才有一个iommu_group),那如果我两个进程要一起使用同一个设备呢?基于现在的架构,你只能通过比如VF(Virtual Function,虚拟设备),在物理上先把一个设备拆成多个,然后还是一个进程使用一个设备。这用于虚拟机还可以,但如果用于其他功能,基本上是没戏了。

再说,VF功能基本都依赖SR-IOV这样的实现,也不是你想用就能用的。

【PART 07 VFIO-mdev】

VFIO 技术在实际应用场景,除了之前提到的不支持热迁移的问题外,还有一个限制就是一个设备只能透传给一个虚机,无法做到资源共享。SR-IOV 技术从某种程度上能够解决这个问题,即将一个物理 PCI 设备从硬件层面进行资源划分,划分成多个 VF,透传给多个虚机进行使用,但是有很多设备可能并不具备 SR-IOV 能力,并且SR-IOV还不支持热迁移,希望提供一个标准的接口来帮助设备驱动实现软件层面的资源切分,并能够利用 VFIO 技术透传给虚机。VFIO-mdev 这个技术框架应运而生。

该技术本质是在内核实现了一个虚拟设备(Mediated device)总线驱动模型,并在 VFIO 内核框架上进行了扩展,增加了对 mdev 这类虚拟设备的支持(mdev bus driver),从原来只支持从标准的硬件 PCI 设备和硬件 platform 设备获取透传信息。

虚拟网络演进之路

mdev本质上是在VFIO层面实现VF功能。在mdev的模型中,通过mdev_register_device()注册到mdev中的设备称为父设备(parent_dev),但你用的时候不使用父设备,而是通过父设备提供的机制(在sysfs中,后面会详细谈这个)创建一个mdev,这个mdev自带一个iommu_group,这样,你有多个进程要访问这个父设备的功能,每个都可以有独立的设备页表,而且互相不受影响。所以,整个mdev框架包括两个基本概念,一个是pdev(父设备),一个是mdev(注意,我们这里mdev有时指整个vfio-mdev的框架,有时指基于一个pdev的device,请注意区分上下文)。前者提供设备硬件支持,后者支持针对一个独立地址空间的请求。

两者都是device(struct device),前者的总线是真实的物理总线,后者属于虚拟总线mdev,mdev上只有一个驱动vfio_mdev,当你通过pdev创建一个mdev的时候,这个mdev和vfio_mdev驱动匹配,从而给用户态暴露一个普通vfio设备的接口(比如platform_device或者pci_device)的接口。

换句话说,如果一个设备需要给多个进程提供用户态驱动的访问能力,这个设备在probe的时候可以注册到mdev框架中,成为一个mdev框架的pdev。之后,用户程序可以通过sysfs创建这个pdev的mdev。

【PART 08 vDPA】

VFIO定义了一个IOMMU地址翻译模型,它基于平台IOMMU设备,而很多厂商的设备自己集成了地址翻译组件(比如mellox)并不使用平台IOMMU设备,这些厂商的NIC的地址翻译模型并不能很好的适配VFIO的模型。VFIO 和 virtio 这两类技术一直是最主流的设备虚拟化技术。VFIO 能够直接将硬件资源透传给虚机使用,性能最佳,virtio 性能稍逊,但胜在更加灵活。那有没有可能将两者的优势结合起来呢?vDPA 技术框架,就是为了实现这一目标。

vDPA 的全称是 Virtio Data Path Acceleration,它表示一类设备:这类设备的数据面处理是严格遵循 Virtio 协议规范的,即驱动和设备会按照第三节提到的 Virtio 通信流程来进行通信,但控制路径,比如:通信流程里面提到的 ring buffer 和 descriptor table 的内存地址,驱动如何告知设备,设备支持的特性,驱动如何感知,这些都是厂商自定义的。这样做的好处是,可以降低厂商在实现这类设备时的复杂度。

Linux 内核为了将这类设备应用起来,就提出了 vDPA 这样一个技术框架。这个技术框架本质上和 VFIO-mdev 类似,也实现了一个虚拟设备(vDPA device)总线驱动模型,和 VFIO-mdev 不同的是,通过 vDPA 框架虚拟出来的设备,既可以给虚机使用,又可以直接从宿主机(比如:容器)进行访问。这一切都归功于,vDPA 设备的数据路径是遵循 Virtio 协议规范的,因此,可以直接被宿主机上的 virtio 驱动直接访问。同时,该技术框架对 vhost 内核子系统进行了扩展,赋予了类似 VFIO 技术框架的功能,允许将 vDPA 设备用来进行数据通信的硬件资源(ring buffer, descriptor table,doorbell 寄存器等)透传给虚机使用。虚拟机的 virtio 驱动进行数据通信时,也是直接访问硬件资源,而不再需要通过 vhost、vhost-user 等方式进行处理了。更重要的一点是,由于虚机驱动是原本的 virtio 驱动,因此,当需要支持热迁移时,QEMU 可以灵活切换软件模拟的方式,来保证热迁移的顺利进行。这样,vDPA 这个设备虚拟化技术框架既保证了最佳性能又保留了 virtio 设备的灵活性,而且还统一了虚机和容器的 I/O 技术栈。

虚拟网络演进之路

虚拟网络演进之路

【PART 09 VDUSE】

通过上述 vDPA 技术框架,我们基本解决了长期以来设备虚拟化技术在虚机场景下暴露的一些问题,而更重要的是,它将 virtio 技术也带到了容器领域。但这个技术框架还存在一个问题,就是需要硬件设备的支持。回想之前提到的 virtio、vhost、vhost-user,本质上都是软件定义的虚拟设备。那 vDPA 这个技术框架有没有可能也能够使用软件定义的设备呢?VDUSE 这项技术就是用来实现这个目标的,通过 VDUSE,我们可以在一个用户进程实现一个软件定义的 vDPA 设备,并可以通过上述 vDPA 框架接入 virtio 或者 vhost 子系统,供容器或者虚机使用。

虚拟网络演进之路

结束语

从服务虚拟机到支持容器,从纯软件模拟到硬件直通再到软硬件结合,Linux 设备虚拟化技术这几十年里一直在朝着极致性能、应用灵活等方向不断演进。随着云原生的浪潮,各大硬件厂商的入局,全新的软硬件结合方式不断涌现,我们相信后续也会有更多精彩技术在等待着我们。

如果觉得本文对您有用欢迎点赞转发加关注!!!文章来源地址https://www.toymoban.com/news/detail-496320.html

到了这里,关于虚拟网络演进之路的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 容器技术发展和编排技术演进之路

    目录 Jail 时代 1979 年 贝尔实验室发明 chroot 2000 年 FreeBSD 4.0 发行 FreeBSD Jail 2001 年 Linux VServer 发行 2004 年 Solaris Containers 发行 云时代 2006 年 google 推出 Process Containers 2008 年 LXC 推出 2011 年 CloudFoundry 推出 Warden 2013 年 LMCTFY 启动 2013 年 Docker 推出到风靡全球 云原生时代 Google Docke

    2024年02月12日
    浏览(55)
  • 服务端⾼并发分布式结构演进之路

    应⽤(Application)/系统(System) 为了完成一整套服务的一个程序或相互配合的程序群 模块(Module)/组件(Component) 当应⽤较复杂时,为了分离职责,将其中具有清晰职责的、内聚性强的部分,抽象出概念,便于理解 分布式(Distributed) 分布式(Distributed)是指将计算、任务

    2024年02月13日
    浏览(94)
  • 微服务_微服务的架构演进之路

    目录 一、前言 二、单体架构 三、分布式架构 四、微服务 五、SpringCloud 六、服务拆分 5.1服务拆分原则 5.2服务拆分示例 微服务是一种软件开发架构风格,它将单个应用程序拆分成多个小型服务,每个服务都具有自己的特定功能。这些服务之间通过API进行通信,可以独立部署

    2023年04月09日
    浏览(76)
  • 火山引擎 BVE 视频图片硬件编码器演进之路

    动手点关注 干货不迷路 近日,第 17 届世界编码器大赛 MSU 2022 公布硬件编码器比赛结果,在 60 fps(帧率)的超快视频编码赛道上,火山引擎多媒体实验室自主研发的 BVE 1.1 编码器表现突出,荣获最佳 FPGA 编码器(各项指标大幅领先);并在所有硬件编码器中,技术指标获得

    2024年02月06日
    浏览(52)
  • docker macvlan虚拟化网络与宿主机通信问题解决——筑梦之路

    默认情况下各个macvlan之间可以通讯,但是不能与宿主机进行通讯!! 主要原因:为了安全而禁止互通 如宿主机ping容器的ip,尽管他们属于同一网段,但也是ping不通的,反过来也是。 这里用两个实例来说明如何解决这个问题。 实例一  实例二 参考资料: 解决Docker macvlan网络

    2024年02月07日
    浏览(51)
  • 探索容灾架构演进之路-从单点到异地多活

    在公司发展初期,业务发展和用户增长是首要关注的焦点。然而,随着业务规模不断扩大,用户数量逐渐攀升,应用稳定性的重要性也变得愈发凸显。在这个演进过程中,传统架构下的应用部署模式开始显露出多方面的稳定性风险,其中最为显著的问题之一就是机房单点故障

    2024年02月05日
    浏览(57)
  • 星云零售信贷基于 Apache Doris 的 OLAP 演进之路

    本文导读: 腾梭科技是国内领先的零售金融数字化及安全服务提供商,是腾讯投资且在金融领域的战略合作伙伴,并与腾讯联合研发了“星云智慧信贷解决方案。在其信贷业务转型过程中,随着系统规模不断扩大,早期架构无法再满足业务需求,因此腾梭科技决定引入 Apac

    2024年02月16日
    浏览(40)
  • 漫谈前端自动化测试演进之路及测试工具分析

    作者:京东零售 杜兴文 随着前端技术的不断发展和应用程序的日益复杂,前端自动化测试也在不断演进。 Web 前端 UI 自动化测试发展史可以追溯到 2000 年,当时最早的 Web 应用程序越来越复杂,开发人员开始使用自动化测试工具来确保应用程序的正确性和可靠性。 在早期,

    2023年04月19日
    浏览(49)
  • 软件架构之前后端分离架构&服务器端高并发演进之路

    首先,当一个项目刚起步的时候,不能预知后续的访问量和并发能达到多少,在初步开发的架构选型中,采用前后端分离的架构。关于前后端分离架构,其优势如下: 前后端分离是一种软件系统架构模式,它将应用程序的前端和后端分离开发和部署。在这种架构中,前端和后

    2024年02月10日
    浏览(54)
  • 美团到店终端从标准化到数字化的演进之路

    总第580 篇 |  2023年第032篇 本文整理自美团技术沙龙第76期《大前端研发协同效能提升与实践》。前端团队在产研多角色协同形式上存在不同阶段,而大前端多技术栈在各阶段都有其独特的实践,同时又有类似的演进路线。本文从到店终端团队移动端和前端技术栈持续交付演进

    2024年02月04日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包