在Docker中執行DPDK
版本
Docker:1.12.1
DPDK:16.07
Docker的安裝
在Ubuntu中docker的安裝還是很簡單的。參考官方文件1就行了。需要注意的是隻能在64位,linux版本號不低於3.11.0-15-generic
的發行版上執行。所以在OpenVZ的VPS上不能執行。
製造DPDK的Docker映象
這邊主要參考的是網上的一篇部落格2和紅帽的Github[^2]來寫Dockerfile的。Dockerfile如下:
FROM ubuntu
MAINTAINER NachtZ<[email protected]>
LABEL RUN docker run -it --privileged -v /sys/bus/pci/devices:/sys/bus/pci/devices -v /sys/kernel/mm/hugepages:/sys/kernel/mm/hugepages -v /sys/devices/system/node:/sys/devices/system/node -v /dev:/dev --name NAME -e NAME=NAME -e IMAGE=IMAGE IMAGE"
# Setup yum repos, or use subscription-manager
# Install DPDK support packages.
RUN apt-get update && apt-get install -y libpcap-dev wget xz-utils gcc automake autoconf libtool make
# Build DPDK and pktgen-dpdk for x86_64-native-linuxapp-gcc.
WORKDIR /root
COPY ./build_dpdk.sh /root/build_dpdk.sh
COPY ./dpdk-profile.sh /etc/profile.d/
#RUN /root/build_dpdk.sh
# Defaults to a bash shell, you could put your DPDK-based application here.
CMD ["/bin/bash"]
這個Dockerfile的註解如下:
FROM ubuntu
:說明該映象的源映象是Ubuntu。
MAINTAINER NachtZ<[email protected]>
:介紹映象的作者。
LABEL RUN docker run -it --privileged -v /sys/bus/pci/devices:/sys/bus/pci/devices -v /sys/kernel/mm/hugepages:/sys/kernel/mm/hugepages -v /sys/devices/system/node:/sys/devices/system/node -v /dev:/dev --name NAME -e NAME=NAME -e· IMAGE=IMAGE IMAGE"
: 映象的標籤。
RUN apt-get update && apt-get install -y libpcap-dev wget xz-utils gcc automake autoconf libtool make
:安裝DPDK所需要的依賴程式,因為在Docker中的系統都是比較精簡的,所以很多程式都需要自己安裝。
WORKDIR /root
COPY ./build_dpdk.sh /root/build_dpdk.sh
COPY ./dpdk-profile.sh /etc/profile.d/
上面這段話是把Dockerfile同目錄下./build_dpdk.sh
,./dpdk-profile.sh
拷貝到映象裡面去。
CMD ["/bin/bash"]
:指定動作是開啟一個bash。
到此為止,一個可以用來安裝DPDK的映象就完成了。接下來就是開啟它。
在Docker中安裝DPDK
在shell中執行:
docker run -it --privileged -v /sys/bus/pci/devices:/sys/bus/pci/devices -v /sys/kernel/mm/hugepages:/sys/kernel/mm/hugepages -v /sys/devices/system/node:/sys/devices/system/node -v /dev:/dev xxx
(最後的xxx表示的是之前的映象的名字)
在執行這個之前,需要將宿主機的DPDK環境都配置好。比如hugepage,以及轉載好DPDK驅動的埠。之後執行docker run,
--privileged -v /sys/bus/pci/devices:/sys/bus/pci/devices -v /sys/kernel/mm/hugepages:/sys/kernel/mm/hugepages -v /sys/devices/system/node:/sys/devices/system/node
這段話的意思就是給Docker容器許可權來使用宿主機的埠,hugepage等。
之後我們進入到Docker的容器中。
在容器的root
目錄下可以看到之前拷貝的./build_dpdk.sh
。內容如下:
#!/bin/bash
################################################################################
#
# build_dpdk.sh
#
# - Build DPDK and pktgen-dpdk for
#
# Usage: Adjust variables below before running, if necessary.
#
# MAINTAINER: [email protected]
#
#
################################################################################
################################################################################
# Define Global Variables and Functions
################################################################################
URL=http://fast.dpdk.org/rel/dpdk-16.04.tar.xz
BASEDIR=/root
VERSION=16.04
PACKAGE=dpdk
DPDKROOT=$BASEDIR/$PACKAGE-$VERSION
CONFIG=x86_64-native-linuxapp-gcc
# Download/Build DPDK
cd $BASEDIR
wget $URL
tar -xf $PACKAGE-$VERSION.tar.xz
cd $DPDKROOT
sed -i 's/CONFIG_RTE_EAL_IGB_UIO=y/CONFIG_RTE_EAL_IGB_UIO=n/' ${DPDKROOT}/config/common_linuxapp \
&& sed -i 's/CONFIG_RTE_LIBRTE_KNI=y/CONFIG_RTE_LIBRTE_KNI=n/' ${DPDKROOT}/config/common_linuxapp \
&& sed -i 's/CONFIG_RTE_KNI_KMOD=y/CONFIG_RTE_KNI_KMOD=n/' ${DPDKROOT}/config/common_linuxapp
# don't build unnecessary stuff, can be reversed in dpdk_config.sh
sed -i 's/CONFIG_RTE_APP_TEST=y/CONFIG_RTE_APP_TEST=n/' ${DPDKROOT}/config/common_base \
&& sed -i 's/CONFIG_RTE_TEST_PMD=y/CONFIG_RTE_TEST_PMD=n/' ${DPDKROOT}/config/common_base \
&& sed -i 's/CONFIG_RTE_EAL_IGB_UIO=y/CONFIG_RTE_EAL_IGB_UIO=n/' ${DPDKROOT}/config/common_base \
&& sed -i 's/CONFIG_RTE_LIBRTE_IGB_PMD=y/CONFIG_RTE_LIBRTE_IGB_PMD=n/' ${DPDKROOT}/config/common_base \
&& sed -i 's/CONFIG_RTE_LIBRTE_IXGBE_PMD=y/CONFIG_RTE_LIBRTE_IXGBE_PMD=n/' ${DPDKROOT}/config/common_base \
make config T=$CONFIG
sed -ri 's,(PMD_PCAP=).*,\1y,' build/.config
make config T=$CONFIG install
這個文件來自[^3]。我依照DPDK 16.04
中的文件和部落格[^2]來改造的。在部落格[^2]中提到:
One thing that is important is to not rely on kernel headers; doing so would be seriously non portable. The uio and igb_uio kernel modules have to be built and installed by the host that will run the DPDK container. Therefore, we configure the SDK to not compile kernel modules, and therefore not require installing kernel headers on the build system.
就是說在Docker中,用到的網絡卡驅動是宿主機的驅動,所以不需要編譯網絡卡核心驅動。在./build_dpdk.sh
中,的兩行sed語句就是在修改編譯配置。
手動執行完./build_dpdk.sh
之後,就可以正常編譯執行DPDK的程式了。
比如可以:
$:export RTE_SDK=/root/dpdk-16.04
$:export RTE_TARGET=x86_64-native-linuxapp-gcc
$:cd dpdk-16.04/example/helloworld
$:make
$:./build/helloworld
就可以看到helloworld正常的運行了。
Github
這是修改完成之後的Docker的Dockerfile和兩個sh檔案。NachtZ/docker-dpdk
參考資料
- Jason的部落格[^2]
- Redhat的dpdk_docker[^3]