Open vSwitch(OVS)使用DPDK

在部署openstack的官方文档(最近几个版本)中的neutron组件默认使用的是linux bridge来做网桥,除直接使用提供者网络(provider network)以外,网络节点的负载会比较大,所有的外部网络通信流量都要走网络节点,于是就看了看Juno版本以后增加的 DVR(分布式虚拟路由器),有了 DVR 之后,路由变成了分布式,每个计算节点上面都可以做路由,东西向流量直接通过计算节点路由而不需要经过网络节点,Floating IP 也是在计算节点上面实现的,对于有 floating IP 的 VM 访问公网,直接走计算节点上面的路由器出去,对于没有 floating IP 的 VM 访问公网才会从网络节点的路由器 SNAT 出去。

看来看去,想起来几年前,我比较熟悉的OVS(Open vSwitch),于是打开官网看了看,更新还真不少,搞出来了个OVN,OVN 是 OVS 的控制平面,它给 OVS 增加了对虚拟网络的原生支持,用在openstack上的话,相当于它干了大部分以前neutron agent干的活,计算节点不在需要部署neutron agent了,OVN全搞定,neutron只需要调用OVN的北向接口,其它的事都交给OVN来搞定,应该说是彻底解放了neutron,具体的安装配置可以参考:https://docs.openstack.org/networking-ovn/latest/。

在看OVS文档过程中,看到了一个DPDK的东东,完全不懂,于是就研究一下,在这里把整个过程记录下来,和大家分享一下。

DPDK

DPDK(Data Plane Development Kit),是一组快速处理数据包的开发平台及接口,运行于Intel X86平台上(最新版本也开始支持PowerPC和ARM)。

在X86结构中,处理数据包的传统方式是CPU中断方式,既网卡驱动接收到数据包后通过中断通知CPU处理,然后由CPU拷贝数据并交给协议栈。在数据量大时,这种方式会产生大量CPU中断,导致CPU无法运行其他程序。而DPDK则采用轮询方式实现数据包处理过程:DPDK重载了网卡驱动,该驱动在收到数据包后不中断通知CPU,而是将数据包通过零拷贝技术存入内存,这时应用层程序就可以通过DPDK提供的接口,直接从内存读取数据包。这种处理方式节省了CPU中断时间、内存拷贝时间,并向应用层提供了简单易行且高效的数据包处理方式,使得网络应用的开发更加方便。但是DPDK需要网卡支持,目前以intel的网卡为主,想要知道您的网卡是否支持,可以到DPDK的官网查询:http://dpdk.org。

怎么样,是不是很高大尚?要不要写个程序通过DPDK提供的接口来读取数据包?呵呵,说句实话,这对我来说目前还有一定难度,在这里就暂时不给大家show了,如果有兴趣的话,DPDK的源代码里有helloworld,还有一些其它的sample。

DPDK + OVS

我们再回到OVS上来,OVS是目前得到广泛认可的一个软件虚拟交换机,目前已经实现了通过DPDK的接口从内存直接读取数据包,然后在软件层再进行各种转发……,这应该是充分发挥了DPDK的优势,相信速度也会得到明显的改善(别高兴太早)。下面我就把我在Mac+virtualbox环境下的整个安装、调试过程和大家分享一下。

基础环境准备

如果您有硬件环境,那么建议您还是使用两台物理服务器来进行测试,要求是内存至少要2G以上,网卡需要支持DPDK,可以到DPDK的官网查询:http://dpdk.org查询您的网卡是否支持。
怎么样知道你的网卡型号呢? 很简单,打开机盖看,哈哈。

当然也有不打开机盖的方法,安装完操作系统(centos)后,执行lspci,应该就能看到你的网卡的具体型号了。

如果没有硬件怎么办? 当然是万能的虚拟机了,本文中将使用virtualbox来创建两台虚拟机进行测试,为了达到相关的要求,建议你的机器内存>=8G。

网络:需要用到3个Host-Only网络,在virtualbox上提前创建好。


Open vSwitch(OVS)使用DPDK_第1张图片
network_3.jpg

网络名分别为: vboxnet0、vboxnet1、vboxnet2三个,它们对应的网络为:

