Container Device Interface (CDI) Usage Guide#

Overview#

Container Device Interface (CDI) enables defining specifications that allow greater control on how devices are exposed to containers. Instead of running containers in --privileged mode, which exposes every host device, or manually bind-mounting /dev/dri paths, CDI lets you request devices by name — the runtime handles device nodes, permissions, and mounts automatically.

CDI uses predefined YAML specification files in /etc/cdi/ to describe the device files, mounts, and environment variables that are exposed to the container.

CDI Kind

Specification File

Device Names

Description

intel.com/gpu

intel.com-gpu.yaml

card0, card1, …

Intel® GPU devices [Physical Function (PF) and SR-IOV Virtual Functions (VFs)]

intel.com/npu

intel.com-npu.yaml

npu0

Intel® NPU accelerator device


Prerequisites#

  • Edge Node Infrastructure Blueprint image deployed

  • Docker Engine version 25 or newer (with CDI support enabled), Podman version 4.1 or newer, or containerd version 1.7 or newer

  • Intel GPU with SR-IOV VFs enabled

  • Intel NPU hardware present (optional)

  • sudo access


Step 1: CDI Specification Generation (Automatic on First Boot)#

In Edge Node Infrastructure Blueprint images, the CDI specification generation service is automatically started on first boot. The service includes:

  • GPU specifications: Generated using the official intel-cdi-specs-generator-gpu binary from Intel® Resource Drivers for Kubernetes

  • NPU specifications: Generated using the custom intel-cdi-npu-generator.sh bash script

The CDI generation service is pre-configured with:

  1. Udev rules — triggers CDI regeneration when GPU VFs or NPU devices appear

  2. Systemd service (intel-cdi-regenerate.service) — runs both GPU and NPU generators

  3. Systemd timer — periodic fallback regeneration (every 5 minutes)

Verify CDI Specification Generation#

After the first boot, verify that the service ran successfully:

systemctl status intel-cdi-regenerate.service
journalctl -u intel-cdi-regenerate.service --no-pager -n 20

Verify that the specifications were generated:

ls /etc/cdi/
# Expected: intel.com-gpu.yaml  intel.com-npu.yaml

Manual Regeneration (If Needed)#

If you need to trigger specification regeneration manually:

sudo systemctl start intel-cdi-regenerate.service

Or run the generators directly:

# Scripts are located at /opt/edge/scripts/cdi
sudo /opt/edge/scripts/cdi/intel-cdi-specs-generator-gpu --cdi-dir /etc/cdi gpu
sudo bash /opt/edge/scripts/cdi/intel-cdi-npu-generator.sh --cdi-dir /etc/cdi

Step 2: Configure Docker Daemon for CDI#

Check /etc/docker/daemon.json:

{
  "features": {
    "cdi": true
  },
  "cdi-spec-dirs": ["/etc/cdi"]
}

Restart Docker daemon after any changes:

sudo systemctl restart docker

Step 3: Run Containers with CDI Devices#

GPU Container#

Use the --device flag with the CDI device name from the specification file:

docker run --rm --device intel.com/gpu=card1 ubuntu:24.04 ls /dev/dri/

Expected output — the container sees only the assigned GPU device:

card1
renderD129

NPU Container#

docker run --rm --device intel.com/npu=npu0 ubuntu:24.04 ls /dev/accel/

Expected output:

accel0

Multiple Devices#

Assign a GPU and an NPU to the same container:

docker run --rm \
  --device intel.com/gpu=card1 \
  --device intel.com/npu=npu0 \
  ubuntu:24.04 sh -c "ls /dev/dri/ && ls /dev/accel/"

Multiple GPU VFs#

Assign two GPU VFs to a single container:

docker run --rm \
  --device intel.com/gpu=card1 \
  --device intel.com/gpu=card2 \
  ubuntu:24.04 ls /dev/dri/

Step 4: Use CDI Devices with Docker Compose#

Reference CDI device names directly in your Docker Compose file:

services:
  gpu-workload:
    image: my-inference-app:latest
    devices:
      - intel.com/gpu=card1
      - intel.com/npu=npu0

Run:

docker compose up

GPU-only example:

services:
  gpu-worker:
    image: my-gpu-worker:latest
    devices:
      - intel.com/gpu=card1

CDI Specification Format Reference#

The GPU specification generated by intel-cdi-specs-generator-gpu follows the standard CDI 0.5.0 format:

---
cdiVersion: 0.5.0
kind: intel.com/gpu
devices:
    - name: card1
      containerEdits:
        deviceNodes:
            - path: /dev/dri/card1
              hostPath: /dev/dri/card1
              type: c
            - path: /dev/dri/renderD129
              hostPath: /dev/dri/renderD129
              type: c
        mounts:
            - hostPath: /dev/dri/by-path/pci-0000:00:02.1-card
              containerPath: /dev/dri/by-path/pci-0000:00:02.1-card
              options:
                - bind
                - rw
              type: none

The NPU specification generated by intel-cdi-npu-generator.sh:

---
cdiVersion: "0.5.0"
kind: intel.com/npu
devices:
  - name: npu0
    containerEdits:
      deviceNodes:
        - path: /dev/accel/accel0
          hostPath: /dev/accel/accel0
          type: c

Troubleshooting#

No CDI Specification Files in /etc/cdi/#

# Scripts are located at /opt/edge/scripts/cdi
sudo /opt/edge/scripts/cdi/intel-cdi-specs-generator-gpu --cdi-dir /etc/cdi gpu
sudo bash /opt/edge/scripts/cdi/intel-cdi-npu-generator.sh --cdi-dir /etc/cdi

Docker Says “CDI device not found”#

  1. Verify that the Docker Engine version is 25 or newer:

    docker --version
    
  2. Verify that CDI is enabled in /etc/docker/daemon.json:

    {
      "features": { "cdi": true },
      "cdi-spec-dirs": ["/etc/cdi"]
    }
    
  3. Restart the Docker service:

    sudo systemctl restart docker
    

NPU Not Detected#

Verify that the NPU driver is loaded and the device exists:

ls /sys/bus/pci/drivers/intel_vpu/
ls /dev/accel/

If /dev/accel/ is empty, load the driver:

sudo modprobe intel_vpu

For kernel version 6.17 or newer, verify that the NPU firmware is present:

ls /lib/firmware/intel/vpu/
dmesg | grep -i vpu

GPU VFs Not Showing in CDI Specification#

Verify that SR-IOV VFs are enabled:

cat /sys/bus/pci/devices/0000:00:02.0/sriov_numvfs
ls /dev/dri/renderD*

If the VFs are not created, enable them first, then regenerate the CDI specifications.


References#