基于OVS-DPDK 的docker 网络性能提升方案*
2023-01-16涂俊亮
涂俊亮,陈 伟
(中国电子科技集团公司第三十研究所,四川 成都 610041)
0 引言
当前,云服务商大多采用虚拟交换机来管理、隔离不同租户间的通信[1],应用最广泛的是Nicira公司的开源虚拟交换机(Open vSwitch,OVS)项目[2]。OVS 具备基础的网络隔离和报文转发功能,但在大网络流量下存在性能瓶颈。OVS 对报文的接收、处理主要在内核态进行,操作过程中内存会多次移动或拷贝报文,浪费内核资源,导致转发效率低下。此外,OVS 组网时,多容器(docker)的网络并发性能不佳,带宽分配不均匀。因此原生OVS 难以满足大规模云平台对网络边缘设备的性能需求。
英特尔公司推出的数据平面开发包(Intel Data Plane Development Kit,DPDK)[3]为用户态快速处理数据包提供了丰富的库函数和灵活的驱动支撑。DPDK 结合OVS 后,性能变得高效且方便开发,但直接部署还存在一些困难,如环境相关性高,运维困难,且对传输控制协议(Transmission Control Protocol,TCP)分片卸载的支持度不高。TCP 大包需要先分片变小后才能被送至网卡,导致虚拟机负载加剧,网络传输性能降低[4]。有研究表明,将OVS-DPDK 部署在docker[5]环境中会明显改善性能,因为在容器中,OVS 共享宿主机文件系统,宿主机和虚拟机间的连接采用OVS-DPDK 的桥接端口,从而无须通过物理网卡,TCP 分片卸载问题也不复存在。因此,本文选择在docker 环境下研究OVSDPDK 提升网络性能的效果。
本文首先介绍OVS 和DPDK 的原理及核心技术;其次针对实验瓶颈,利用二者联合部署解决;最后,从3 层转发、应用层传输两方面进行测试,研究OVS+DPDK 在生产环境中的优缺点及优化方向。
1 OVS 简介
1.1 OVS 结构
OVS 由核心组件ovs-vswitchd、数据库组件ovsdb-server、内核模块openvswitch.ko 3大要素构成,结构如图1 所示。
图1 OVS 内部组成
ovs-vswitchd 是OVS 的核心模块,在用户空间运行,负责地址学习、物理端口绑定、逻辑转发等基本功能。可利用OVS 自带的工具ovs-ofctl,基于openflow 协议进行交换机配置管理。
ovsdb-server 是存储OVS 配置、状态和日志等信息的轻量级数据库服务,ovsdb 是一个可持久化的数据库,交换机的配置信息均保存在其中,即使设备掉电也不会丢失。ovsdb-server 与ovs-vswitchd间采用OVS 数据库(OVS Data Base,OVSDB)管理协议通信,其内容包含但不限于配置信息加载、运行过程中变化的OVS 相关信息。
openvswitch.ko 组件作为快速转发平面运行在内核空间,实现修改报文、匹配流表、封装隧道、维护转发表等功能。在OVS 中,报文先经该组件封装或解析,然后进行转发规则匹配,匹配成功则直接转发,否则转交给用户空间的ovs-vswitchd 组件处理。它与ovs-vswitchd 采用NetLink 协议规范进行内核态和用户态进程间的通信。
1.2 OVS 网络应用
OVS 以软件形态存在于虚拟网络中,角色类似于物理交换机,具有局域网划分、隧道搭建、路由模拟3 大功能,其典型网络应用如图2 所示。图中虚拟交换机OVS0 是中心交换机,作为网络中心连接OVS1、OVS2、OVS3、OVS4 这4 个边缘交换机。边缘交换机与虚拟机直连,负责同网络的虚拟机间通信和跨网络的虚拟机间包转发。
1.2.1 局域网划分
通过划分虚拟局域网(Virtual Local Area Network,VLAN),可以实现同网络的虚拟机间局域网隔离。通过给中心交换机端口配置不同的VLAN 号,使边缘OVS 属于不同VLAN,隔断边缘OVS 间二层通信,实现跨网络的虚拟机间局域网隔离。本文便是利用该功能实现docker 间网络隔离。
1.2.2 隧道搭建
边缘OVS 可搭建隧道。在虚拟扩展局域网(Virtual Extensible Local Area Network,VXLAN)隧道应用中,OVS 能实现其中的由虚拟网段隧道终结点(VXLAN Tunnel End Point,VTEP)负责的VXLAN 报文解析封装、转发、地址学习等功能[6]。
1.2.3 路由模拟
OVS 结合控制器可模拟路由转发功能,实现在不同局域网中主机的数据转发。图2 中虚拟机B和F 所直连的边缘OVS(OVS1 和OVS3)属于两个局域网,不能进行二层转发。配合控制器,首先,将局域网中的地址解析协议(Adress Resolution Protocol,ARP)报文上报到控制端;其次,控制端感知OpenFlow中网络节点,获得所有设备网络信息;最后,将对应ARP 流表下发到OVS 上,有了流表信息,不同局域网的主机B 和F 便可通信。
图2 OVS 在网络中的应用
1.3 OVS 与网桥对比
相较于网桥(Linux-Bridge),OVS 图形化工具更方便管理员对云环境中的网络状态、数据流量等信息进行监管。相比网桥单纯基于媒体访问控制(Media Access Control,MAC)地址学习的转发规则,OVS 引入流缓存机制,可提高数据包转发效率。网桥仅支持通用路由封装隧道,OVS 则支持更多的隧道协议,如VXLAN、互联网安全协议(Internet Protocol Security,IPsec)。此外,OVS 作为软件定义网络(Software Defined Network,SDN)生态的一部分,其扩展性更高和应用范围更广。
OVS 也存在局限,其稳定性和可靠性不及网桥,其复杂的内部结构导致OVS 安装复杂、运维困难,并且OVS 与操作系统的集成友好度也不如网桥。
2 Intel DPDK 简介
2.1 DPDK 特点
DPDK 的设计理念是基于通用服务器,采用软件方式优化,以代替原用于网络设备的专用网络处理器。经过多次适配迭代,DPDK 目前已支持x86、精简指令集机器(Advanced RISC Machine,ARM)、无内部互锁流水级的微处理器(Microprocessor without Interlocked Piped Stages,MIPS)等架构,应用广泛[7]。DPDK 的主要技术特点有:
(1)用户态输入/ 输出(Userspace Input/Output,UIO),直接在用户态实现网卡I/O,实现零拷贝数据。
(2)CPU 预分配、并行处理,内存无须多次申请和释放,缓存高效工作,包时延锐减。
(3)CPU 和程序亲和性关联。把不同CPU 核与控制面及数据面线程绑定,减少核间切换,并调度热点代码段一直处于高速缓存中。
(4)无锁(LOCKLESS)环形缓存管理,去掉锁开销。
(5)内存大页方案,增大程序基础内存块容量,提高缓存命中和访问内存效率。
(6)轮询驱动(Poll Mode Driver,PMD)。用户态轮询,减少中断沉睡唤醒、上下文切换开销。
2.2 DPDK 架构
DPDK 是由在用户空间运行的数据处理、访问底层硬件资源与内核通信等接口库组成的集合,其内部结构如图3 所示。
图3 DPDK 库结构
样例App、用户App和独立软件开发商(Independent Software Vendors,ISV)系统App 作为应用运行在顶层。中层是各种库函数,其中核心库提供内存池、无锁环和大页内存等基础功能;扩展库函数提供扩展功能,如定时器;PMD 库匹配原生和虚拟网卡,通过轮询、线程绑定等技术获得网卡高速转发性能;Classify 支持如前缀最长匹配、通配符匹配的查表操作;QoS 库提供网口限速、流控和调度等功能。底层的内核网卡接口(Kernel NIC Interface,KNI)、虚拟功能输入输出(Virtual Function I/O,VFIO)等技术将I/O、直接存储器访问(Direct Memory Access,DMA)、中断等内核功能安全有效地向上提供给用户空间调用,并支持将报文向下注入内核协议栈。
2.3 DPDK 关键技术
本文的性能提升主要涉及UIO、内核网卡接口(Kernel NIC Interface,KNI)、PMD 技术,具体如下文所述。
2.3.1 UIO 技术
UIO 用户空间I/O 技术是指把内核中的大部分I/O 功能迁移至用户态完成,即绕过内核协议栈,直接从网卡收发数据包,减少内核资源消耗,其工作原理如图4 所示。
图4 UIO 技术工作原理
设备驱动由内核空间驱动和用户空间驱动组成,内核空间只负责UIO 设备注册、资源分配及少部分中断,其余大部分驱动工作在用户空间中完成。利用接口将UIO 驱动注册到内核后,会生成一个含有设备物理地址信息的地图文件,用户进程读取此文件,将内核空间地址映射到用户空间。操作用户空间便等同于直接映射操作其内存空间,以此避免数据在内核缓冲区和应用程序缓冲区的多次拷贝。
2.3.2 KNI 组件
KNI 组件能将数据重入内核协议栈,高效利用传统内核协议栈已有的成熟功能。DPDK 对包的处理旁路了内核,若在用户空间构建一套新的完整独立的协议栈是很复杂的;因此,可以在用户空间实现某些特殊的协议功能,再利用KNI 重载进入内核,而常用的普通协议无须重复造轮。KNI 通信机制如图5 所示。
图5 KNI 通信机制
虚拟网卡上的KNI 虚拟接口是用户空间和内核协议栈间通信的桥梁。网卡收到的数据包通过应用程序转发到用户空间,再通过KNI 虚拟接口到达内核协议栈进行处理,处理后若有响应报文,则再交由KNI 虚拟接口返回给应用程序。通信中的发送线程及接收线程,由两个逻辑核(如图5 所示CoreA0和CoreB0)独立处理,从而达到互不阻塞、提高效率的目的。
2.3.3 PMD 轮询
PMD 提供了一系列高优先级的配置设备、队列的接口,还能以屏蔽中断的形式访问、发送和接收描述符,因此用户态应用可以实时地收发包,甚至以最高优先级处理包。通过PMD 的轮询机制从网卡收包,屏蔽了中断,提高了大流量下的实时效率。显然这也导致CPU 核的占用率一直很高,不够节能,且不能直观看到CPU 负载状况。
3 实验环境和改进方案
3.1 实验环境介绍
在万兆服务器上创建多个虚拟机(docker),提供租户隔离的云服务,每个docker 上运行业务服务端程序,期望在高并发下获得高效的网卡性能。网桥部署下的实验场景如图6 所示,实验环境相关信息如表1 所示。
图6 网桥部署下的实验环境
表1 实验环境信息
测试端n个用户t1~tn通过运行业务客户端程序,访问对应的虚拟机docker-0~docker-N。虚拟机配置双网卡,分别桥接到服务器的bridge-0和bridge-1,两个桥分别绑定在实际网卡Net-0 和Net-1 上,网络包从一个网口进入虚拟机,从另一个网口返回客户端。为充分测试性能,客户端上业务程序均是多线程满负载并发执行,统计此情况下随着测试客户端的增加,物理网卡Net 上的总带宽和服务器的CPU 占用率。实验数据如图7 所示。
图7 不同docker 数时带宽和CPU 占用率
由图7可知,采用桥接模式时,随着docker增加,CPU 占用率逐渐增大,总网卡带宽在docker 为5 时达到峰值8.9,随后呈现下降趋势,无法达到万兆标称值,且单个docker 的带宽分配也不均匀,存在随机性。此外随着docker 增加,服务器上线程呈倍数级上涨,中断过多,任务切换开销大,内核负载增加,然而实验中发现内存使用并未显著增加;因此,当前瓶颈主要在CPU。基于DPDK 网络性能优势,考虑采用OVS-DPDK 组网。
3.2 OVS-DPDK 改进方案
本文设计的OVS-DPDK 架构如图8 所示。系统自下而上由OVS 内核态进程、DPDK 平台管理层、用户空间协议栈、OVS 用户空间核心进程共4 个模块组成。OVS 内核进程负责内核态报文转发和流表匹配。OVS 用户空间的核心进程负责用户态包传递,将报文传入用户空间协议栈,然后根据用户态流表匹配返回的结果进行相应处置(转发或丢弃)。用户空间协议栈则按各层协议进行封装或解析。
改进重点在于加入了DPDK 平台管理层,承上启下,对上层模块屏蔽底层硬件资源,并通过对上层提供接口实现对底层资源如内存、网卡、缓存等的管理。
如图8 所示,图中标注“1”“2”“3”的位置代表主要模块间的交互。
图8 基于DPDK 平台的OVS 架构
“1”表示数据收发管理线程和用户空间协议栈交互,涉及包发送或接收,报文按协议封装或解析。“2”中用户空间协议栈处理报文时,向网络缓存管理模块申请报文缓存区,用完后立刻释放,提高内存使用率。“3”中数据收发管理线程和流表匹配模块交互,依据报文头匹配结果进行相应的返回操作,本文设计流表能加快包在用户态转发,且旁路内核。
本文所提OVS-DPDK 架构与原生OVS 的区别在于,OVS-DPDK 架构指定CPU 核,通过OVS 配置的端口收到数据包,报文跳过内核态openvswitch.ko 操作,经DPDK 轮询机制直接实时送达用户态ovs-vswitchd 里处理。原生OVS 和OVS-DPDK 包交换对比如表2 所示。
表2 原生OVS 和OVS-DPDK 的比较
4 OVS-DPDK 配置
本文实验中使用到的关键软件版本为OVS(v2.8.0)+DPDK(v16.11),OVS-DPDK 环境安装和配置过程简述如下:
(1)相关编译环境、依赖库安装,包括但不限于gcc、libpcap、libnet 等。
(2)确定网卡型号是否支持DPDK,脚本为:lspci -nn |grep Ethernet #得到网卡类型为“xxx”进入dpdk目录,grep --include=*.h -rn -e ‘xxx’
(3)编译安装OVS 和DPDK。
(4)操作系统配置:
①系统BIOS 需打开VT-d,并通过grub 配置iommu 和intel_iommu 参数来支持VFIO 驱动;
②配置大页,系统每个page 默认占2 MB,本文配置1 000 个大页,大页共占用2 GB 内存。
(5)设置dpdk 驱动,脚本为:
modprobe vfio-pci #加载dpdk 驱动
网卡绑定到dpdk dpdk-devbind --bind=vfio-pci enp4s0f1(网卡名)
(6)启动OVS 进程。
(7)初始化DPDK,开启DPDK 功能。从ovs-v2.7.0 开始,不能通过vswitchd 进程启动时指定DPDK 等参数开启DPDK 功能,需通过设置ovsdb 来实现。主要配置3 个参数,具体如下:
ovs-vsctl --no-wait set Open_vSwitch .other_config:dpdk-init=true #设置dpdk 初始化启动
ovs-vsctl --no-wait set Open_vSwitch .other_config:dpdk-socket-mem=”2056,0” #指定的sockets 从大页预先分配的内存,大小为2 GB
ovs-vsctl set Open_vSwitch .other_config:pmdcpu-mask=0x02 #指定在某些core 上运行,该命令表示在02 号核上运行
(8)配置OVS,主要有创建OVS 网桥、网桥上新增DPDK 端口、配置模式,连接控制器、新增流表等。本文使用vhostuser 方式配置,主要脚本摘录如下:
创建两个dpdk 的虚拟桥
ovs-vsctl add-br br0 --set bridge br0 datapath_type=netdev
通过mac 地址接管网卡,并加入到br0 中
ovs-vsctl add-port br0 dpdk0 --set Interface dpdk0 type=dpdk options:dpdk-devargs=0000:04:00.1
使用vhostuser 配置
ovs-vsctl add-port br0 vnic0 --set Interface vnic0 type=dpdkvhostuserclient options:vhost-server-path=/tmp/dpdkvhostclient0
(9)创建docker,配置其网络,进行实验。
5 测试和分析
5.1 OVS-DPDK 的3 层转发能力测试分析
本文主要使用OVS_DPDK 的3 层转发能力,先使用DPDK 自带的收发包测试工具进行3 层转发测试。OVS+DPDK 3层转发测试平台拓扑如图9所示。
如图9 所示,服务器1 作转发服务器,服务器2 作测试服务器。在服务器1 上安装OVS+DPDK,创建并启动虚拟机,配置vhost-user 接口模式,并与虚拟机网口对应绑定连接到虚拟交换机上。虚拟机中安装DPDK 自带的3 层转发应用程序DPDK L3 Forwarding,它能实现3 层IP 间的包转发。修改OVS 流表规则配置,将eth0 上的包转到Vhostuser1 口,L3 Forwarding 可配置两个虚拟网卡的IP分别为192.168.1.1 和192.168.1.2。服务器2 上安装收发测试应用程序Pktgen。测试过程中数据包的流向:服务器2 PDK Pktgen—eth0 —Vhost-user1—virtio—L3 Forwarding—virtio—Vhost-user2—eth1—服务器2 DPDK Pktgen。闭环返回到Pktgen 应用程序中,并由其度量性能。
图9 OVS+DPDK 的3 层转发能力测试拓扑
测试转发大小递增的数据包,转发性能统计数据如表3 所示。
表3 不同大小包下3 层转发性能统计
测试结果表明,在3 层包的处理上,OVS+DPDK 比OVS+linux kernel 有明显性能提升。原生OVS 在小包转发时出现丢包现象,而OVS+DPDK在测试中未出现该现象,这得益于PMD 和大页内存的使用,提高了OVS 的收包能力。OVS 结合DPDK 后在3 层转发性能上是原生OVS 的4~7倍,当包大小为256 byte 时,性能提升最明显,且OVS+DPDK 可避免小包丢包现象。
5.2 OVS-DPDK 的应用层面能力测试分析
基于以上理想状态下的测试结果,在实际业务应用层面上进行性能测试,实验网络拓扑参考图7配置,将linux-bridge 模式换成OVS+DPDK 部署,使用单CPU 双核心模式,进行业务并发测试,结果如表4 所示。
表4 不同配置下的网络性能测试统计
数据绘制在双坐标轴中如图10 所示。使用OVS-DPDK 在容器数量从1 增加到10 的过程中,总带宽比较平稳,在9 GB 左右,网卡基本满载,CPU 的变化曲线相较网桥也更平稳,在docker 数量较少时,能高效利用CPU 性能,带宽利用也比普通桥接高8%~10%。docker 数量为10 时,OVSDPDK 带宽是网桥的1.3 倍,可以看出在容器数量增多的情况下,OVS-DPDK 的网卡利用性能更充分。OVS-DPDK 的CPU 占用率一直比普通桥接高,也印证了上文2.3.3 节中,CPU 核心的占用率会一直很高、不够节能的观点。
图10 OVS+DPDK 和linux_bridge 网络性能对比
给OVS 分配2 个CPU、4 个处理器逻辑核心后,OVS-DPDK 带宽测试结果可达到网桥的1.86 倍,但将核心继续增加到8 个和16 个时,OVS-DPDK带宽测试结果并没有比4 个的情况更好,这与核心数过多,任务调度消耗资源增多有关。
测试可得:在OVS-DPDK 架构下,使用virtio 驱动和vhost-user 接口配置虚拟机网卡,可有效提升网络性能,服务器网卡的性能损耗也明显降低,且在4 核时网络性能提升最大,网卡总带宽是原生桥接的1.86 倍。
DPDK 自带的3 层测试工具显示网卡吞吐率是网桥的4~7 倍,在实际应用层面上带宽只有1.3~1.86 倍,二者数值上有一定差距,吞吐率是瞬时收发性能的体现,带宽则是实际传输能力的衡量。从传输层到应用层之间还存在性能损耗,这与实验中流表配置是否合适、大页分配是否合理、包分片大小、CPU 绑定情况以及业务程序代码逻辑等均有很大关系。目前,1.86 倍的应用层带宽提升有一定效果,3 层测试工具吞吐率的4~7 倍提升是基于测试程序的底层极限性能提升,后续带宽优化到网桥的2 倍或接近万兆总带宽是可行的研究 目标。
6 结语
本文首先介绍了现阶段云网络方案,分析了OVS 性能瓶颈;其次引入DPDK;最后根据实际业务场景进行了OVS+DPDK 和网桥的3 层转发能力实验对比。理论上OVS+DPDK 的吞吐率是网桥的4~7倍,实际业务场景下带宽则是网桥的1.3~1.86倍。DPDK 在处理高速数据报文中有较大作用,但其配置复杂,且对CPU 的亲和性有一定要求。此外,从理论上的传输层到实际中的应用层间的性能兑现还需更多研究。
部分学者提出了OVS+DPDK 的优化方向,主要有开发用户态网络协议栈、添加DPDK 中断优先级、支持动态配置大页内存[8]3 个方面。OVS+DPDK 模式为云的网络性能优化提供了有效方案,后续希望能从以上3 个方面进行深入研究,结合实际业务需求,以期在应用层面上获得更大的网络性能提升。