LabHub
学习 学习路径 课程

Rootless Podman 运维

编写 CDI 规格

在 LabHub 中继续学习

目标

亲自编写 CDI(Container Device Interface)规范,验证其语法和存放位置,并准确使用 podman run --device 参数格式。

为什么重要

CDI 是一种厂商中立的标准,用于描述“要把该设备加入容器,需要哪些设备节点、库和环境变量”。与过去的运行时钩子方式相比,它更透明、可移植性更高,podman、containerd 和 CRI-O 均支持它。在实际工作中,通常由 nvidia-ctk cdi generate 自动生成规范;但驱动更新后 GPU 无法被识别的事故,大多源于遗漏了规范重新生成,因此你必须能够读懂规范内容。

此环境没有真实 GPU。因此,我们将检查规范的语法、结构、存放位置以及 --device 参数格式——这些正是现场最容易出错的地方。

步骤

  1. 创建 /etc/cdi 目录,同时创建 /root/cdi 工作目录。
  2. 创建 /etc/cdi/nvidia.yaml。顶层必须包含 cdiVersion: "0.6.0"kind: nvidia.com/gpu,并且 devices 数组中必须有一个 name: "0" 的条目。该条目的 containerEdits.deviceNodes 中必须包含 /dev/nvidia0/dev/nvidiactl/dev/nvidia-uvm 三个路径。
  3. 将该文件解析为 YAML,并把顶层键列表保存到 /root/cdi/parsed.txt。必须能看到 cdiVersionkinddevices 三个键。
  4. devices 数组中添加第二个条目,其值为 name: "all"。该条目的 deviceNodes 中也必须至少包含两个路径。
  5. name: "0" 条目的 containerEdits 中添加 mountshostPathcontainerPath 都应为 /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.550.90.07,且 options 中必须包含 ronosuidnodevbind 四个值。
  6. name: "0" 条目的 containerEdits 中添加 hookshookNamecreateContainerpath/usr/bin/nvidia-ctkargs["nvidia-ctk", "hook", "update-ldcache"]
  7. 编写 /root/cdi/run.sh。其中必须包含使用 podman run 请求 nvidia.com/gpu=all 设备的命令。--device 参数值的格式必须准确。
  8. 创建包含以下 5 行的 /root/cdi/report.txt。各值必须通过解析你编写的规范获得。 CDI_VERSION=0.6.0 / KIND=nvidia.com/gpu / DEVICES=<devices 배열 길이> / NODES_DEV0=<name 이 "0" 인 장치의 deviceNodes 개수> / SPEC_PATH=/etc/cdi/nvidia.yaml

参考

准备 CDI 目录

创建 /etc/cdi 目录,同时创建 /root/cdi 工作目录。

有两个标准路径。请选择用于存放持久规范的路径。

编写最小规范

创建 /etc/cdi/nvidia.yaml。顶层必须包含 cdiVersion: "0.6.0"kind: nvidia.com/gpu,并且 devices 数组中必须有一个 name: "0" 的条目。该条目的 containerEdits.deviceNodes 中必须包含 /dev/nvidia0/dev/nvidiactl/dev/nvidia-uvm 三个路径。

顶层需要两个键以及 devices 数组。kind 使用斜杠连接域名格式的厂商和类别。

验证 YAML 语法

将该文件解析为 YAML,并把顶层键列表保存到 /root/cdi/parsed.txt。必须能看到 cdiVersionkinddevices 三个键。

使用 python3 的 yaml 模块读取文件,语法错误会立即显现。请汇总并保存解析结果。

添加第二个设备

devices 数组中添加第二个条目,其值为 name: "all"。该条目的 deviceNodes 中也必须至少包含两个路径。

按照惯例,all 是表示所有设备的名称。请在 devices 数组中再添加一个条目。

添加库挂载

name: "0" 条目的 containerEdits 中添加 mountshostPathcontainerPath 都应为 /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.550.90.07,且 options 中必须包含 ronosuidnodevbind 四个值。

mounts 条目包含 hostPath、containerPath、options 三个键。options 是字符串数组。

添加钩子

name: "0" 条目的 containerEdits 中添加 hookshookNamecreateContainerpath/usr/bin/nvidia-ctkargs["nvidia-ctk", "hook", "update-ldcache"]

hooks 条目中包含 hookName、path、args。请使用容器创建时的钩子名称。

编写运行命令

编写 /root/cdi/run.sh。其中必须包含使用 podman run 请求 nvidia.com/gpu=all 设备的命令。--device 参数值的格式必须准确。

--device 的值由 kind 和设备名称以等号连接而成。请将其保存在脚本中。

规范验证报告

创建包含以下 5 行的 /root/cdi/report.txt。各值必须通过解析你编写的规范获得。 CDI_VERSION=0.6.0 / KIND=nvidia.com/gpu / DEVICES=<devices 배열 길이> / NODES_DEV0=<name 이 "0" 인 장치의 deviceNodes 개수> / SPEC_PATH=/etc/cdi/nvidia.yaml

各值必须通过解析实际编写的规范获得。数量即数组长度。