亚马逊AWS官方博客
如何在 AWS EC2 实例以及基于 AWS 的容器平台中使用 DPDK(一)
1 背景
数据平面开发工具包 Data Plane Development Kit(DPDK) 由一组库和用户空间驱动组成的,用来加速包处理和转发的速度并降低延时,它支持多种不同的处理器架构和操作系统。DPDK被设计运行在用户空间,这样,基于DPDK的应用程序可以直接与网卡交互收发数据包,对于某些网络性能密集型场景下的应用有着现实的意义。
具体来说,DPDK所带来的主要的优势在于:通过用户空间的驱动,旁路kernel和TCP协议栈,规避了过多的内存拷贝和系统调用;通过轮询的方式,避免传统包处理时的中断和上下文切换;通过hugepage降低TLB miss,同时利用多通道内存,避免了过多访存开销;最后,还可以设置亲和性和独占,避免了不同核心的线程切换。除此之外,DPDK还在管理上提供了更多的包处理的可控制性。
进一步,在容器环境下,无论是原生的Docker还是平台化的kubernetes,不同的网络插件也提供了对于DPDK的支持,使得在容器环境中也可以利用到DPDK所提供的优势和性能提升。
2 DPDK对AWS的支持
在AWS平台上,DPDK可以支持具有增强网络(Enhanced Networking)的实例,包括了基于intel的82599(ixgbevf)和基于AWS的Elastic Network Adapter(ena)。具体来说,基于Nitro的实例,例如C5,M5,I3和T3以及上一代基于intel的C4,M4和T2等具备增强网络的实例都可以支持DPDK。在使用DPDK时,需要选用16.04之后的版本,DPDK在该版本之后才提供了对AWS EC2的支持。
下图示意了non-DPDK和DPDK优化的应用之间的区别。
本文使用AWS EC2 C5.2xlarge实例,说明了如何在AWS EC2中安装和部署DPDK环境。
在后续的文章中,会进一步针对AWS上的容器平台如何和DPDK集成给出说明。
3 设置DPDK环境
使用amazon linux2 AMI启动一台c5.2xlarge实例,并通过ssh登录。
3.1 设置hugepages
CPU所能支持的hugepages大小可以通过查看CPU的flag确认,如果支持pse,则平台支持2MB的hugepages,如果支持pdpe1gb,则平台支持1GB的hugepages。
查看我们使用的操作系统环境c5.2xlarge。
可见,c5.2xlarge可以支持2MB的hugepages和1GB的hugepages。 对于不同的hugepages,用不同的方式完成配置。一般来说,对于64-bit的应用,建议使用1GB hugepages。下面我们会分别来进行说明。 针对2M hugepage,设置如下: 在大多数较新的linux发行版,默认已经启用的2M hugepages,并已经通过dev-hugepages.mount服务进行挂载,比如本文所使用的amazon linux2。镜像为amzn2-ami-hvm-2.0.20191116.0-x86_64-gp2 (ami-07539a31f72d244e7),kernel版本4.14.154-128.181.amzn2.x86_64。 更新系统。
查看当前系统对于hugepages分配和支持。
针对2M hugepages,可以通过不同的方式来进行配置。
设置内核参数的方式。针对grub2引导的发行版,配置如下:
重启后可以确认已经生效。
临时修改修改内核参数的方式。
对于多节点的NUMA实例,需要显式的设定不同的NUMA节点。
当然,上述方式重启丢失需要重新设置,可以通过sysctl.conf配置来配置持久生效。
针对1G hugepages,只能通过配置内核启动参数的方式进行设置。后续的操作会使用1G hugepage来进行。
首先修改/etc/default/grub,增加GRUB_CMDLINE_LINUX=”default_hugepagesz=1G hugepagesz=1G hugepages=4”
重新启动实例。可以查看设置已经生效。
3.2 安装和配置DPDK
配置编译和使用所需的系统环境。
DPDK可以使用meson和ninjia来进行配置,构建和安装,如果使用这种方式请首先安装meson和ninjia。
下面的说明中,我们使用makefile而并没有使用meson和ninjia进行安装。下载DPDK包。
配置和安装。
另外,DPDK提供了安装配置脚本dpdk-19.11/usertools/dpdk-setup.sh,我们也可以使用该脚本进行安装并可以进行后续的配置操作。
基于脚本配置方式如下。
安装完毕之后,创建的目标目录内会包括了所有的lib库,poll-mode驱动和header文件,用以后续构建基于DPDK的应用。此外,该目录还包括一些内置编译完成可用的DPDK应用,可以用于测试。
接下来,我们需要加载相应的驱动来替代默认的ena驱动,以支持DPDK。ENA网卡可以支持UIO模式或者VFIO模式的DPDK驱动,linux的内核已经包含了标准的uio_pic_generic驱动,而刚刚我们编译也获得了DPDK提供的igb_uio驱动,uio_pic_generic对于Virtual functions的支持会有限制,通常在UIO模式下,我们会使用igb_uio。
相对来说,VFIO会是一个更加安全和健壮的选择,但是VFIO需要依赖于IOMMU,并且也不支持创建Virtual functions,同时还需要设置所需的权限来运行非特权用户的DPDK应用。当在不支持IOMMU的环境中,比如我们使用的EC2 C5.2xlarge环境,想要使用VIFO时,也会工作在类似UIO的非安全环境。另外,你可能需要使用AWS的patch https://github.com/amzn/amzn-drivers/tree/master/userspace/dpdk来重编译vfio-pci,以避免可能的性能问题或支持某些特性比如write combining。如下为直接加载vfio-pci模块并配置权限。
对于大部分实例来说,并不支持IOMMU,需要确保驱动的noiommu参数被设置。
对于其他一些实例来说,比如 i3.metal,可以支持IOMMU,需要在内核参数指定。通过类似的方法,修改grub2启动设定。在GRUB_CMDLINE_LINUX中追加iommu=1 intel_iommu=on。然后重新生成引导参数文件。
重启即可生效。
3.3 挂载hugepagefs
之前的操作已经完成了hugepages内存的预留,要使得DPDK能够使用这些内存,还需要如下步骤的配置和操作。
对于2M hugepage来说。
或者通过修改/etc/fatab来持久化设置挂载点。
对于1G hugepage,必须要指定pagesize作为挂载参数,本文的操作采用此方式。
3.4 绑定ENA设备到UIO或者VFIO模块
这里以UIO模块为例。
首先,我们在测试的实例上增加一个新的ENI网口来配置DPDK。只需在控制台新增网络接口,并附加到正在使用的实例上。如下所示。
之后,我们可以在实例内查看到这块新加入的设备。
我们将eth1绑定到igb_uio模块,DPDK提供的dpdk-devbind.py脚本可以用来进行绑定,解绑或者状态查看等操作(或者使用dpdk-setup.sh脚本来进行配置)。当前两个ENA设备均使用的ena驱动。
接下来,将设备 eth1,0000:06:00.0绑定到 igb_uio 驱动。
首先关闭eth1端口
绑定到igb_uio驱动。
也可以使用设备名:
确认是否正常绑定。
如果需要恢复eth1使用原有的内核ena驱动,类似的简单进行如下操作。
4 测试DPDK环境
请注意前面设置的RTE_SDK和RTE_RARGET环境变量是否正确。编译一个内嵌的helloworld应用来进行测试。
5 结论
DPDK可以支持AWS ENA和82599网络设备,可以在AWS多种不同的实例上部署DPDK和运行支持DPDK的应用,从而对多种应用场景,比如电信行业虚拟化分组核心等提供更全面的支撑。
另外,DPDK也已经和容器网络有了良好集成,这体现在原生的Docker网络上,也体现在包括kubernetes在内的诸多平台使用的CNI实现中,比如contiv和Vhostuser等都可以支持DPDK。
在后续的文章中,我们会针对AWS上的Docker和容器编排平台使用DPDK来进行进一步说明。
6 参考链接
https://github.com/amzn/amzn-drivers/tree/master/userspace/dpdk
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/index.html