Linux 网络虚拟化技术的演进

大家好!我是大聪明-PLUS

虽然文章标题写的是"网络虚拟化技术",但这些技术实际上也适用于其他类型的设备,例如硬盘和显卡。文章深入分析了设备虚拟化技术的发展历程和原因,并解释了这些技术的工作原理、优势和劣势。

硬件虚拟化是云计算中最重要、最基础的技术之一。没有它,虚拟机内的任何设备都无法运行:网卡、硬盘、键盘、鼠标等等。本文将追溯Linux中硬件虚拟化技术的发展历程。

陷阱与模仿

在硬件虚拟化的早期阶段,像QEMU这样的机器仿真技术通常采用完全硬件虚拟化。借助QEMU,我们可以模拟真实设备的全部寄存器和控制例程。当虚拟机内部的驱动程序访问设备的寄存器时,该指令会被QEMU拦截并处理。因此,虚拟机内部的设备驱动程序会将虚拟设备视为真实的硬件设备,可以直接使用,无需任何修改。(注:简单来说,您可以从制造商的网站下载并使用特定型号真实设备的驱动程序。)

陷阱模拟法的工作原理如下:

VirtIO

VirtIO是一种半虚拟化技术,旨在解决以往陷阱模拟方法固有的性能问题。VirtIO 于 2008 年被纳入 Linux 内核主线。

VirtIO 不使用真实的设备驱动程序;相反,它定义了专门为虚拟设备设计的驱动程序。与*"陷阱模拟"方法不同,VirtIO 设备驱动程序完全清楚它正在操作的是虚拟设备,而不是真实设备。这消除了许多不必要的 MMIO/PIO 操作,这些操作在使用* "陷阱模拟"方法时会因频繁的中断和内核调用而降低虚拟机的性能。最终,VirtIO 提高了 I/O 性能。

虚拟机内部的 VirtIO 驱动程序与 QEMU 模拟的虚拟设备之间的交互机制基于共享内存和环形队列。基本数据结构(拆分虚拟队列 )包括两个环形缓冲区(可用环已用环)以及一个描述符表。

VirtIO 的运行机制与 DMA(直接内存访问 )类似。在虚拟机内部,VirtIO 驱动程序首先将要传输到内存的缓冲区地址和长度写入描述符表。然后,它将与这些描述符对应的描述符表索引写入可用环,并通过 eventfd机制通知主机上的 VirtIO 服务器。

由于所有这些环形缓冲区、描述符表和缓冲区都在共享内存中------虚拟机本质上是一个用户空间进程,其内存可以与其他进程交互,例如由SPDK、DPDK等管理的进程------VirtIO 后端也可以直接访问部分共享内存,首先获取缓冲区的地址和长度,然后直接访问缓冲区。

处理完请求后,VirtIO 后端会填充相应的缓冲区,将描述符索引写入使用的环形缓冲区,并使用 eventfd机制发送中断来通知虚拟机内部的 VirtIO 驱动程序。

VirtIO技术图

虚拟主机

VirtIO 技术引入后,设备通常由 QEMU 自身进行模拟。因此,数据传输和接收直接通过 QEMU 进行,QEMU 处理数据后再将其传输到虚拟机。然而,随着时间的推移,开发者注意到,在模拟网卡时,数据传输和接收首先要经过 QEMU,然后再通过额外的系统调用和内核中断才能在硬件层面实际进行数据传输和接收。由此产生了一个问题:能否优化这一操作,避免 QEMU 和内核之间不必要的上下文切换开销以及额外的数据复制?

最终,在 2010 年,Linux 内核社区引入了vhost技术。这项技术通过将 VirtIO数据平面移至一个单独的内核线程中来优化整个过程,该线程专门负责数据处理。

因此,VirtIO 通信机制发生了变化:虚拟机驱动程序现在不再与模拟设备的 QEMU 用户进程线程通信,而是与服务于虚拟主机的独立内核线程通信。当服务于特定虚拟机的虚拟主机的内核 I/O 线程接收到数据包后,它会将数据包直接传递给内核网络协议栈和网卡驱动程序进行处理,从而消除了 QEMU 进程和内核之间上下文切换的开销。

VFIO

随着云计算的稳步发展,用户对VirtIO设备的性能越来越不满意。与此同时,对GPU等难以用VirtIO虚拟化的设备的需求也在不断增长。这促使了VFIO(虚拟功能I/O)的开发,VFIO于2012年被纳入Linux主线内核。本质上,VFIO是一个用户空间设备驱动程序框架,这意味着它允许用户空间进程直接访问设备驱动程序,绕过内核。

与早期的用户空间 I/O ( UIO ) 框架相比,VFIO 可以有效地利用硬件IOMMU(输入/输出内存管理单元)机制来提供安全的进程隔离。这使得 VFIO 可以应用于需要多租户的云计算环境中。

上图显示,得益于VFIO,QEMU 可以将虚拟 PCI 设备直接连接到物理 PCI 设备,从而在两者之间建立直接的数据路径。当虚拟机内部的设备驱动程序访问虚拟 PCI 设备的BAR(基址寄存器)空间时,该 MMIO 访问会通过EPT(扩展页表)机制重定向到 BAR 空间中与实际物理设备对应的地址,从而无需 QEMU 拦截此访问。这意味着虚拟机驱动程序几乎可以零开销地直接访问实际物理设备,从而确保最佳性能。

同时,VFIO驱动程序使用IOMMU进行DMA重定向和设备中断。这确保了严格的隔离------一台虚拟机无法直接访问运行在同一主机上的另一台虚拟机的设备内存。它还确保执行DMA的设备只能通过分配给该虚拟机的虚拟地址直接访问分配给该虚拟机的特定物理内存。同时,VFIO驱动程序使用IOMMU来实现DMA重定向和设备中断。

虚拟主机用户

尽管 VFIO 为虚拟机提供了接近物理机的 I/O 性能,但这项技术存在一个缺点:它不支持实时迁移*。*这意味着,使用 VFIO 设备的虚拟机无法像使用普通 VirtIO 设备的虚拟机那样轻松地进行迁移。因此,人们开发了新的设备虚拟化技术,这些技术既要具备与 VFIO 相同的性能,又要具备与 VirtIO 相同的灵活性。

其中一项技术是vhost-user,它于 2014 年引入 QEMU 社区。QEMU 的线程模型和vhost并未针对 I/O 操作进行优化,而为每个虚拟机分配一个单独的线程来处理 I/O 请求的传统方法对于整个系统而言也并非总是最优的。因此,vhost-user 的开发者提出了一种新方法:将VirtIO 设备的数据平面移至一个独立的用户空间进程中。

由于这是一个独立的进程,它不受 QEMU 和vhost传统线程模型的限制(QEMU 为每个设备分配一个单独的线程)。这意味着我们可以根据需要组织和实现该进程。此外,这样的进程可以以 1:M 模式同时处理来自多个虚拟机的 I/O 请求,也就是说,单个进程(服务器)可以处理来自多个客户端(虚拟机)的请求。这是一种更高效、更具可扩展性的虚拟机 I/O 请求处理方法。

与在内核空间运行的虚拟主机(vhost)相比,用户进程在管理和维护方面提供了更大的灵活性。vhost -user框架迅速引起了社区的关注,并成为新型虚拟机 I/O 请求服务模型(例如 SPDK 和OVS-DPDK)的基础。这些模型具有用户空间驱动程序,程序无需通过内核即可与其交互。此外,这些驱动程序不等待完成消息,而是直接轮询设备。

VFIO-mdev

在实际应用中,VFIO 技术除了缺乏实时迁移支持外,还存在另一个局限性*:* 一个设备只能分配给一个虚拟机,无法实现资源共享。SR-IOV技术可以通过将单个物理 PCI 设备划分为多个虚拟功能设备 (VFIO) 并同时分配给多个虚拟机,在一定程度上缓解这个问题。

然而,大多数设备缺乏 SR-IOV 支持(必须在硬件层面提供),因此在 2016 年,Linux 内核社区将VFIO-mdev框架集成到内核中。它提供了一个标准化的接口,允许在软件层面(驱动程序层面)共享物理资源,然后使用 VFIO 将这些资源传输到多个虚拟机。

VFIO- mdev 技术主要在内核中实现,它是一个虚拟设备总线(中介设备 ),扩展了内核内置的 VFIO 框架。它增加了对虚拟设备(例如mdev,即mdev 总线驱动程序 )的支持。以前,可以使用硬件 PCI 设备的 BAR 空间来处理数据,而现在可以直接从物理设备处理数据,也可以通过mdev 驱动程序定义的虚拟设备接口来处理数据。(译者注:这意味着现在有两种情况。第一种情况是,PCI 设备提供自己的 BAR 空间,QEMU 使用该空间来操作该设备(经典 VFI​​O)。第二种情况是,设备驱动程序提供一个虚拟设备 (mdev),该设备具有与 BAR 空间交互的类似接口,QEMU 可以使用该接口。)

例如,如果我们需要分割 PCI 设备的资源,我们可以实现相应的mdev设备驱动程序:从物理设备的 BAR 空间中切出各个部分,每个部分都是 4 KB 页面大小的倍数,并将它们作为 mdev 设备提供给不同的虚拟机使用。

vDPA

VFIO 和VirtIO 长期以来都是最流行的设备虚拟化技术。VFIO 可以直接为虚拟机提供硬件资源,确保最佳性能。而 VirtIO 虽然性能略低,但更加灵活。因此,人们自然会想要结合这两种技术的优势。正因如此,vDPA(VirtIO 数据路径加速)框架于 2020 年被纳入 Linux 内核主线。

vDPA 是一组设备,其数据平面严格遵循 VirtIO 协议规范(如本文相关章节所述),但控制平面的实现------例如环形缓冲区和描述符表的内存地址、通知驱动程序变更的方法、设备支持的功能以及所有这些在驱动程序中的实现方式------均由设备制造商自行决定,可能不遵循 VirtIO 协议。这降低了此类设备的制造复杂性。

vDPA框架与VFIO- mdev 本质上类似,也实现了虚拟设备总线(vDPA设备)。然而,与VFIO-mdev不同的是,使用vDPA框架虚拟化的设备既可以被虚拟机使用,也可以被宿主机使用(例如,容器)。

这是因为vDPA 设备的数据平面 符合 VirtIO 协议,这意味着主机上的 VirtIO 驱动程序可以直接访问这些设备。此外,该框架扩展了内核的vhost 子系统,提供了类似于 VFIO 的功能:它允许虚拟机直接访问用于与 vDPA 设备交换数据的硬件资源(例如,铃声缓冲区、描述符表、门铃 寄存器等)。当虚拟机中的 VirtIO 驱动程序执行数据交换时,它可以直接访问硬件资源,而无需使用vhostvhost-user等方法。

更重要的是,如果需要实时迁移支持,QEMU 可以灵活切换到软件仿真,确保实时迁移成功,因为虚拟机驱动程序是标准的 VirtIO 驱动程序。因此,vDPA 框架在保持 VirtIO 设备灵活性的同时,确保了最佳性能,并统一了虚拟机和容器的 I/O 堆栈。

VDUSE

vDPA框架解决了虚拟机场景下设备虚拟化技术长期存在的难题,更重要的是,它将VirtIO技术引入了容器领域。然而,该框架仍然存在一个问题:需要物理设备的支持。而VirtIO、vhostvhost-user技术则运行在软件层面,与硬件无关。

自然而然地,问题来了:软件定义设备能否在 vDPA 框架内使用?VDUSE技术正是为了应对这一挑战而开发的。它允许我们在用户空间创建软件定义的 vDPA 设备,并通过同一个 vDPA 框架将其连接到 VirtIO 或vhost子系统。这使得此类设备既可以用于虚拟机,也可以用于容器。

结论

几十年来,Linux 设备虚拟化技术一直在不断发展演进,从虚拟机管理和容器支持,到软硬件结合以实现最佳性能和灵活性。得益于云计算的指数级增长和主要硬件厂商的支持,软硬件结合的新兴技术层出不穷。

相关推荐
知识分享小能手2 小时前
Ubuntu入门学习教程,从入门到精通, Ubuntu 22.04 的磁盘存储管理(10)
linux·学习·ubuntu
半桔2 小时前
【高并发架构】从 0 到亿,从单机部署到 K8s 编排:高并发架构的 8 级演进之路
linux·云原生·容器·架构·kubernetes
脏脏a2 小时前
【Linux】从 fork 到进程终止:写时拷贝细节与常见退出方式
linux·运维·服务器·进程终止
大聪明-PLUS6 小时前
面向开发者的实用 GNU/Linux 命令(第二部分)
linux·嵌入式·arm·smarc
sorry#10 小时前
top简单使用
linux·运维
QQ__176461982411 小时前
Ubuntu系统创建新用户与删除用户
linux·运维·服务器
渣渣盟11 小时前
Linux邮件服务器快速搭建指南
linux·服务器·开发语言
6极地诈唬11 小时前
【PG漫步】DELETE不会改变本地文件的大小,VACUUM也不会
linux·服务器·数据库
ArrebolJiuZhou11 小时前
00 arm开发环境的搭建
linux·arm开发·单片机·嵌入式硬件