写在前面

网络虚拟化曾经只是内核虚拟化功能开发者才会关注的技术。但随着云计算模式和云原生概念的推广,云上业务的部署形态都已转向了虚拟机和容器,而两者都依赖网络虚拟化技术提供高性能网络功能,因此虚拟网络已经是云环境下的主流网络形态。而云上的虚拟机和容器对网络虚拟化技术的易用性、功能和性能都提出了更高的要求。

对于云上环境的网络基础设施开发者来说,网络虚拟化已经成为了一种必须掌握的技术。但在学习网络虚拟化技术时,笔者没能找到一个能够完整介绍网络虚拟化技术类型、原理和实现的信息源,特别是中文资料。因此,笔者计划将学习网络虚拟化技术过程中收集到的信息总结一下,形成一系列介绍各种网络虚拟化技术的文章,供后续的学习和工作中参考。每项技术都会从笔者最关心的问题出发,介绍相关知识并尝试回答这些问题。

本文是其中的第一篇,介绍最经典的网络虚拟化技术——QEMU虚拟网卡。

问题

  1. 使用QEMU虚拟网卡时,guest系统中是如何使用网卡和网络的?是否感知虚拟化设备的存在,是否需要和运行在物理机上时使用不同的配置?是否需要修改内核?
  2. 在guest系统中如何感知和加载网卡?QEMU是如何实现来支持这种功能的?
  3. 在guest系统中如何通过网卡收发报文?QEMU是如何实现来支持这种功能的?
  4. guest系统收发的报文,在QEMU和host系统中是如何流转的?通过哪些环节实现guest和host、guest和外部网络间的交互?
  5. 用QEMU虚拟网卡方式支持虚拟机网络功能有哪些优点和不足?

QEMU

QEMU是LINUX平台上广泛应用的虚拟机管理器(VMM),它能够模拟多种硬件架构和设备,支持模拟运行多种不同的操作系统。其中,QEMU就支持了对特定网卡设备(例如e1000)的全虚拟化,使得guest操作系统和内核不需要做任何修改就能使用原有的网卡驱动完成网络操作。

QEMU-KVM架构图(来自wiki.qemu.org)

QEMU模拟IO设备的原理,可以参考Understanding QEMU devices和High-level introduction to virtualization's low-level。大体上,通过指令翻译或者基于KVM和CPU硬件虚拟化,QEMU可以在guest操作设备,也就是执行访问设备地址空间或寄存器的指令时,中断guest的执行流并模拟出guest操作对设备的影响,之后再恢复guest的执行。

QEMU虚拟网卡

网卡作为一种网络IO设备,在QEMU中的模拟实现和其他IO设备是一样的。通过QEMU的模拟,guest系统中使用虚拟网卡时的使用方法和感受和在物理机上是完全相同的(除了性能之外),不需要修改内核驱动或配置。

guest系统对网卡的感知和加载的模拟和其他设备的模拟也是一样的,对网卡的感知来自于QEMU对PCI/PCIE总线设备的模拟,对网卡的加载、收发包则是对网卡设备的模拟。

QEMU中实现了多种经典网卡设备的模拟,例如e1000、rtl8139、i82559c等。网卡设备和驱动的逻辑都是类似的,这里就以e1000的网络报文收发为例,分析一下guest中网络rx/tx操作的实现逻辑步骤。由于主流的x86架构CPU都已经支持了CPU硬件虚拟化,例如Intel的VT-x和AMD的AMD-V,因此这里只讨论QEMU-KVM场景。

TX:

  1. guest内核将tx报文内容写入skb
  2. guest内核将tx报文信息(例如数据的dma地址、长度等)写入descriptor ring
  3. guest内核修改网卡的tx队列寄存器,通知网卡处理tx报文
  4. 触发VM Exit,KVM处理VM Exit事件
  5. KVM发现是IO操作,返回用户态QEMU进程(qemu进程从ioctl中返回)
  6. QEMU处理IO操作,根据descriptor内容将报文转发
  7. QEMU更新虚拟网卡的状态和DMA内存
  8. QEMU重新通过KVM接口恢复guest执行(VM Entry)

RX:

  1. QEMU收到rx报文
  2. QEMU将rx报文内容写入guest指定的DMA地址空间
  3. QEMU将rx报文信息写入descriptor ring
  4. QEMU更新rx队列寄存器(虚拟)
  5. QEMU向guest注入中断
  6. guest处理中断,更新descriptor ring和寄存器,这里又会陷入QEMU

