一、Dpdk简介
Dpdk是X86平台报文快速处理的库和驱动的集合,不是网络协议栈,不提供二层,三层转发功能,不具备防火墙ACL功能,但通过DPDK可以轻松的开发出上述功能。优势在于通过Dpdk,可以将用户态的数据,不经过内核直接转发到网卡,实现加速目的。主要架构如图1.1所示。在intel的大力发展下,Dpdk已经基本建立了自己的生态系统,比较完善的文档以及各种开发范例都可以在http://www.dpdk.org/下载到,目前最新的发行版本是V16.01。
图1.1
二、Ovs+Dpdk编译与安装
目前Ovs的最新发行版版本为v2.5.0,根据Ovs的官方文档,由于Qemu早期版本不支持vhost-usertype,所以qemu版本必须在v2.1以上。虽然qemu版本更新很快,但是我们测试机器采用的是Centos7.1系统,Centos官方升级包中支持的qemu版本较低,所以我们使用了符合要求的较低版本Qemuv2.2以防止出现新的问题。Qemu编译安装时间比较长,需要提前去qemu官网下载对应版本,并安装。
Step1:下载Ovs和Dpdk相关版本
wgethttp://openvswitch.org/releases/openvswitch-2.5.0.tar.gz
wgethttp://www.dpdk.org/browse/dpdk/snapshot/dpdk-16.04.tar.gz
Step2:清理环境,因为Ovs+Dpdk,需要Ovs在编译时link到Dpdk的lib库,所以如果环境原来已经安装有Ovs,也需要先卸载掉,重新编译安装。
Step3:编译Dpdk
修改配置文件config/common_linuxapp,这里我们测试vhost模式,所以需要把下面两个配置项,配置为yes。
CONFIG_RTE_BUILD_COMBINE_LIBS=y CONFIG_RTE_LIBRTE_VHOST=y
|
CONFIG_RTE_BUILD_COMBINE_LIBS
=
y
CONFIG_RTE_LIBRTE_VHOST
=
y
|
Step 4:安装Dpdk
新建一个安装目录 mkdir -p /usr/src/dpdk
make installT=x86_64-native-linuxapp-gcc DESTDIR=/usr/src/dpdk
|
make
installT
=
x86_64
-
native
-
linuxapp
-
gcc
DESTDIR
=
/
usr
/
src
/
dpdk
|
Step 5:编译相关模块
cd /home/dpdk-16.04/rte_vhost/eventfd_link make
|
cd
/
home
/
dpdk
-
16.04
/
rte_vhost
/
eventfd_link
make
|
Step 6:安装ovs
./boot.sh ./configure --with-dpdk=/home/ dpdk-16.04/x86_64-native-linuxapp-gcc CFLAGS="-g -O2 -Wno-cast-align" make && make install
|
.
/
boot
.sh
.
/
configure
--
with
-
dpdk
=
/
home
/
dpdk
-
16.04
/
x86_64
-
native
-
linuxapp
-
gcc
CFLAGS
=
"-g -O2 -Wno-cast-align"
make
&&
make
install
|
Step7:安装相关内核模块
modprobe uio insmod /home/dpdk-16.04/x86_64-native-linuxapp-gcc/kmod/igb_uio.ko insmod /home/dpdk-16.04/lib/librte_vhost/eventfd_link/eventfd_link.ko
|
modprobe
uio
insmod
/
home
/
dpdk
-
16.04
/
x86_64
-
native
-
linuxapp
-
gcc
/
kmod
/
igb_uio
.ko
insmod
/
home
/
dpdk
-
16.04
/
lib
/
librte_vhost
/
eventfd_link
/
eventfd_link
.ko
|
三、环境准备
Step1:启动namespace ovs
mkdir -p /usr/local/etc/openvswitch mkdir -p /usr/local/var/run/openvswitch rm /usr/local/etc/openvswitch/conf.db /usr/local/bin/ovsdb-tool create /usr/local/etc/openvswitch/conf.db \ /usr/local/share/openvswitch/vswitch.ovsschema /usr/local/sbin/ovsdb-server --remote=punix:/usr/local/var/run/openvswitch/db.sock \ --remote=db:Open_vSwitch,Open_vSwitch,manager_options \ --private-key=db:Open_vSwitch,SSL,private_key \ --certificate=Open_vSwitch,SSL,certificate \ --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert --pidfile --detach /usr/local/bin/ovs-vsctl --no-wait init
1
2
3
4
5
6
7
8
9
10
11
12
13
|
mkdir
-
p
/
usr
/
local
/
etc
/
openvswitch
mkdir
-
p
/
usr
/
local
/
var
/
run
/
openvswitch
rm
/
usr
/
local
/
etc
/
openvswitch
/
conf
.db
/
usr
/
local
/
bin
/
ovsdb
-
tool
create
/
usr
/
local
/
etc
/
openvswitch
/
conf
.db
\
/
usr
/
local
/
share
/
openvswitch
/
vswitch
.ovsschema
/
usr
/
local
/
sbin
/
ovsdb
-
server
--
remote
=
punix
:
/
usr
/
local
/
var
/
run
/
openvswitch
/
db
.sock
\
--
remote
=
db
:
Open_vSwitch
,
Open_vSwitch
,
manager
_options
\
--
private
-
key
=
db
:
Open_vSwitch
,
SSL
,
private
_key
\
--
certificate
=
Open_vSwitch
,
SSL
,
certificate
\
--
bootstrap
-
ca
-
cert
=
db
:
Open_vSwitch
,
SSL
,
ca_cert
--
pidfile
--
detach
/
usr
/
local
/
bin
/
ovs
-
vsctl
--
no
-
wait
init
|
Step2:配置hugepage
1)查看当前hugepage配置
cat /proc/meminfo | grep -i huge
|
cat
/
proc
/
meminfo
|
grep
-
i
huge
|
2)修改hugepage页数为1024
echo 1024 > /proc/sys/vm/nr_hugepages
|
echo
1024
>
/
proc
/
sys
/
vm
/
nr_hugepages
|
3)挂载
mount -t hugetlbfs none /dev/hugepages
|
mount
-
t
hugetlbfs
none
/
dev
/
hugepages
|
Step3:启动dpdk和ovs
/usr/local/sbin/ovs-vswitchd--dpdk -c 0x1 -n 4 --socket-mem 400,400 --unix:/usr/local/var/run/openvswitch/db.sock --pidfile –detach
|
/
usr
/
local
/
sbin
/
ovs
-
vswitchd
--
dpdk
-
c
0x1
-
n
4
--
socket
-
mem
400
,
400
--
unix
:
/
usr
/
local
/
var
/
run
/
openvswitch
/
db
.sock
--
pidfile
–
detach
|
这里socket-mem400,400的含义是,在socket0和socket1上分别分配400MB的内存给dpdk使用。
Step4:将网口绑定为Dpdk设备
在/Dpdk/tools目录下,有一个网口绑定工具,使用这个工具可以将eth设备绑定为Dpdk设备(绑定的目的是修改网口的驱动)
dpdk_nic_bind.py --bind=igb_uio eth1
使用这个工具也可以查看当前网卡驱动的绑定情况,图2.1中显示,两个82599ES网口一个使用内核驱动,一个使用DPDK驱动。
图2.1
四、简单测试
测试环境选择在两台物理机上分别通过Dpdk网口,创建两台虚拟机,使用netperf工具来测试两台虚拟机之间的网络性能。Ovs+Dpdk和Ovs本身之间的区别可以由图3.1简单来表示。
图3.1
虚拟机以及Dpdk的bridge和port之间的结构如图3.2所示:
图3.2
先通过ovs命令,创建相关bridge和port:
ovs-vsctl add-br br-tun -- set bridge br-tundatapath_type=netdev ovs-vsctl add-port br-tun vhost-user-1 -- set interface vhost-user-1 type=dpdkvhostuser ofport_request=1 ovs-vsctl add-port br-tun vxlan-1 -- set interface vxlan-1 type=vxlan ofport_request=100 options:remote_ip=7.0.0.2 ovs-vsctl add-br br_int-- set bridge br_int datapath_type=netdev ovs-vsctl add-port br_int dpdk0 -- set interface dpdk0 type=dpdk ofport_request=1
|
ovs
-
vsctl
add
-
br
br
-
tun
--
set
bridge
br
-
tundatapath_type
=
netdev
ovs
-
vsctl
add
-
port
br
-
tun
vhost
-
user
-
1
--
set
interface
vhost
-
user
-
1
type
=
dpdkvhostuser
ofport_request
=
1
ovs
-
vsctl
add
-
port
br
-
tun
vxlan
-
1
--
set
interface
vxlan
-
1
type
=
vxlan
ofport_request
=
100
options
:
remote_ip
=
7.0.0.2
ovs
-
vsctl
add
-
br
br_int
--
set
bridge
br_int
datapath_type
=
netdev
ovs
-
vsctl
add
-
port
br_int
dpdk0
--
set
interface
dpdk0
type
=
dpdk
ofport_request
=
1
|
在bridge和port创建好以后,ip addr命令的相关网口部分如下:
36: br0: mtu 1500 qdisc pfifo_fast state UNKNOWNqlen 500
link/ether 16:8e:6a:b6:4f:44 brdff:ff:ff:ff:ff:ff
inet 6.0.0.101/24 brd 6.0.0.255 scopeglobal br0
valid_lft forever preferred_lft forever
inet6 fe80::148e:6aff:feb6:4f44/64 scopelink
valid_lft forever preferred_lft forever
37: br1: mtu 1500 qdisc pfifo_fast state UNKNOWNqlen 500
link/ether ec:f4:bb:e9:2b:4a brdff:ff:ff:ff:ff:ff
inet7.0.0.1/24 brd 7.0.0.255 scope global br1
valid_lft forever preferred_lft forever
inet6 fe80::eef4:bbff:fee9:2b4a/64 scopelink
valid_lft forever preferred_lft forever
通过ovs创建的bridge和port如图3.2下:
图3.2
Dpdk相关port创建好以后,一个简单的方法可以判断一下Dpdk端口是否创建成功,如果成功,通过top命令可以看到/usr/local/sbin/ovs-vswitchd进程的cpu使用率会一直保持在100%。
两台物理机上采用相同的方式来配置bridge和port。然后启动虚拟机。在Ovs的官方文档中,虚拟机的启动都是采用命令的方式,在命令中进行相关参数的配置。类似下面这样的:
qemu-system-x86_64 -enable-kvm -m 1024 -smp 2-chardev socket,id=char0,path=/usr/local/var/run/openvswitch/vhost-user-1-netdev type=vhost-user,id=mynet1,chardev=char0,vhostforce -devicevirtio-net-pci,netdev=mynet1,mac=52:54:00:02:d9:05 -objectmemory-backend-file,id=mem,size=1024M,mem-path=/dev/hugepages,share=on -numanode,memdev=mem -mem-prealloc -net user, -net nic /home/test3.qcow2 -vnc0.0.0.0:30
|
qemu
-
system
-
x86_64
-
enable
-
kvm
-
m
1024
-
smp
2
-
chardev
socket
,
id
=
char0
,
path
=
/
usr
/
local
/
var
/
run
/
openvswitch
/
vhost
-
user
-
1
-
netdev
type
=
vhost
-
user
,
id
=
mynet1
,
chardev
=
char0
,
vhostforce
-
devicevirtio
-
net
-
pci
,
netdev
=
mynet1
,
mac
=
52
:
54
:
00
:
02
:
d9
:
05
-
objectmemory
-
backend
-
file
,
id
=
mem
,
size
=
1024M
,
mem
-
path
=
/
dev
/
hugepages
,
share
=
on
-
numanode
,
memdev
=
mem
-
mem
-
prealloc
-
net
user
,
-
net
nic
/
home
/
test3
.qcow2
-
vnc0
.
0.0.0
:
30
|
很多人喜欢使用xml文件的方式来启动虚拟机。这种命令转换为xml文件也很简单,可以使用qemu commands的方式:
|
<
qemu
:
commandline
>
<
qemu
:
arg
value
=
'-enable-kvm'
/
>
<
qemu
:
arg
value
=
'-chardev'
/
>
<
qemu
:
arg
value
=
'socket,id=char0,path=/usr/local/var/run/openvswitch/vhost-user-1'
/
>
<
qemu
:
arg
value
=
'-netdev'
/
>
<
qemu
:
arg
value
=
'type=vhost-user,id=mynet1,chardev=char0,vhostforce'
/
>
|
因为使用了Dpdk,数据包从虚拟机出来以后,直接送到了物理网卡,不经过内核,所以常规的Tcpdump抓包工具无法奏效。这里我们可以使用Ovs的dummy模块进行镜像抓包。根据抓包结果来确定是否真正的走了vxlan协议。
图3.3是使用Dpdk和不使用Dpdk网络性能对比情况,明显可以看出,使用Dpdk以后,网络性能有了显著提高,特别是TCP_CRR这种应用,性能提高了10倍以上。
图3.3
四、问题
Ovs+Dpdk实际使用中的问题,主要来源于两个方面。一方面由于Dpdk+Ovs涉及到kernel、Qemu、Ovs、Libvirt等不同项目,各个模块都存在bug,比如Ovs的watchdog crash问题、Qemu中关于vhost socket断开以后,需要重启虚拟机才能恢复正常的问题、Dpdk使用了huagepage,当系统内存使用紧张时,会出现虚拟机网络延时变大的问题,以及GCC编译器版本不同带来的Ovs程序crash问题等等。虽然Ovs项目中正式纳入Dpdk时间已经比较长,但是真正在生产环境部署,还有很多问题需要解决。另一方面由于Ovs天生的性能方面的缺陷,当集群规模非常大的时候,Ovs性能迅速下降。今年由思科,爱立信以及intel主导的开源项目Vpp+Dpdk(https://fd.io/)横空出世,基本解决了Ovs的性能瓶颈问题。Vpp是思科一项成熟技术(目前Ovs拥有的功能,Vpp基本都有),通过和Dpdk的结合,在性能方面带来了质的提升。图4.1是思科提供给的一些测试数据,随着routes增加Vpp+Dpdk能做到性能不下降,而Ovs+Dpdk性能会出现急剧下降。
图4.1
五、展望
实验室中的测试相对简单,从测试到生产环境,还有很多的路需要走。特别是Dpdk作为一个新生事物,Ovs+Dpdk如何跟Openstack,以及nova、neutron的结合、网络复杂以后,各port的mtu值如何来设定、libvirtd中qemu commands格式的xml文件如何转换为适合openstack使用的xml文件格式、Dpdk资源池的大小该设为多少等等我们都做了一些探索性工作,这些工作我们会在后期和大家逐步分享。
来源:JD南京研发