虚拟交换机发展历程

虚拟机交换机发展历程可以总结为: Linux Bridge -> OVS -> OVS-DPDK 阶段.

1、Linux Bridge

同 tap/tun、veth-pair 一样,Bridge也是一种虚拟网络设备,具备虚拟网络设备的所有特性,比如配置IP、MAC等,除此之外,Bridge与普通的网络设备相比,有个重要的特点:Bridge有多个端口,数据可以从多个端口进,从多个端口出,普通设备就像一个管道,只有两端,一端进一端出.

Bridge这个特性让它可以接入其他的网络设备,比如物理设备、虚拟设备、VLAN设备等.Bridge通常充当主设备,其他设备为从设备,这样的效果就等同于物理交换机的端口连接了一根网线.如下图通过Bridge连接两个VM的tap虚拟网卡和物理网卡eth0.

Bridge 常用语虚拟机和容器网络中,这两种网络在数据传输流程中有一些不同,如下图所示.

1.1、虚拟机网络

虚拟机一般通过tap/tun 设备将虚拟机网卡同宿主机里的Bridge连接起来,完成同主机和跨主机的通信,具体步骤如下:

  1. 创建一个bridge设备br0

    cmd 复制代码
    # 有两种实现方式
    # 第一种
    ip link add br0 type bridge
    ip link set br0 up
    
    # 第二种
    brctl addr br0
    ifconfig br0 up
    brctl addif br0 eth0
  2. 虚拟机网络使用桥接设备br0连接到宿主机网络,如下配置就会让VM使用br0网桥作为其网络连接

    xml 复制代码
    # 配置 虚拟机xml中 <interface> 节点
    <interface type='bridge'>
      <mac address='52:54:00:bd:be:2b'/>
      <source bridge='br0'/>
      <model type='virtio'/>
      <address type='pci' slot='0x3'/>
    </interface>

    配置如上后,当执行virsh start vm1.xml​ 拉起虚机时,libvirt首先解析xml,并构建qemu命令行,在这一步骤就会open /dev/net/tun 创建tun/tap设备,并获取该设备对应的文件描述符fd,并将其信息传入到qemu命令行中

    powershell 复制代码
    # -netdev tap,fd=36 表示的就是连接主机上的tap设备,fd=36为读写/dev/net/tun 的文件描述符
    /usr/bin/qemu-kvm -name vm1 .... -netdev tap,fd=36,id=hostnet0,vhost=on,vhostfd=37 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:bd:be:2b,bus=pci.2,addr=0x0 .....

    这条命令启动了一个虚机,并为其配备了:高性能半虚拟化网络接口virtio-net device,该接口通过TAP设备连接到主机,并启用了vhost-net内核加速.该网络配置分为两部分;后端在主机host上做的事情,前端guest虚机内部看到什么.

    后端 -netdev tap,fd=36,id=hostnet0,vhost=on,vhostfd=37​这部分定义了虚拟机网络在主机端的实现方式:

    • -netdev tap指定网络后端类型为TAP,Qemu发送的网络包会直接出现在主机的TAP设备上;
    • fd=36表示了通知Qemu不需要自己创建TAP设备,直接使用已经打开并传入的文件描述符fd,编号为36
    • id=hostnet0为这个网络后端设置一个唯一的ID,该ID将用于在 -device 参数中引用这个后端,将虚拟网卡与它连接起来
    • vhost=on启用vhost-net内核加速
    • vhostfd=37 这是一个指向 /dev/vhost-net 设备的已经打开文件描述符,表示已经为Qemu准备好了vhost-net的句柄

    前端 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:bd:be:2b,bus=pci.2,addr=0x0​ 定义了虚拟机内部能看到的虚拟硬件信息:

    • -device virtio-net-pci告诉Qemu在虚拟机中插入一个设备,类型为 virtio-net-pci
    • netdev=hostnet0这是连接前后端的关键,他告诉这个虚拟网卡,应该使用ID为hostnet0的后端数据通道,这样虚拟机里的 virtio-net设备就和主机上的TAP设备连接起来了
    • mac=52:54:00:bd:be:2b为虚拟网卡设备指定一个固定的MAC地址,52:54:00是QEMU/KVM常用的私有MAC地址前缀
    • bus=pci.2,addr=0x0指定这个设备在虚拟PCI总线上的位置
  3. 可以配置上ip, ping包试试