上面只是一个简化的流程,guest处理报文的逻辑和物理机是一样的,可以参考Linux系统下网络数据包的处理流程_dillanzhou的博客-CSDN博客。中断注入原理可以参考High-level introduction to virtualization's low-level。

通过上述流程,guest发送的报文就能够被QEMU转发到host内核或网络上,而从host或网络上发给guest的报文也可以被QEMU转发到guest虚拟网卡上。

QEMU虚拟网络

前面已经介绍了QEMU如何模拟guest的网卡行为,但仍然有一个问题,就是报文在QEMU到host内核/网卡之间是如何流转的?毕竟,guest需要通信的对象并不是QEMU本身。这部分功能称为虚拟网络的后端。

QEMU支持的网络后端模式实现主要有两种:SLIRP(user)和TAP。

SLIRP模式是一种在用户态实现的后端。在这种模式下,QEMU在用户态解析guest收发的网络报文,并向其他guest和host转发。同时SLIRP还支持NAT地址转换。这就要求在SLIRP模式下实现一套TCP/IP协议栈。SLIRP的实现笔者没有看过,也没有找到详细介绍其原理的文章。据找到的个别资料介绍,SLIRP在和host或外部网络通信时,并不是通过raw socket转发报文的形式实现的,而是通过将guest报文的行为翻译成普通socket操作来实现的,例如guest发送了一个SYN包,SLIRP就调用一个到目标地址的connect syscall。这个实现听起来有些不可思议,但SLIRP本身来自于很古老的协议模拟软件,因此也是可以理解的。但这种实现功能必然有限,如果guest发送一些不太标准的报文或SLIRP协议栈不能理解或处理的报文,那么网络功能必然不能正常运行。

TAP模式就比较好理解了。这种模式下QEMU为每个guest创建一个tap设备,直接向这个tap设备收发报文。tap设备可以连接到一个bridge上实现更复杂的路由功能。

其实guest报文到了QEMU用户态逻辑之后,后端的实现方式可以有很多种,例如OVS或OVS-DPDK。这部分的功能与虚拟化其实已经没有太多的关系,更多是网络报文处理转发能力的实现。后续将不再重点讨论这部分技术。

小结

本文分析了QEMU的经典网络虚拟化实现:物理网卡虚拟,以及QEMU的经典后端实现方式:SLIRP和TAP。通过本文的分析,应该已经可以回答文章开头提出的4个问题:

1. 使用QEMU虚拟网卡时,guest系统中是如何使用网卡和网络的?是否感知虚拟化设备的存在,是否需要和运行在物理机上时使用不同的配置?是否需要修改内核?

答案是不需要,guest完全不用感知或修改网络使用方式。

2. 在guest系统中如何感知和加载网卡?QEMU是如何实现来支持这种功能的?

通过拦截和模拟实现guest的PCI和网卡设备访问操作,让guest获得和在物理机上相同的操作结果。

3. 在guest系统中如何通过网卡收发报文?QEMU是如何实现来支持这种功能的?

同样通过拦截和模拟实现guest的网卡操作,并将外部发给guest的报文也通过模拟的方式交给虚拟机处理并注入中断。

4. guest系统收发的报文,在QEMU和host系统中是如何流转的?通过哪些环节实现guest和host、guest和外部网络间的交互?

通过SLIRP或TAP模式将报文转发到host或外部网络。

5. 用QEMU虚拟网卡方式支持虚拟机网络功能有哪些优点和不足?

QEMU虚拟网卡方式实现网络功能的优点是对guest系统透明,不需要guest系统做任何修改,使用物理网卡驱动就能操作虚拟网卡完成网络通信。

这种实现方式的主要缺点有两个。一是需要用软件去模拟各种真实物理硬件网卡的功能,由于硬件网卡功能复杂而缺乏标准,因此QEMU模拟网卡的代码也复杂多变,而且可能存在软件模拟的网卡行为和硬件不一致,导致guest系统中的网络行为和host上出现差异。

另一个更明显的缺点是性能。根据前面的分析,每次读写网卡寄存器或IO地址时都会导致guest应用到QEMU进程的来回切换,而一次网络读写操作可能会产生多次网卡IO操作,这就导致使用QEMU虚拟网卡时虚拟机的网络性能受限于上下文和guest/host切换的速度,必然远低于物理机的性能水平。

