工作原理

kubernets cdi主要完成   让节点感知可供容器使用的设备资源,当容器申请对应资源时,为该容器分配设备并挂入容器使用。

以cdi接入nvidia显卡设备到容器为例

  • nvidia-device-plugin 将通过daemonset的方式运行在各个节点上
  • nvidia-device-plugin 向kubelet.sock注册
  • kubelet 通过nvidia-device-plugin 感知节点上的GPU设备并同步到集群的node资源上。
  • 当有容器调度到节点上申请GPU设备资源时,nvidia-device-plugin 将通过nvidia-container-tookit获取可分配的GPU设备
  • kubelet 调用runtime时创建容器时将调用 nvidia-container-runtme 而非 container-runtme
  • nvidia-container-runtime 主要扩展功能是支持将gpu设备uuid以env的方式注入到容器的启动配置 config.json(oci规范),并注册启动时的hook调用
  • nvidia-container-runtime 启动runc, runc 启动时发现 hook 配置,将根据hook地址调用nvidia-container-runtime-hook, container-runtime-hook最终调用 nvidia-container-cli将gpu设备以及相关的依赖库挂入容器的挂载空间, 挂入哪个gpu由环境变量注入的设备uuid决定。
  • gpu 设备挂入完成后,再启动容器对应的服务进程。

配置分析

节点的设备感知

查询节点信息,已通过device-plugin感知到设备

apiVersion: v1
kind: Node
...

status:
  allocatable:
    nvidia.com/4090_xxGB: "8"
  capacity:
    nvidia.com/4090_xxGB: "8"

容器的设备挂载配置

容器的config.json 中通用配置外,可见也注入了分配的GPU设备的UUID,以及启动hooks使用

nvidia-container-runtime-hook

{
  "ociVersion": "1.1.0",
  "process": {
    "env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
      "container=oci",
      "NVIDIA_VISIBLE_DEVICES=GPU-bb5c2ee2-29d5-5a74-fc60-22820eef8702",
    ]
  },
  "hooks": {
    "prestart": [
      {
        "path": "/usr/bin/nvidia-container-runtime-hook",
        "args": [
          "nvidia-container-runtime-hook",
          "prestart"
        ]
      }
    ],
    "createContainer": [
      {
        "path": "/usr/bin/nvidia-ctk",
        "args": [
          "nvidia-ctk",
          "hook",
          "enable-cuda-compat",
          "--host-driver-version=570.133.20"
        ]
      },
      {
        "path": "/usr/bin/nvidia-ctk",
        "args": [
          "nvidia-ctk",
          "hook",
          "update-ldcache"
        ]
      }
    ]
  }
}

查看设备挂载

容器中

# stat /dev/nvidia7
  File: /dev/nvidia7
  Size: 0               Blocks: 0          IO Block: 4096   character special file
Device: 0,5     Inode: 2011        Links: 1     Device type: 195,7
Access: (0666/crw-rw-rw-)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2025-09-22 15:44:53.081517950 +0800
Modify: 2025-09-22 15:44:53.081517950 +0800
Change: 2025-09-22 15:44:53.081517950 +0800
 Birth: -

节点上

# stat /dev/nvidia7
  File: /dev/nvidia7
  Size: 0               Blocks: 0          IO Block: 4096   character special file
Device: 0,5     Inode: 2011        Links: 1     Device type: 195,7
Access: (0666/crw-rw-rw-)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2025-09-22 15:44:53.081517950 +0800
Modify: 2025-09-22 15:44:53.081517950 +0800
Change: 2025-09-22 15:44:53.081517950 +0800
 Birth: -

通过设备号 确定主机显卡设备挂入了容器

通过容器进程的proc文件系统可查到更详细的挂载情况

/proc/[pid]/task/[pid]/mountinfo

52504 52463 0:5 /nvidiactl /dev/nvidiactl ro,nosuid,noexec,relatime master:2 - devtmpfs udev rw,size=528160624k,nr_inodes=132040156,mode=755,inode64
52505 52463 0:5 /nvidia-uvm /dev/nvidia-uvm ro,nosuid,noexec,relatime master:2 - devtmpfs udev rw,size=528160624k,nr_inodes=132040156,mode=755,inode64
52506 52463 0:5 /nvidia-uvm-tools /dev/nvidia-uvm-tools ro,nosuid,noexec,relatime master:2 - devtmpfs udev rw,size=528160624k,nr_inodes=132040156,mode=755,inode64
52507 52463 0:5 /nvidia6 /dev/nvidia6 ro,nosuid,noexec,relatime master:2 - devtmpfs udev rw,size=528160624k,nr_inodes=132040156,mode=755,inode64
52508 52484 0:23 /driver/nvidia/gpus/0000:b1:00.0 /proc/driver/nvidia/gpus/0000:b1:00.0 ro,nosuid,nodev,noexec,relatime master:13 - proc proc rw

查看设备权限配置

cgroupv2 的设备权限是通过bpf配置的的,使用下列命令查询。

可见配置的设备权限,具体可导出后分析

sudo bpftool cgroup list /sys/fs/cgroup/system.slice/docker-<ID>.scope effective

ID       AttachType      AttachFlags     Name
440466   device          multi
525755   device          multi

更多推荐