关于容器设备接口 | Container Device Interface, CDI

截至v1.12.0版本发布,NVIDIA容器工具包(Nvidia Container Toolkit)已支持生成容器设备接口(CDI)规范。

CDI是针对容器运行时的开放规范,它抽象了对设备(如NVIDIA GPU)的访问权限,并在不同容器运行时之间实现了访问方式的标准化。主流容器运行时能够读取并处理该规范,从而确保设备能在容器中可用。由于CDI规格适用于所有支持它的容器运行时,因此简化了对NVIDIA GPU等设备的支持。

此外,CDI还提升了NVIDIA容器堆栈与某些特性(如无根容器)的兼容性。原文链接

生成一个CDI规范

前置要求

  • 您已安装 NVIDIA 容器工具包(NVIDIA Container Toolkit),或者您已安装了 nvidia-container-toolkit-base 包。基础包包含容器运行时和 nvidia-ctk 命令行界面,但不会安装容器运行时钩子和间接依赖项。如果您仅使用 CDI,则不需要这些钩子和依赖项。
  • 您已安装 NVIDIA GPU 驱动程序。

操作步骤

CDI 规范通常存储在以下两个常见位置:/etc/cdi/ /var/run/cdi/

/var/run/cdi/ 目录中的内容会在系统启动时被清空。然而,创建和使用的路径可能取决于您使用的容器引擎。

1. 生成CDI规范文件:

    $ sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml

    上述示例命令使用 sudo 确保在 /etc/cdi/nvidia.yaml 路径下创建文件。您可以省略 --output 参数,将生成的规范输出到标准输出(STDOUT)。

    输出示例
    INFO[0000] Auto-detected mode as "nvml"
    INFO[0000] Selecting /dev/nvidia0 as /dev/nvidia0
    INFO[0000] Selecting /dev/dri/card1 as /dev/dri/card1
    INFO[0000] Selecting /dev/dri/renderD128 as /dev/dri/renderD128 INFO[0000] Using driver version xxx.xxx.xx
    ...

    2. (可选操作)检查生成的CDI设备名称

    $ nvidia-ctk cdi list --spec=/etc/cdi/nvidia.yaml
    输出示例
    name: nvidia.com/pci_bus_id=0000:81:00.0
    vendor: NVIDIA Corporation
    product: GA102GL [A30]
    pci Bus ID: 0000:81:00.0
    UUID: GPU-<UUID>

      注意

      在进行过如下任意一种改动后,你都需要重新生成新的CDI规范(执行上述步骤):

      • 修改了CUDA驱动配置
      • 你使用的CDI规范生成目录如 /var/run/cdi 在重启后被清除了

      当MIG设备被创建/移除或驱动更新时都会导致配置改变

      在Podman容器中使用GPU

      使用 CDI 注入 NVIDIA 设备可能会与使用 NVIDIA 容器运行时钩子(NVIDIA Container Runtime hook)产生冲突。这意味着如果存在 /usr/share/containers/oci/hooks.d/oci-nvidia-hook.json 文件,请删除它,或确保在运行容器时不设置 NVIDIA_VISIBLE_DEVICES 环境变量。

      CDI 规范的使用依赖于您所使用的支持 CDI 的容器引擎或 CLI。以 podman 为例,从版本 v4.1.0 开始,支持在 --device 参数中指定 CDI 设备。假设您已经按照前文所述生成了 CDI 规范,则运行一个可以访问所有 NVIDIA GPU 的容器需要以下命令:

      $ podman run --rm --device nvidia.com/gpu=all --security-opt=label=disable ubuntu nvidia-smi -L

      上述示例命令的输出应与在主机上直接运行 nvidia-smi -L 相同。

      CDI 规范还包含对单个 GPU 或 MIG 设备的引用。您可以在启动容器时通过指定它们的名称来请求这些设备,例如以下示例:

      $ podman run --rm \
                   --device nvidia.com/gpu=0 \
                   --device nvidia.com/gpu=1:0 \
                   --security-opt=label=disable \
                   ubuntu nvidia-smi -L

      上述示例命令请求了索引为 0 的完整 GPU 和 GPU 1 上的第一个 MIG 设备。输出应仅显示所请求设备的 UUID。

      By i2cy

      发表回复