docker構建dpdk運行環境鏡像


構建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

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM