随着云计算与大数据的快速发展,其对数据中心网络的性能和管理提出了更高的要求,但传统云计算架构存在多个I/O瓶颈,由于云平台基本上是采用传统的X86服务器加上虚拟化方式组建,随着40G、100G高速网卡的出现,如何在通用的X86平台上实现网络的快速转发就成为关键。DPDK是INTEL推出的基于X86平台提升数据面报文快速处理速率的应用程序开发包[1],关于DPDK的资料已经比较多,本文不再做过多介绍,本文重点关注DPDK与OpenStack的结合。
目前在OpenStack中使用DPDK实现数据平面用户态转发的项目有两个networking-ovs-dpdk 和networking-vpp,networking-vpp[2]项目还在功能完善阶段,而Open vSwitch+DPDK的实现已经全部合入主干,因此本文主要介绍Open vSwitch+DPDK的实现原理、如何配置使用以及该特性目前在社区的完善度。

Open vSwitch with DPDK

Open vSwitch在2.2版本开始支持DPDK,从2.4开始可以使用DPDK优化的vHost路径[3],其架构如下图所示[4]:

Open vSwith使用DPDK在用户态实现了netdev datapath:使用轮询driver绕过内核协议栈来直接处理物理网卡上的数据包,使用vHost and IVSHEM库作为宿主机到guest OS的控制和数据通道。当使用IVSHEM时,可以在guest OS中运行DPDK应用,这种场景下DPDK中的应用必使用宿主机上的共享内存大页。对于vHost的实现,Open vSwith通过socket实现控制消息的处理,通过共享的内存大页实现真正数据包的处理。

Open vSwitch中vHost-user类型

vHost-user介绍

vhost-user是利用现有的vhost提供的机制(共享内存,ioeventfd和irqfd),针对virito设备实现的一种交换的传输方式。vhost-user通过UNIX socket在两个进程之间设置Vrings和共享内存。当virtio设备发出kick信息时,也通过UNIX socket和进程进行交互,想了解关于vhost、vhost-user更多细节可参考我同事写的一篇文章[14]。

结合Open vSwitch和QEMU使用时,在Open vSwitch的vhost-user模式下,Open vSwitch作为backend,QEMU作为client,在vhost-user-client模式下,QEMU作为backend,Open vSwitch作为client,下一节会有详细说明。

Open vSwitch支持的vHost-user类型

在Open vSwitch中vHost User通过socket进行通信,模式为client-server,其中server端负责创建/管理/销毁所需socket连接,客户端只需要通过socket连接到server端,Open vSwitch支持两种类型的vHost User端口[5]:

VHOST-USER

vhost-user在Open vSwitch中的端口类型为dpdkvhostuser,该模式下Open vSwitch作为server端,QEMU作为client端,使用该类型端口时,要求QEMU版本必须>=2.2。
该模式下vHost端口不具备‘reconnect’能力。当Open vSwitch服务异常后,QEMU作为client端能感知到该异常并将端口状态置为down,但当Open vSwitch服务恢复后,QEMU作为client端不会自动重新连接server,导致虚拟机网络无法自动恢复。

VHOST-USER-CLIENT

vhost-user-client在Open vSwitch中的端口类型dpdkvhostuserclient,该模式下Open vSwitch作为client端,QEMU作为server端,使用该类型端口时,要求QEMU版本必须>=2.7。
该模式下vHost端口具备‘reconnect’能力。使用该类型端口创建虚拟机时,QEMU会等端口创建成功,client连接上后启动虚拟机,在Open vSwitch服务出现异常或被停止后,QEMU会将端口状态置为down,当Open vSwitch服务恢复正常后,client会重新连接server,触发QEMU重新将端口状态置为up。

Open vSwitch with DPDK在OpenStack中的实现

OpenStack对Open vSwitch with DPDK的支持是在Kilo版本,这是一个跨Nova和Neutron两个模块的特性,Nova中需要在libvirt 的vif driver中新增一个vhost user driver,具体实现可参考[6],Neutron侧的代码放在一个独立的子项目networking-ovs-dpdk[7],在Mitaka版本,Neutron侧的代码全部合入主干[8],但该特性的CI仍然保留在networking-ovs-dpdk子项目。
本文以OpenStack最新发行版Ocata介绍该特性的实现,OS选用Ubuntu 16.04,由于该特性需要使用内存大页,服务器推荐至少8G内存,2块物理网卡,本实验使用的是Intel 82567网卡。