网络虚拟化——QEMU虚拟网卡相关推荐

  1. QEMU虚拟网卡设备的创建流程

    基于qemu-kvm-0.12.1.2-2.160.el6_1.8.src.rpm 虚拟网卡类型为virtio-net-pci virtio网卡设备对应的命令行参数为  -device virtio- ...

  2. virbr0怎么关闭_kvm虚拟化关闭虚拟网卡virbr0的方法

    我们知道:kvm虚拟化环境安装好后,ifconfig会发现多了一个虚拟网卡virbr0 这是由于安装和启用了libvirt服务后生成的,libvirt在服务器(host)上生成一个 virtual n ...

  3. virtualbox 创建桥接网络_VirtualBox 配置虚拟网卡(桥接),实现主机-虚拟机网络互通(图文教程)...

    网上搜出来的比较乱,讲的不明不白,因此根据自己弄过一次,确认可行的方式,做个备份,方便日后查阅. 环境: 在Oracle VM VirtualBox中安装的Ubuntu,具体版本名是:ubuntu-1 ...

  4. 网络虚拟化——virtio

    前言 在上一篇文章(网络虚拟化--QEMU虚拟网卡)中,讨论了经典的网络设备全虚拟化技术.这种技术不需要guest内核对虚拟网络设备有任何的感知和特殊处理,但性能较差,一次读写操作可能会产生多次需要H ...

  5. 华为dra路由方式分为relay和proxy_华为云计算(3)——网络虚拟化

    ​关注微信公众号IT小组,获取更多干货知识~ 一.网络虚拟化 网络虚拟化在介绍网络虚拟化之前,需要考虑一个问题--为什么需要网络虚拟化呢?之所以要对网络进行虚拟化,是因为在没有进行虚拟化之前,每个服务 ...

  6. 网络虚拟化技术与NFV

    一.虚拟化技术概述 1.虚拟化技术简介 虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机.在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在相互独 ...

  7. 建立服务器虚拟网卡,增加一个虚拟网卡 - 卡饭网

    如何在网络连接里面添加一个IP地址给虚拟网卡 如何在网络连接里面添加一个IP地址给虚拟网卡 一般来说当系统完成添加虚拟网卡以后,IP设置系统就会自动完成的,不需要手动.如果它不能够自动设置IP地址,也 ...

  8. esxi6.7虚拟机网卡连接第二个虚拟交换机_Linux云计算底层技术之网络虚拟化

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,第一时间掌握技术干货! 网络虚拟化相对计算.存储虚 ...

  9. 图解几个与Linux网络虚拟化相关的虚拟网卡-VETH/MACVLAN/MACVTAP/IPVLAN

    Linux的网卡驱动中内含了很多"虚拟网卡".早先的文章曾经详细分析过tun,ifb等虚拟网卡,类似的思路,在虚拟化大行其道的趋势下,Linux源码树中不断增加对"网络虚 ...

最新文章

  1. Android进阶知识:事件分发与滑动冲突(一)
  2. 最佳学习方法(3)听课--听一反三
  3. ARM嵌入式编程之STM32的命名方法 STM32F103VET6命名解释
  4. 李宏毅线性代数总结:万事万物皆可为向量
  5. 看《长安十二时辰》可以了解哪些算法知识
  6. android 初始化语言,Android Init Language(安卓初始化语言)
  7. 49 CO配置-控制-获利能力分析-把控制范围分配给经营范围
  8. 从0开始架构一个IOS程序——03 — -分包用添加pch全局引用文件
  9. Java孩子父母类_父母和子女复选框
  10. 【数据结构和算法笔记】:稀疏矩阵的存储结构详解
  11. MFC中如何在CMainFrame类中访问CxxxView视图类中的成员
  12. 服务器主板支持nvme,给老主板刷上一个加入支持NVMe模块的改版“BIOS”
  13. 邮件服务器搬家,邮件搬家操作方法
  14. ZJOI2018游记Round2
  15. 自动排课系统V2.0基本完善了
  16. ASP.NET Identity 2新增双重认证、帐号锁定、防伪印章功能并修复了一些bug
  17. idea如何使用subversion创建补丁包
  18. [收藏] 最全服务器基础知识科普
  19. 【Python语言】Python编程基础
  20. No Feign Client for loadBalancing defined.错误

热门文章

  1. 解决qemu-system-aarch64 Guest has not initialized the display (yet)
  2. Android Studio:Android Studio安装Genymotion插件
  3. 都说大数据前景很好,那么大数据培训出来就业情况如何?
  4. 【NOIP模拟】怪兽
  5. 仿知乎日报2.64版本
  6. 深度学习卷积神经网络学习小结2
  7. shell实例100例《七》
  8. 维视智造定义“工业机器视觉检测大脑”VisionBank AI 视觉软件发布会圆满召开
  9. 坐头等舱会比坐经济舱先到达目的地吗
  10. java如何将字符串写入到txt文件中,值得收藏!