Nvidia Device Plugin入门二之envvar策略

在 Kubernetes 中使用 GPU,NVIDIA Device Plugin 是必不可少的组件。它支持多种 GPU 注入策略,其中 envvar 是最早、最简单的一种。本文将带你深入理解 envvar 策略的原理、优缺点以及适用场景。

一、背景

在 Kubernetes 中,Device Plugin 框架 为 GPU、FPGA、RDMA 等特殊硬件提供了标准化的管理接口。

NVIDIA Device Plugin 是 NVIDIA 官方实现的 GPU 设备插件,负责:

  • 向 kubelet 注册 nvidia.com/gpu 资源
  • 汇报节点上可用的 GPU 列表及健康状态
  • 在 Pod 启动时,将分配的 GPU 注入到容器中

其中Nvidia Device Plugin比较核心的一个配置是DEVICE_LIST_STRATEGY,用来设置容器分配网卡的策略。 而今天要介绍的**envvar 策略,是最早支持也是现在默认的策略。


二、什么是 envvar 策略

envvar 策略的核心思想是:

通过设置环境变量 NVIDIA_VISIBLE_DEVICES,将分配的 GPU 列表传递给nvidia的容器运行时,由运行时在容器启动时注入对应的 /dev/nvidia* 设备。 这种方式实现简单、兼容性好,是最早的 GPU 注入方案。


三、工作原理

假设一个 Pod 申请了 2 张 GPU:

3.1 Pod 请求 GPU

yaml 复制代码
resources:
  limits:
    nvidia.com/gpu: 2

3.2 kubelet 调用 Device Plugin

  • kubelet 调用 Device Plugin 的 Allocate() 方法
  • Device Plugin 选择可用的 GPU(例如 UUID=GPU-abc123, GPU-def456)

3.3 Device Plugin 返回 AllocateResponse

json 复制代码
"envs": {
  "NVIDIA_VISIBLE_DEVICES": "GPU-abc123,GPU-def456"
}
  • 值是 GPU UUID 或 index(取决于配置)
  • kubelet 将这个环境变量写入容器 spec

3.4 容器运行时解析

  • nvidia-container-runtime 在容器启动的 prestart hook 中读取 NVIDIA_VISIBLE_DEVICES
  • 根据 UUID 找到对应的 /dev/nvidia* 设备
  • 注入设备到容器,并更新 cgroup devices.allow

四、优点

  1. 实现简单
    • 只需设置一个环境变量,不需要修改 CRI API
    • 容易在不同容器运行时(Docker、containerd、CRI-O、Podman)中实现
  2. 兼容性好
    • 即使不在 Kubernetes 中,直接:

      arduino 复制代码
      docker run --gpus '"device=0,1"' nvidia/cuda:12.2-base nvidia-smi

      也能用类似方式工作

  3. 早期唯一可行方案
    • 在没有 CDI(Container Device Interface)之前,这是最容易落地的方式

五、缺点与安全风险

5.1 容易被绕过

  • 用户可以在 PodSpec 中手动设置:
yaml 复制代码
env:
  - name: NVIDIA_VISIBLE_DEVICES
    value: all
  • 即使只申请了 1 张卡,也能访问所有 GPU

5.2 默认镜像可能全卡开放

  • 很多 NVIDIA 官方镜像(如 nvidia/cuda:*)默认带:
ini 复制代码
ENV NVIDIA_VISIBLE_DEVICES=all
  • 如果 runtime 没有额外限制,这会覆盖 Device Plugin 的分配结果

5.3 不受 Kubernetes 资源模型约束

  • Kubernetes 无法阻止用户自己设置这个环境变量
  • 在多租户/HPC 场景下可能导致 GPU 越权使用

5.4 systemd daemon-reload会掉卡

这是一个致命的问题 在pod运行过程中,如果节点运行了systemd daemon-reload,pod内会丢失显卡的操作权限,遇到如下报错

vbnet 复制代码
/# nvidia-smi
Failed to initialize NVML: Unknown Error

相关issue

相关推荐
运维-大白同学1 小时前
2025最全面开源devops运维平台功能介绍
linux·运维·kubernetes·开源·运维开发·devops
敲上瘾8 小时前
【探索实战】:Kurator分布式统一应用分发平台的全面解析与实践指南
分布式·容器·kubernetes·serverless
Connie145119 小时前
记一次K8s故障告警排查(Grafna告警排查)
云原生·容器·kubernetes·grafana
谷隐凡二1 天前
Kubernetes主从架构简单解析:基于Python的模拟实现
python·架构·kubernetes
陈陈CHENCHEN1 天前
SuperMap iManager for K8s 离线环境镜像仓库 Containerd 部署
kubernetes
会飞的小蛮猪1 天前
Ubuntu24.04 基于Containerd部署K8s1.34(私服部署)
docker·云原生·kubernetes
间彧2 天前
Kubernetes滚动发布详解
kubernetes
间彧2 天前
在实际生产环境中,Kubernetes声明式API如何实现蓝绿部署、金丝雀发布等高级部署策略?
kubernetes
间彧2 天前
Kubernetes声明式API相比传统命令式API在故障恢复场景下的具体优势有哪些?
kubernetes·github
间彧2 天前
为什么说Kubernetes的API设计是其成功的关键因素之一?
kubernetes