Data Plane Kit on a Docker Container

From RidgeRun Developer Wiki






Docker Support for DPDK

This section provides guidance on setting up DPDK inside a Docker container.


Info
If you haven't installed Docker on your system, feel free to follow our guide on how to do it.


Setting Up the Docker Container

To create a Docker container for DPDK with access to required resources, first create the image using the following Dockerfile:

# Use the same Ubuntu version as your host system
FROM ubuntu:22.04

# Set the working directory
WORKDIR /root

# Update package list and install required dependencies
RUN apt update && \
    apt install -y wget xz-utils meson python3-pip libnuma-dev libpcap-dev python3-pyelftools pciutils iproute2

# Download and extract DPDK source code
RUN wget https://fast.dpdk.org/rel/dpdk-23.11.2.tar.xz && \
    tar -xf dpdk-23.11.2.tar.xz && \
    rm dpdk-23.11.2.tar.xz

# Set working directory to DPDK source
WORKDIR /root/dpdk-stable-23.11.2

# Build DPDK using meson and ninja
RUN meson build -Dexamples=all && \
    ninja -C build && \
    ninja -C build install

# Define default command to open a bash shell
CMD ["/bin/bash"]

Place the above content in a file called Dockerfile, the path is not important, for this example it will be placed in a directory called docker. After this, create the docker image:

cd docker/
docker build -t dpdk-image .

Now you can create create the docker container using the image you just created:

docker create \
-ti --network host --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 \
-v /lib/modules/:/lib/modules \
--name dpdk-container dpdk-image


Note

The above command extends privileges to the container with the --priveleged flag. Root privileges are required by some of the utilities of DPDK, for example to unbind and bind the NIC to the corresponding driver, and to reserve and free the required hugepages for the applications.

Additionally, DPDK relies on some system resources, and to access these resources inside the docker container the -v is used for several paths:

  • /sys/bus/pci/devices: DPDK often needs direct access to PCI devices (like network interface cards). By mounting this directory, the container can access PCI devices directly to perform device initialization, resource management, and more.
  • /sys/kernel/mm/hugepages: DPDK relies on hugepages (large memory pages) to improve memory access efficiency. Mounting this path allows DPDK in the container to manage hugepages set up on the host, as it needs to allocate hugepage-backed memory for its operations.
  • /sys/devices/system/node: This directory provides information about NUMA (Non-Uniform Memory Access) nodes, which is used by DPDK.
  • /dev: This mount allows access to various device files in /dev, including network interfaces and hugepages.
  • /lib/modules/: The container needs access to the kernel modules on the host, specifically the PMD (Poll-Mode Driver) driver, the DPDK setup uses kernel modules to bind/unbind these drivers.


Next, access the container with:

# First, start the container
docker start dpdk-container

docker exec -ti dpdk-container bash

Examples

Inside the docker container you can run some of the examples provided by DPDK.

  • First, check the available NIC device:
cd ~/dpdk-stable-<dpdk version>/
python3 usertools/dpdk-devbind.py -s

It will give a similar output like this:

Network devices using kernel driver
===================================
0000:02:00.0 'RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller 8168' if=enp2s0 drv=r8169 unused= 

No 'Baseband' devices detected
==============================

No 'Crypto' devices detected
============================

No 'DMA' devices detected
=========================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
==============================

No 'Misc (rawdev)' devices detected
===================================

No 'Regex' devices detected
===========================

No 'ML' devices detected
========================

Which says, for this case, there is one NIC binded to the kernel driver, with interface name enp2s0. For this example we are using a virtual device, for this reason the NIC will not binded to the PMD driver.

  • Now you can reserve the hugepages to use with the example applications:
python3 usertools/dpdk-hugepages.py --pagesize 2M --setup 600M --node 0

Verify with the command python3 usertools/dpdk-hugepages.py -s the available hugepages. The output will be like the following:

Node Pages Size Total
0    300   2Mb    600Mb

Hugepages mounted on /dev/hugepages
  • Execute the example application, in this case we are using the ethtool application which is a command line tool, we test the drvinfo and link commands:
export INTERFACE=enp2s0
./build/examples/dpdk-ethtool --vdev net_pcap0,iface=$INTERFACE

The command line will open, you can test the application with the commands drvinfo and link, a similar output will be shown:

EAL: Detected CPU lcores: 12
EAL: Detected NUMA nodes: 1
EAL: Detected static linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
TELEMETRY: No legacy callbacks, legacy socket not created
Number of NICs: 1
Init port 0..
EthApp> drvinfo
firmware version get error: (Operation not supported)
Port 0 driver: net_pcap (ver: DPDK 23.11.2)
firmware-version: 
bus-info: net_pcap0
EthApp> link
Port 0: Up