構建dpdk運行環境
編寫Dockerfile文件
FROM debian:stretch
MAINTAINER yanhai<yh@chinabluedon.cn>
COPY sources.list /etc/apt/
COPY dpdk-18.11.tar.xz /opt/
# 解壓xz格式的文件,需要先安裝xz-utils
RUN apt-get update && \
apt-get install -y xz-utils && \
apt-get install -y gcc make && \
apt-get install -y libnuma-dev && \
apt-get install -y libpcap-dev && \
rm -rf /var/lib/apt/lists/*
# 關閉掉一些編譯開關,因為我們不需要這些功能,打開會由於某些原因編譯失敗
# 如果使能PMD_PCAP,需要先安裝libpcap開發包
RUN cd /opt && tar -xf dpdk-18.11.tar.xz && \
cd dpdk-18.11 && \
export RTE_SDK=/opt/dpdk-18.11 && \
export RTE_TARGET=x86_64-native-linuxapp-gcc && \
sed -i 's/CONFIG_RTE_EAL_IGB_UIO=y/CONFIG_RTE_EAL_IGB_UIO=n/' config/common_linuxapp && \
sed -i 's/CONFIG_RTE_LIBRTE_KNI=y/CONFIG_RTE_LIBRTE_KNI=n/' config/common_linuxapp && \
sed -i 's/CONFIG_RTE_KNI_KMOD=y/CONFIG_RTE_KNI_KMOD=n/' config/common_linuxapp && \
sed -i 's/CONFIG_RTE_APP_TEST=y/CONFIG_RTE_APP_TEST=n/' config/common_base && \
sed -i 's/CONFIG_RTE_TEST_PMD=y/CONFIG_RTE_TEST_PMD=n/' config/common_base && \
sed -i 's/CONFIG_RTE_EAL_IGB_UIO=y/CONFIG_RTE_EAL_IGB_UIO=n/' config/common_base && \
sed -i 's/CONFIG_RTE_LIBRTE_IGB_PMD=y/CONFIG_RTE_LIBRTE_IGB_PMD=n/' config/common_base && \
sed -i 's/CONFIG_RTE_LIBRTE_IXGBE_PMD=y/CONFIG_RTE_LIBRTE_IXGBE_PMD=n/' config/common_base && \
sed -i 's/CONFIG_RTE_LIBRTE_I40E_PMD=y/CONFIG_RTE_LIBRTE_I40E_PMD=n/' config/common_base && \
sed -ri 's,(PMD_PCAP=).*,\1y,' config/common_base && \
make config T=$RTE_TARGET && \
make -j4 install T=$RTE_TARGET DESTDIR=/usr/local && \
cd / && \
rm -rf /opt/dpdk-18.11.tar.xz && \
rm -rf /opt/dpdk-18.11
build
我們將鏡像命名為dpdk-dev
docker build -t dpdk-dev .
測試
首先在宿主機配置dpdk環境
前提,在宿主機上已經編譯了dpdk源碼,在/opt/dpdk-18.11/
下
安裝igb驅動
modprobe uio
insmod /opt/dpdk-18.11/x86_64-native-linuxapp-gcc/kmod/igb_uio.ko
配置大頁內存
mkdir -p /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
# 分配系統總內存的4分之1用作2MB大頁內存
total_mem=`cat /proc/meminfo | grep MemTotal | awk '{print $2}'`
if [[ -d /sys/devices/system/node/node1 ]]; then
hugepages_mem=$(($total_mem/8000000*1024/2))
echo $hugepages_mem > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo $hugepages_mem > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
else
hugepages_mem=$(($total_mem/8000000*1024))
echo $hugepages_mem > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
fi
創建容器
docker run -it -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 dpdk-dev
進入examples目錄
這里編譯運行helloworld程序
export RTE_SDK=/opt/dpdk-18.11
export RTE_TARGET=x86_64-native-linuxapp-gcc
cd /opt/dpdk-18.11/examples/helloworld
make
./build/app/helloworld
案例
現在有這樣一個需求,在宿主機上運行一個dpdk的讀取網卡數據包的一個進程(相當於生產者),將收到的數據包放入一個隊列(rx_queue),
在docker里面有一個相當於消費者的進程,讀取rx_queue中的數據包進行分析處理,處理完畢后放入tx_queue隊列,生產者從tx_queue取出數據包,
再回收內存(放入包池)。
那么如何讓docker內外的2個進程共享dpdk隊列呢?
這種需求是可以實現的,
在創建容器時,除了共享如上面測試helloworld程序時的/sys/bus/pci/devices
、/sys/kernel/mm/hugepages
、
/sys/devices/system/node
、/dev
外,還需要共享/var/run/dpdk/
目錄
即
-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 \
-v /var/run/dpdk:/var/run/dpdk
/var/run/dpdk/
目錄存放了dpdk創建的ring mempool等其他的一些信息
注意
本例使用的是dpdk-18.11版本,共享/var/run/dpdk/目錄就可以了
在dpdk-stable-16.11.1版本中,配置信息是存放在/var/run/.rte_config
和/var/run/.rte_hugepage_info
目錄的
因此在dpdk-stable-16.11.1版本中需要共享
-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 \
-v /var/run/.rte_config:/var/run/.rte_config \
-v /var/run/.rte_hugepage_info:/var/run/.rte_hugepage_info