一、前言
在文章《DPDK系列之十一:容器云的数据通道加速》中提到,社区改进了virtio来支持基于DPDK的容器NFV或者上层应用。本文对于基于virtio-user(容器虚拟化网络前端)和vhost-user(容器虚拟化网络后端)与DPDK技术的结合进行分析:
转载自https://blog.csdn.net/cloudvtech
二、virtio-user对于容器内DPDK PMD的支持
在文章《DPDK系列之六:qemu-kvm网络后端的加速技术》中提到,virtio和vhost技术在虚拟机网络的前端和后端进行了一些改进,引入了内存共享机制,提供高性能的虚拟网络和IPC。virtio-user和vhost-user经过改进,可以支持虚拟机使用OVS-DPDK提供的dpdkvhostuser端口作为虚拟网卡:
/root/openvswitch-2.8.1/utilities/ovs-vsctl add-port br0 myportnameone -- set Interface myportnameone type=dpdkvhostuser
/root/qemu-2.11.0/x86_64-softmmu/qemu-system-x86_64 -m 1024 -smp 1 -hda ./centos.qcow2 -boot c -enable-kvm -no-reboot -net none -nographic \
-chardev socket,id=char1,path=/usr/local/var/run/openvswitch/myportnameone \
-netdev type=vhost-user,id=mynet1,chardev=char1,vhostforce \
-device virtio-net-pci,mac=00:00:00:00:00:01,netdev=mynet1 \
-object memory-backend-file,id=mem,size=1G,mem-path=/dev/hugepages,share=on \
-numa node,memdev=mem -mem-prealloc \
-vnc :1 --enable-kvm \
-netdev tap,id=tapnet,ifname=vnet0,script=no -device rtl8139,netdev=tapnet,mac=52:54:00:12:34:58
virtio本质上是一个基于内存共享的包收发机制。在虚拟机环境中,qemu-kvm将整个虚拟机的物理内存分布共享给vhost后端;而在容器环境中,由于容器是一个进程,只能共享部分由DPDK初始化的hugepage内存给后端vhost,所以容器的virio DPDK也只有借助这个区域进行基于共享内存的数据包收发,virtio对于容器内DPDK支持的主要改动也就在这边。最终目的就是virtio-user能虚拟出一个能够被容器内DPDK所管控的para-virtualization PCI设备。经过改进后的virtio在容器模式内可将以如下方式加速容器数据通路:
容器内的DPDK PMD借助这个改进的virtio-user直接使用宿主机上OVS-DPDK建立的dpdkvhostuser port作为其端口(对应的unix socket file用于进行控制面消息交互):
docker run -i -t -v /tmp/sock0:/var/run/usvhost \ -v /dev/hugepages:/dev/hugepages \ dpdk-app-testpmd testpmd -l 6-7 -n 4 -m 1024 --no-pci \ --vdev=virtio_user0,path=/var/run/usvhost \ --file-prefix=container \ -- -i --txqflags=0xf00 --disable-hw-vlan
更详细的关于virtio对于容器内DPDK的支持可以参见如下链接:
转载自https://blog.csdn.net/cloudvtech
三、vhost-user对OVS-DPDK的支持
在OVS DPDK中,可以建立两种方式的DPDK port,type分别是dpdk和dpdkvhostuser/dpdkvhostuserclient
3.1 OVS port type=dpdk
这种方式的DPDK port可以用如下命令建立:
ovs-vsctl add-port br0 dpdk-p0 -- set Interface dpdk-p0 type=dpdk options:dpdk-devargs=0000:01:00.0
这个port需要对应某个PCI设备,这个PCI设备就是使用DPDK工具脚本所绑定的基于UIO驱动的网卡
3.2 OVS port type=dpdkvhostuser/dpdkvhostuserclient
dpdkvhostuser和dpdkvhostuserclient是同一种方式的两个模式,通过如下命令可以实现:
ovs-vsctl add-port br0 vhost-user-1 -- set Interface vhost-user-1 \
type=dpdkvhostuser
ovs-vsctl add-port br0 dpdkvhostclient0 \
-- set Interface dpdkvhostclient0 type=dpdkvhostuserclient \
options:vhost-server-path=/tmp/dpdkvhostclient0
这两种方式的区别在于在进行控制面消息沟通的时候,是QEMU和OVS谁作为server谁作为client,以及在出错时候的不同行为模式:
这样建立的port是基于vhost-user后端并支持DPDK的OVS port,这个port在OVS DPDK所在的系统中会有一个socket对应,这个socket可以传输给容器或者虚拟机以供里面的virtio PMD使用,进行控制面消息传递。
建立dpdkvhostuser port并给虚拟机使用的例子如下:
OVS建立port命令
ovs-vsctl add-port br0 vhost-user-1 -- set Interface vhost-user-1 \
type=dpdkvhostuser
Qemu启动命令
-chardev socket,id=char1,path=/usr/local/var/run/openvswitch/vhost-user-1
-netdev type=vhost-user,id=mynet1,chardev=char1,vhostforce
-device virtio-net-pci,mac=00:00:00:00:00:01,netdev=mynet1
建立dpdkvhostuser port并给容器使用的例子如下:
ovs-vsctl add-port br0 vhost-user0 -- set Interface vhost-user0 type=dpdkvhostuser
ovs-vsctl add-port br0 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuser
docker run -ti --privileged \
-v /mnt/huge:/mnt/huge \
-v /usr/local/var/run/openvswitch:/var/run/openvswitch \
$DOCKER_TAG
容器内启动PMD并使用OVS-DPDK port的命令
export DPDK_PARAMS="-c 0x19 --master-lcore 3 -n 1 --socket-mem 1024 \
--file-prefix pktgen --no-pci \
--vdev=virtio_user0,mac=00:00:00:00:00:00,path=/var/run/openvswitch/vhost-user0 \
--vdev=virtio_user1,mac=00:00:00:00:00:01,path=/var/run/openvswitch/vhost-user1 "
export PKTGEN_PARAMS='-T -P -m "0.0,4.1"'
./app/app/$DPDK_BUILD/pktgen $DPDK_PARAMS -- $PKTGEN_PARAMS
这里virtio_user0和virtio_user1都是满足DPDK参数格式的,virtio_user表示使用的驱动,0和1表示设备ID:
3.3 为DPDK port建立OVS流表
通过为dpdk类型port、dpdkvhostuser/dpdkvhostusercleint类型port之间建立流表,可以使得数据在这些port之间转发;如果为两个dpdkvhostuser port建立流表,则可以实现东西向的高速通道,如果为dpdk port和dpdkvhostuser port建立流表,可以建立南北向高速通道。具体可以参见OVS关于这部份功能的文档。
转载自https://blog.csdn.net/cloudvtech