配置内存大页

传统的X86平台默认内存页大小为4K,可配置2MB,1GB 的内存大页,可参考[9]中相关说明,生产环境中需要根据实际需求来选择大页内存类型,例如在NFV场景,对虚拟机的性能有较高要求,宿主机的CPU和内存不开启复用,那么配置1GB的内存大页更合理,本实验使用2MB的内存大页。

挂载内存大页,并设置OS启动时自动挂在大页

 
1
2
3
4
# mkdir -p /dev/hugepages
# mount -t hugetlbfs none /dev/hugepages -o pagesize=2MB
# vi /etc/fstab
nodev /dev/hugepages hugetlbfs pagesize=2MB 0 0

重启OS

 
1
$ sudo reboot

验证大页是否挂载成功

绑定使用DPDK的网卡

安装DPDK

推荐使用源码编译安装DPDK[9],DPDK最新开发版本为17.02,最新稳定版本为16.11.1:

 
1
2
3
4
5
6
7
8
$ cd  /opt/dpdk
$ wget  http://fast.dpdk.org/rel/dpdk-16.07.tar.xz
$ tar xf dpdk-16.07.tar.xz
$ export DPDK_DIR="/opt/dpdk"
$ export DPDK_TARGET="x86_64-native-linuxapp-gcc"
$ export DPDK_BUILD="$DPDK_DIR/dpdk-16.07/$DPDK_TARGET"
$ cd $DPDK_DIR/dpdk-16.07
$ sudo make install T=$DPDK_TARGET DESTDIR=install

加载IGB_UIO驱动

编译好的DPDK中包括该驱动:

 
1
2
# modprobe uio
# insmod $DPDK_DIR/dpdk-16.07/x86_64-native-linuxapp-gcc/kmod/igb_uio.ko

绑定网卡

查询网卡的PCI号:

 
1
ethtool -i eth1 | grep bus-info

使用DPDK源码中提供的绑定脚本绑定网卡

 
1
python dpdk-devbind.py --bind=igb_uio 网卡PCI号

网卡绑定成功后如下图所示:

NEUTRON中相关配置

OPENVSWITCH-AGENT安装配置

openvswitch-agent安装时只会自动安装openvswitch,需要手动安装openvswitch-dpdk,推荐使用openvswitch的源码编译、安装,安装之前需要先停掉openvswitch服务。

 
1
# service openvswitch-switch stop

编译安装OPENVSWITCH

从官方下载openvswitch:http://openvswitch.org/download,本实验使用ovs 2.6.1版本

 
1
2
3
4
5
6
7
8
9
$ export OVS_DIR="/opt/ovs"
$ export  OVS_DB_PATH="/usr/local/etc/openvswitch"
$ export  OVS_DB_SOCK="/usr/local/var/run/openvswitch/db.sock"
$ tar xvf openvswitch-2.6.1.tar.gz
$ cd $OVS_DIR/openvswitch-2.6.1
$ ./boot.sh
$ ./configure --with-dpdk=$DPDK_BUILD
$ make
$ sudo make install

创建OVS 数据库

 
1
2
3
$ sudo mkdir -p $OVS_DB_PATH
$ sudo ovsdb-tool create $OVS_DB_PATH/conf.db \
/usr/local/share/openvswitch/vswitch.ovsschema

设置OVS使用的内存大页

可先查询各NUMA node上内存大页的使用情况,

 
1
2
$ cat /sys/devices/system/node/node*/meminfo|grep Huge
$ sudo ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-socket-mem="512,1"

启动OVS DB服务

 
1
2
3
4
$ sudo ovsdb-server --remote=punix:$OVS_DB_SOCK \
   --remote=db:Open_vSwitch,Open_vSwitch,manager_options \
   --pidfile –detach
sudo ovs-vsctl --db=unix:$OVS_DB_SOCK --no-wait init

设置ovs以DPDK的方式启动:

 
1
$ sudo ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true

添加物理网卡

物理网卡绑定DPDK驱动后才能被ovs-vswitchd发现:

在openvswitch2.7之前,物理网卡在openvswitch中的命名以dpdk开头:

 
1
$ sudo ovs-vsctl add-port br-eth1 dpdk0 -- set Interface dpdk0 type=dpdk

启动OVS-VSWITCHD

 
1
2
$ sudo ovs-vswitchd unix:$OVS_DB_SOCK \
--pidfile --detach --log-file=/var/log/openvswitch/ovs-vswitchd.log

创建DATAPATH类型为NETDEV的网桥

 
1
2
$ sudo ovs-vsctl add-br br-int -- set bridge br-int datapath_type=netdev
$ sudo ovs-vsctl add-br br-eth1 -- set bridge br-eth1 datapath_type=netdev

修改OPENVSWITCH-AGENT配置文件

在ovs标签下修改下面3个配置项:

 
1
2
3
4
[ovs]
datapath_type=netdev
vhostuser_socket_dir=/usr/local/var/run/openvswitch
bridge_mappings=dpdk:br-eth1(使用vlan类型网络配置该项)

重启openvswitch-agent服务

Nova中相关配置

创建带内存大页的flavor:

 
1
2
$ sudo openstack flavor create --id 3 --ram 64 --vcpus 1 hugepage
$ sudo openstack flavor set --property  hw:mem_page_size=large hugepage

基本功能验证

创建虚拟机

在Ocata版本之前,Neutron只支持vhost-user类型的port,Ocata实现了对vhost-user-client类型的port的支持[11]。
创虚拟机时,Neutron会根据openvswitch-agent上报openvswitch支持的interface type作端口绑定,在vhost-user-client和vhost-user都支持的情况下优先使用vhost-user-client。
虚拟机使用vhost-user port如下图所示:

虚拟机使用vhost-user-client port如下图所示:

可以通过查看端口的状态来检查虚拟机的网卡是否被Open vSwitch和QEMU正确处理:

虚拟机热迁移

经验证在Ocata版本Nova支持对带vhostuser类型网卡的虚拟机进行在线迁移。

支持的网络类型

经验证在Ocata 版本,Neutron中flat、vlan、vxlan类型的网络均支持vhostuser类型的port,如何配置使用vxlan网络可参考[12]。

安全组功能

当Open vSwitch使用DPDK后,使用iptables实现的安全组driver已经无法使用,但完全基于OpenFlow流表实现的安全组driver在Newton版本已经实现[13],修改openvswitch-agent的配置文件:

 
1
2
[securitygroup]
firewall_driver = openvswitch

经验证vhostuser类型port的安全组功能在Ocata版本基本可用,但还存在一些问题,例如计算节点上port较多时,Open vSwitch流表数量过多(社区已在做相关优化[15]),链接跟踪无法自动清除问题。

总结

通过上述实验可以看出,OpenStack的发展速度确实比较快,对Open vSwitch with DPDK的基本功能已经全部支持。本文只是验证了一下该特性的基本功能,后续会再做一下稳定性和性能相关测试,如何将该特性应用到生产环境会是我接下来研究的重点。

参考资料

1. http://dpdk.org/
2. https://launchpad.net/networking-vpp
3. http://openvswitch.org/releases/NEWS-2.4.0
4. https://docs.mirantis.com/openstack/fuel/fuel-9.1/nfv-guide/ovs-dpdk.html
5. http://docs.openvswitch.org/en/latest/topics/dpdk/vhost-user/#vhost-user-vs-vhost-user-client
6. https://blueprints.launchpad.net/nova/+spec/libvirt-vif-vhost-user
7. https://launchpad.net/networking-ovs-dpdk
8. https://review.openstack.org/#/c/237264/
9. http://docs.openvswitch.org/en/latest/intro/install/dpdk/
10. https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
11. https://bugs.launchpad.net/neutron/+bug/1604924
12. https://github.com/openvswitch/ovs/blob/master/Documentation/howto/userspace-tunneling.rst
13. https://docs.openstack.org/developer/neutron/devref/openvswitch_firewall.html
14. http://www.udpwork.com/item/12720.html
15. https://review.openstack.org/#/c/333804/

