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

相关推荐
helloworddm1 分钟前
Orleans + Kubernetes + Istio 服务网格集成深度解析
容器·kubernetes·istio
小彭律师5 分钟前
Docker/K8s部署MySQL的创新实践与优化技巧大纲
mysql·docker·kubernetes
旦沐已成舟2 小时前
K8S搭建轻量级日志收集系统(EFK)
elk·kubernetes
thinktik4 小时前
AWS EKS安装S3 CSI插件[AWS 海外区]
后端·kubernetes·aws
Jy_06225 小时前
K8s中,deployment 是如何从 yaml 文件最终部署成功 pod 的
云原生·容器·kubernetes
mobº5 小时前
K8s 集群环境搭建 - yaml 版本(一)
云原生·容器·kubernetes
终端行者5 小时前
K8s中部署Minio集群 如何部署minio集群
云原生·容器·kubernetes·1024程序员节
荣光波比5 小时前
Prometheus(二)—— 在K8s集群中部署Prometheus+Grafana+AlertManager实现全方位监控
kubernetes·grafana·prometheus
StarRocks_labs9 小时前
Kubernetes 场景下的 StarRocks 灾备体系:Cluster Snapshot 实践解析
starrocks·kubernetes·数据备份·存算一体架构·快照恢复机制
thinktik9 小时前
AWS EKS 计算资源自动扩缩之Fargate[AWS 海外区]
后端·kubernetes·aws