vboxnet0: 192.168.56.1/24
vboxnet0: 192.168.57.1/24
vboxnet0: 192.168.58.1/24

如下所示:

Open vSwitch(OVS)使用DPDK_第2张图片
network_detail.jpg

虚拟机配置:

cpu 2c 内存2G 硬盘8G

创建完虚拟机后,进入网络设置界面:

Open vSwitch(OVS)使用DPDK_第3张图片
ifsetting.jpg

网卡1-3设置相同,分别选择vboxnet0、vboxnet1、vboxnet2。

特别特别要注意的是:控制芯片一定要选择82545EM,混杂模式一定要全部允许

请在看一遍上面的文字,别怪我没提醒你。

网卡4主要用于上外网,因此选择"网络地址转换(NAT)"即可,如下图所示:

Open vSwitch(OVS)使用DPDK_第4张图片
ifnat.jpg

最后“OK”保存,开始安装你的centos吧,安装过程中不需要创新新用户,给root设置一个密码,这些过程就不写了,如果没搞过自己琢磨吧。

至此,假设你的centos7已经安装完成。

网络配置

网卡1用于做管理使用,配置固定IP,如下:

TYPE=Ethernet
BOOTPROTO=static
IPADDR=192.168.56.160
NETMASK=255.255.255.0
GATEWAY=192.168.56.1
DEFROUTE=no
NAME=enp0s17
DEVICE=enp0s17
ONBOOT=yes

网卡2和3暂时不用动.

网卡4主要用于上外网,配置成自动获取IP、默认路由、默认启动,如下所示:

TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=enp0s10
UUID=2a07d19e-5811-45c9-abd0-d6134386b4b2
DEVICE=enp0s10
ONBOOT=yes

编译安装DPDK

安装前执行下面的命令将操作系统升级到最新版本:

yum update

执行下命的命令安装编译所需的依赖:

yum install rpm-build autoconf automake libtool systemd-units openssl openssl-devel python2-devel python3-devel python2 python2-twisted python2-zope-interface python2-six python2-sphinx desktop-file-utils groff graphviz procps-ng checkpolicy selinux-policy-devel kernel-devel python-sphinx python-twisted-core python-zope-interface libcap-ng-devel kernel-devel

然后下载当前稳定版本的源代码,并解压:

cd /usr/src

wget http://fast.dpdk.org/rel/dpdk-17.05.2.tar.xz

tar xf dpdk-17.05.2.tar.xz

设置环境变量,将以下内容增加到~/.bash_profile文件:

export DPDK_DIR=/usr/src/dpdk-stable-17.05.2
export DPDK_TARGET=x86_64-native-linuxapp-gcc
export DPDK_BUILD=$DPDK_DIR/$DPDK_TARGET

执行下命的命令进行编译:

source ~/.bash_profile

cd dpdk-stable-17.05.2

make install T=x86_64-native-linuxapp-gcc

由于DPDK需要将数据包从网卡直接拷贝到内存,因此需要调整内存页大小和页数,以提高内存使用效率。

编辑/etc/default/grub文件,将下面的内容加到引导启动项GRUB_CMDLINE_LINUX:

default_hugepagesz=2m hugepagesz=2m hugepages=512 iommu=pt intel_iommu=on

执行如下命令写入引导项:

grub2-mkconfig -o /boot/grub2/grub.cfg

编辑/etc/fstab,在最后增加如下内容,在系统启动时挂载大内存页。

nodev /mnt/huge hugetlbfs defaults 0 0

执行如下命令创建挂载点:

mkdir -p /mnt/huge

编译安装Open vSwitch

执行如下命令编译安装OVS:

cd /usr/src/

wget http://openvswitch.org/releases/openvswitch-2.8.1.tar.gz

tar -zxvf openvswitch-2.8.1.tar.gz

chown -R root:root openvswitch-2.8.1

cd openvswitch-2.8.1/

./boot.sh

./configure --with-dpdk=$DPDK_BUILD

make install

为了方便我们后面的配置,把主机名改为ovs1。

编辑/etc/hostname即可。

执行reboot重启机器。

复制虚拟机

