隨着雲計算與大數據的快速發展,其對數據中心網絡的性能和管理提出了更高的要求,但傳統雲計算架構存在多個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/