两个VM通信如下图所示:

虚拟机发出的数据包通过tap设备先到达br0,然后经过eth0发送到物理网络中,数据包不需要经过主机的协议栈,效率较高.

1.2、容器网络

一般是使用 veth-pair 来连接容器和主机,因为在主机看来,容器就是一个个被隔离的 namespace,用 veth-pair 更有优势.

容器的 Bridge 网络通常配置成内网形式,要出外网需要走 NAT,所以它的数据传输不像虚拟机的桥接形式可以直接跨过协议栈,而是必须经过协议栈,通过 NAT 和 ip_forward 功能从物理网卡转发出去,因此,从性能上看,Bridge 网络虚拟机要优于容器.

1.3 Bridge VLAN

物理交换机具有虚拟局域网(VLAN),是对局域网LAN的软件化升级,LAN的缺点是LAN中任何节点发的数据包,其他节点都能收到,这就会很容易导致:

  • 容易形成广播风暴
  • 广播包无法割离,比如节点B不想接收节点A的包,但是无法割离

因此解决如上问题就是VLAN,VLAN可以对广播包进行有效的隔离,将交换机的端口虚拟出多个子端口,用 tag 来标记,相当于将交换机的端口划分多个LAN,同一个LAN的节点发出的数据包打上LAN的tag,这样LAN中其他的节点就无法收到包,达到隔离效果.

Bridge 本身也支持VLAN功能,如下图所示,Bridge将一个物理网卡设备eth0划分成两个字设备eth0.10和eth0.20,分别挂到 Bridge 虚拟出的两个 VLAN 上,VLAN id 分别为 VLAN 10 和 VLAN 20。同样,两个 VM 的虚拟网卡设备 vnet0 和 vnet 1 也分别挂到相应的 VLAN 上。这样配好的最终效果就是 VM1 不能和 VM2 通信了,达到了隔离:

Linux Bridge + VLAN 便可以构成一个和物理交换机具备相同功能的虚拟交换机了。对于网络虚拟化来说,Bridge 已经能够很好地充当交换设备的角色了。

2、OVS(Open vSwitch)

OVS 作为一种网络虚拟化的方式,在虚拟机的虚拟网卡vNIC和服务器的物理网卡之间通过软件模拟网桥的方式进行映射,并依赖精确流表中匹配源/目的IP、源/目的端口、三层协议、VLAN等字段进行报文转发.

OVS的引入和发展主要有一些几个原因:

  • 方便网络管理与监控.可以帮助管理员对整套云环境中网络状态和数据流量进行监控,比如分析网路中流淌的数据包来自哪个VM、哪个OS及哪个用户
  • 加速数据包的寻路与转发,OVS引入流缓存的机制,加速数据包转发效率
  • 隧道协议支持.OVS相较于Bridge支持更多的协议,包括VXLAN、gre、iIPsec

从如上模块图所示,OVS可以划分为管理面、数据面、控制面三块:

  • 数据面:以用户态的 ovs-vswitchd 和内核态的 datapath 为主的转发模块,以及与之相关的数据库模块ovsdb-server(主要保存了整个OVS的配置信息)
  • 控制面:主要由 ovs-ofctl模块负责,给予OpenFlow 协议与数据面进行交互
  • 管理面 :主要是由OVS提供的各种工具来负责,方便用户对底层各个模块的控制管理
  1. 数据包达到虚拟机网卡后(比如TAP),上传给datapath
  2. datapath 首先进行报文头信息的获取,根据报文头信息头生成匹配流表项的key值,得到key值后进行内核态流表匹配(Flow Table),如果缓存中没有找到该记录,内核通过netlink upcall给用户空间的vswitchd
  3. vswitchd 检查数据库数据包的目的端口在哪里,涉及对OpenFlow流表的操作,需要和ovsdb以及ovs-ofctl的交互
  4. 刷新内核态流表
  5. reinject 给 datapath,重发数据包
  6. 再次查询流表,获取数据包精确转发规则后,按照规则转发
  7. 转发数据包

2.1 OVS 交换原理及瓶颈点分析​

TODO:

3、OVS-DPDK

DPDK是Intel开发的一款高性能数据平面的开发工具包,如下图可以显著看出来DPDK的作用:

从传统的OVS交换原理分析中看网络IO实现方式中,内核是导致性能瓶颈的原因所在,要解决性能问题就需要绕开内核,直接在用户态首发包.

OVS- DPDK架构图如下:

OVS-DPDK会创建一堆PMD线程(绑定CPU核),每个线程负责从某个Physical NIC或vhost-user queue轮训手包,可以做流弊哦啊查询、action转发、最终发包,这在过程中没有中断,没有内核参与,纯轮训模式.

网卡收包流程:

  1. 当网卡收到数据包后,DMA到DRAM的 rx ring buffer
  2. PMD线程轮询使用 rte_eth_rx_burst 将包读出来,每个包是rte_mbuf
  3. 在OVS-DPDK中进行Flow匹配查询(先从EMC超高速缓存中查,查不到再去大规模流缓存Megaflow cache中查找0,如果可以找到直接执行action(比如输出到某个NIC、输出vhost-user(发给VM、修改MAC、IP等),转发
  4. 如果没有查询得到,则把报文送给ovs-vswitchd用户态主线程,找到匹配流表,将该流表下发到EMC、Megaflow
  5. 报文reinject再转发

全是用户态,没有内核upcall.

Guest VM发包流程:

  1. Guest virtio-net driver 处理发包,Guest应用写socket->Linux内核->virtio-net driver,最终kick触发通知,此时packet还在Guest DRAM(如果前端是virtio-pmd driver,应该是可以绕过Linux内核的)
  2. Qemu + vhost-user 数据面初始化阶段,Qemu会通过vhost-user协议将ring的物理地址(GPA)又一个GPA->HVA的映射
  3. OVS-DPDK vhost-user PMD线程直接从Guest共享内存的报文读取变成DPDK mbuf,这会有一次拷贝
  4. 在OVS-DPDK中进行Flow匹配查询(先从EMC超高速缓存中查,查不到再去大规模流缓存Megaflow cache中查找0,如果可以找到直接执行action(比如输出到某个NIC、输出vhost-user(发给VM、修改MAC、IP等),转发
  5. 如果没有查询得到,则把报文送给ovs-vswitchd用户态主线程,找到匹配流表,将该流表下发到EMC、Megaflow
  6. 发包:发给物理网卡 tx ring中,nic tx ring 只方一个指向mbuf data的描述符(DMA地址+长度)

OVS-DPDK datapath 简化图对比:

传统OVS依然需要在kernel态和用户态进行切换,datapath如下图所示:

OVS-DPDK datapath 如下图所示:

参考文献

从 Bridge 到 OVS,探索虚拟交换机

Linux 虚拟网络设备详解之 Bridge 网桥

OVS DPDK vs OVS Deep Dive

NFV中:DPDK与SR-IOV应用场景及性能对比

The amazing new observability features of Open vSwitch

OpenvSwitch virtio-net与vhost-net通信

浅谈虚拟交换机(vswitch)技术演进

相关推荐
hbugs0013 小时前
【EVE-NG镜像制作系列教程】28、Nexus 9000v交换机
网络·eve-ng·eve-ng镜像·eve-ng镜像制作·eve-ng教程
init_23614 小时前
【hcip-19】mstp
网络
张3蜂4 小时前
ip可以伪造吗
网络·网络协议·tcp/ip
ICT技术最前线4 小时前
防火墙SD-WAN如何选择,才能既安全又高效?
网络·安全·防火墙·sd-wan
谷粒.4 小时前
DevOps流水线中的质量门禁设计:从理论到实践的全景解析
运维·开发语言·网络·人工智能·python·devops
GOTXX4 小时前
性能与可靠双突破:openEuler 服务器场景评测报告
运维·服务器·网络·人工智能·后端·python
打不了嗝 ᥬ᭄4 小时前
【Linux】多路转接 Select , Poll和Epoll
linux·网络·c++·网络协议·http
9ilk4 小时前
【Linux】--- 五种IO模型
linux·运维·网络
chuxinweihui4 小时前
⽹络层IP协议
服务器·网络·网络协议·tcp/ip