为了我们能够测试两个虚拟机间的传输性能,我们需要使用virtualbox复制一台一样的虚拟机,复制的时候记得选择“网卡重新初始化选项”。复制完成后进行如下更改:
1、将网卡1的IP配置成192.168.56.161。
2、将hostname改为ovs2。

所有配置完成后,启动ovs1和ovs2。

创建虚拟网桥(分别在ovs1和ovs2上执行)

重启机器后执行如下命令将编译好的dpdk驱动加载到系统内核:

modprobe uio
insmod $DPDK_BUILD/kmod/igb_uio.ko

执行如下命令查看当前网卡绑定的情况:

$DPDK_DIR/usertools/dpdk-devbind.py --status

结果如下:

Network devices using DPDK-compatible driver
============================================


Network devices using kernel driver
===================================
0000:00:07.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=enp0s7 drv=e1000 unused= *Active*
0000:00:08.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=enp0s8 drv=e1000 unused=
0000:00:09.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=enp0s9 drv=e1000 unused=
0000:00:0a.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=enp0s10 drv=e1000 unused= *Active*

Other Network devices
=====================


Crypto devices using DPDK-compatible driver
===========================================

可以看到我们的4张网卡目前都是使用默认的e1000驱动。

执行如下命令,将第二张网卡绑定到dpdk驱动:

$DPDK_DIR/usertools/dpdk-devbind.py --bind=igb_uio 0000:00:08.0

再次执行$DPDK_DIR/usertools/dpdk-devbind.py --status结果如下:

Network devices using DPDK-compatible driver
============================================
0000:00:08.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' drv=igb_uio unused=

Network devices using kernel driver
===================================
0000:00:07.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=enp0s7 drv=e1000 unused= *Active*
0000:00:09.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=enp0s9 drv=e1000 unused=igb_uio
0000:00:0a.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=enp0s10 drv=e1000 unused=igb_uio *Active*

Other Network devices
=====================

可以看到第二块网卡已经使用了DPDK驱动。

OK,DPDK到此大功告成。

启动OVS:

export PATH=$PATH:/usr/local/share/openvswitch/scripts
ovs-ctl start

启动过程如下:

Starting ovsdb-server [ OK ]
system ID not configured, please use --system-id ... failed!
Configuring Open vSwitch system IDs [ OK ]
Inserting openvswitch module [ OK ]
Starting ovs-vswitchd Zone 0: name:, phys:0x7f9cecc0, len:0x30100, virt:0x7f1366dcecc0, socket_id:0, flags:0
[ OK ]
Enabling remote OVSDB managers

为什么我们要4张网卡? 除了1张用于管理,1张用于上外网,另外两张主要用于对比测试,第二张192.168.57.1/24网段使用dpdk驱动,第三张192.168.58.1/24使用普通网络。现在我们就创建两个网桥br0和br1,分别将第二张网卡加入到br0、第三张网卡加入到br1。

首先对ovs进行dpdk初始化配置:

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

创建br0,将第二张网卡以DPDK设备形式加入到br0:

ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev
ovs-vsctl add-port br0 myportnameone -- set Interface myportnameone type=dpdk options:dpdk-devargs=0000:00:08.0

0000:00:08.0为第二张网卡的ID。

创建br1,将第三张网卡加入到br1:

ovs-vsctl add-br br1
ovs-vsctl add-port br1 enp0s9

执行ovs-vsctl show查看网桥配置情况如下:

c81a1a9a-ebfc-4aab-a008-24697f1ff1ca
Bridge "br0"
Port myportnameone
Interface myportnameone
type: dpdk
options: {dpdk-devargs="0000:00:08.0"}
Port "br0"
Interface "br0"
type: internal
Bridge "br1"
Port "br1"
Interface "br1"
type: internal
Port "enp0s9"
Interface "enp0s9"
ovs_version: "2.8.1"

上面的过程在ovs1和ovs2上完全相同,下过分别给两个网桥配置ip。

在ovs1上,执行如下命令给br0和br1设置IP:

ifconfig br0 192.168.57.10/24 up

ifconfig br1 192.168.58.10/24 up

