Linux NFD(Node Feature Discovery)的 GPU / RDMA 标签自动发现

3次阅读

nfd-worker默认不发现gpu和rdma设备,因其插件需在configmap中显式启用且依赖驱动、工具及内核模块就绪;标签生成有延迟,且调度需匹配精确的字符串型标签。

Linux NFD(Node Feature Discovery)的 GPU / RDMA 标签自动发现

为什么 nfd-worker 默认不发现 GPU 和 RDMA 设备

因为 NFD 的默认配置只启用基础硬件特征(如 CPU 架构、内核版本),GPU 和 RDMA 属于可选插件,需要显式开启。不改配置的话,kubectl get nodes -o wide 里压根看不到 feature.node.kubernetes.io/pci-xxxfeature.node.kubernetes.io/rdma.available 这类标签。

实操建议:

  • 确认 nfd-worker Pod 正在运行且日志无 failed to load plugin "gpu" 类报错:
    kubectl logs -n nfd nfd-worker-xxxxx
  • 编辑 ConfigMap nfd-worker-conf,在 featureSources 列表中加入 "gpu""rdma"
  • 确保节点上已安装对应驱动:NVIDIA 驱动(非 CUDA Toolkit)、rdma-core 包、且 ibstatnvidia-smi 命令可用

nfd-worker 启用 GPU 插件后仍没打标签的常见原因

不是开了插件就自动生效——GPU 插件依赖 /proc/driver/nvidia/gpus/ 下存在设备目录,且要求 nvidia-smi 可执行、返回非错误码。任意一环断掉,插件静默跳过,日志里可能只有一行 skipping gpu feature source: no devices found

实操建议:

  • nfd-worker 容器手动验证:
    ls /proc/driver/nvidia/gpus/ && nvidia-smi -L

    ,二者必须都成功

  • 若用容器运行时(如 containerd),检查 nfd-worker 是否挂载了 /dev/nvidiactl/dev/nvidia-uvm 等设备节点(否则 nvidia-smi 会失败)
  • 部分云厂商实例(如 AWS p3)需额外加载 nvidia-fs 模块,否则 /proc/driver/nvidia/ 为空

RDMA 标签没出现?先看 ibstat 和内核模块

RDMA 插件只认 ibstat 命令输出,不解析 ibv_devinfo 或 sysfs。如果 ibstat 找不到、返回空、或提示 No HCAs found,插件直接放弃,连日志都不多打一行。

实操建议:

  • 在节点上运行 ibstat;失败则装 rdma-core 工具包(ubuntu/debianapt install rdma-core,RHEL/centosyum install rdma-core
  • 确认 ib_uverbsib_coremlx5_core(或对应网卡驱动)已加载:
    lsmod | grep -E "(ib_|mlx)"
  • NFD 不会自动加载内核模块,必须由管理员提前配置好,否则插件看到的是“没硬件”

标签打上了但 Pod 没法调度到带 GPU/RDMA 的节点

标签本身只是“声明”,真正起作用的是你写的 nodeSelectornodeAffinity。NFD 加的标签名是固定的,比如 GPU 是 feature.node.kubernetes.io/pci-10de.present(10de 是 NVIDIA PCI vendor ID),写错一个字符就匹配不上。

实操建议:

  • kubectl get node xxx -o jsonpath='{.metadata.labels}' | jq 确认实际打出的标签名,别凭记忆写
  • RDMA 相关标签有多个层级,常用的是 feature.node.kubernetes.io/rdma.available(布尔值)和 feature.node.kubernetes.io/pci-15b3.present(Mellanox)
  • 注意 label value 类型:GPU 插件写的是 "true"(字符串),不是 true(布尔),nodeSelector 里必须用引号

最常被忽略的一点:NFD 的标签更新有延迟,从插件识别到标签出现在 Node 对象上,可能隔 30–60 秒。别刚改完配置就立刻查,等一小会儿再 kubectl get node

text=ZqhQzanResources