DPDK在OpenStack中的实现的更多相关文章

  1. OpenStack中Keystone的基本概念理解

    原文http://www.kankanews.com/ICkengine/archives/10788.shtml Keystone简介 Keystone(OpenStack Identity Ser ...

  2. openstack中eventlet使用

    openstack中使用eventlet的协程来实现并发. 第一种,使用eventlet.GreenPool来管理绿色线程 如l3-agent在开启了8个绿色线程来处理router消息 def _pr ...

  3. 探索 OpenStack 之(14):OpenStack 中 RabbitMQ 的使用

    本文是 OpenStack 中的 RabbitMQ 使用研究 两部分中的第一部分,将介绍 RabbitMQ 的基本概念,即 RabbitMQ 是什么.第二部分将介绍其在 OpenStack 中的使用. ...

  4. openstack中彻底删除计算节点的操作记录

    在使用openstack的过程中,我们经常会添加好几台计算节点来部署虚拟机,在后续使用中由于某些原因,一些计算节点出现了问题,需要将这些出了问题的计算节点从openstack的控制节点中踢出去!但是很 ...

  5. OpenStack中给wsgi程序写单元測试的方法

    在 OpenStack 中, 针对web应用, 有三种方法来写单元測试 1) 使用webob生成模拟的request from __future__ import print_function imp ...

  6. openstack中iptables的使用

    openstack中nova使用了iptables实现其网络相关功能,乍看openstack的iptables表比较复杂,整理了一下iptables的filter表和nat表的结构,以一个all in ...

  7. OpenStack中memcached的使用和实现

    概述 主要分享下个人对Liberty版本openstack中cache使用的理解,由于作者水平有限,难免有所错误,疏漏,还望批评指正. openstack中可以使用cache层来缓存数据,Libert ...

  8. openstack中的环境准备

    openstack中环境准备基于Ubuntu系统 author:headsen chen   2017-10-13  11:51:50 个人原创,转载请注明作者,出处. 6 apt-get insta ...

  9. OpenStack中部署glance的步骤

    OpenStack中部署glance的步骤(基于Ubuntu14.04系统) author:headsen  chen   2017-10-13   08:34:35 个人原创,转载请注明作者,出处, ...

随机推荐

  1. 巨蟒python全栈开发数据库前端5:JavaScript1

    1.js介绍&变量&基础数据类型 2.类型查询&运算符&if判断&for循环 3.while循环&三元运算符 4.函数 5.今日总结 1.js介绍&am ...

  2. soft deletion Google SRE 保障数据完整性的手段

    w http://www.infoq.com/cn/articles/GoogleSRE-BookChapter26 Google SRE 保障数据完整性的手段 就像我们假设Google 的底层系统经 ...

  3. CSRF Laravel

    Laravel 使得防止应用 遭到跨站请求伪造攻击变得简单. Laravel 自动为每一个被应用管理的有效用户会话生成一个 CSRF “令牌”,该令牌用于验证授权用 户和发起请求者是否是同一个人. 任 ...

  4. Python菜鸟之路:Django 数据验证之钩子和Form表单验证

    一.钩子功能提供的数据验证 对于数据验证,django会执行 full_clean()方法进行验证.full_clean验证会经历几个步骤,首先,对于model的每个字段进行正则验证,正则验证通过后, ...

  5. JsonResponse对象浅析

    JsonResponse   JsonResponse 对象: class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_ ...

  6. Python高级教程-生成器

    生成器(Generator) 通过列表生成式,可以直接创建一个列表.但是,受内存限制,列表的容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几 ...

  7. sql server等待类型

    sql server 各种等待类型-转 sql server各个等待类型及解决办法:https://www.sqlskills.com/help/waits/writelog/其他等待类型的描述和解决 ...

  8. Android Wear - Design Principles for Android Wear(设计原则)

    ---------------------------------------------------------------------------------------------------- ...

  9. 简述ODS,和数据仓库做简单的比较

    这两天看书,发现了和数据仓库相关的还有一个叫ODS的概念,它是企业级的全局数据库,用于提供集成的,企业级一致的数据,包含如何从各个子系统中向ODS抽取数据以及面向主题的角度存储数据. 它和数据仓库的主 ...

  10. 使用 10046 查看执行计划并读懂 trace 文件

    查看 sql 执行计划的方法有许多种, 10046 事件就是其中的一种. 与其他查看 sql 执行计划不同, 当我们遇到比较复杂的 sql 语句, 我们可以通过 10046 跟踪 sql 得到执行计划 ...