在ovs2上,执行如下命令给br0和br1设置IP:

ifconfig br0 192.168.57.11/24 up

ifconfig br1 192.168.58.11/24 up

配置完成后,在ovs1上应该通直接ping通 192.168.57.11 和 192.168.58.11

网速测试

我们使用iperf进行网速测试,在两台虚拟机上安装iperf:

yum install iperf

在ovs1上关闭防火墙启动服务端:

systemctl stop firewalld.service

iperf -s -i 1

在ovs2上执行如下命令分别测试两条链路的网速:

iperf -t 10 -i 1 -c 192.168.57.10

iperf -t 10 -i 1 -c 192.168.58.10

结果如下:

[root@ovs2 ~]# iperf -t 10 -i 1 -c 192.168.57.10
------------------------------------------------------------
Client connecting to 192.168.57.10, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.57.11 port 46748 connected with 192.168.57.10 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0- 1.0 sec 16.2 MBytes 136 Mbits/sec
[ 3] 1.0- 2.0 sec 19.2 MBytes 161 Mbits/sec
[ 3] 2.0- 3.0 sec 19.2 MBytes 161 Mbits/sec
[ 3] 3.0- 4.0 sec 19.1 MBytes 160 Mbits/sec
[ 3] 4.0- 5.0 sec 17.5 MBytes 147 Mbits/sec
[ 3] 5.0- 6.0 sec 18.4 MBytes 154 Mbits/sec
[ 3] 6.0- 7.0 sec 18.6 MBytes 156 Mbits/sec
[ 3] 7.0- 8.0 sec 17.8 MBytes 149 Mbits/sec
[ 3] 8.0- 9.0 sec 17.8 MBytes 149 Mbits/sec
[ 3] 9.0-10.0 sec 17.5 MBytes 147 Mbits/sec
[ 3] 0.0-10.0 sec 181 MBytes 152 Mbits/sec
[root@ovs2 ~]# iperf -t 10 -i 1 -c 192.168.58.10
------------------------------------------------------------
Client connecting to 192.168.58.10, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[ 3] local 192.168.58.11 port 53078 connected with 192.168.58.10 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0- 1.0 sec 158 MBytes 1.33 Gbits/sec
[ 3] 1.0- 2.0 sec 146 MBytes 1.23 Gbits/sec
[ 3] 2.0- 3.0 sec 147 MBytes 1.23 Gbits/sec
[ 3] 3.0- 4.0 sec 162 MBytes 1.36 Gbits/sec
[ 3] 4.0- 5.0 sec 153 MBytes 1.29 Gbits/sec
[ 3] 5.0- 6.0 sec 119 MBytes 998 Mbits/sec
[ 3] 6.0- 7.0 sec 135 MBytes 1.13 Gbits/sec
[ 3] 7.0- 8.0 sec 117 MBytes 980 Mbits/sec
[ 3] 8.0- 9.0 sec 168 MBytes 1.41 Gbits/sec
[ 3] 9.0-10.0 sec 161 MBytes 1.35 Gbits/sec
[ 3] 0.0-10.0 sec 1.43 GBytes 1.23 Gbits/sec

怎么样? 结果是不是很惊人?

总结

为什么? 为什么? 为什么?为什么使用dpdk驱动的速度会比普通网卡的速度慢那么多呢?只有普通网卡的1/10,理论和实践为什么差距辣么大?

我个人认为可能是由于我的环境所致,本身虚拟机才2G内存,数据传输完成后,OVS还要进行大量的数据包处理,虚拟机cpu性能也不是很强,才会出现这样的局面,这和我的预想完全相反,整个人感觉这几天的工夫白花了。

当然,也可能是某些地方配置不对,希望各位指正。

后续工作

现在需要在物理环境进行测试,但看了一下我手里的服务器网卡都不支持DPDK,特在此向各位征集网卡2张,要求intel的,并且支持dpdk。

如果谁有可以和我联系,微信: cj_zhao, 1周内测试完成,原样寄回,谢谢!


如果您喜欢我的作品,欢迎点赞、打赏、关注。
请我吃个雪糕……

你可能感兴趣的:(Open vSwitch(OVS)使用DPDK)