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

相关推荐
牛奶咖啡1313 小时前
k8s容器编排技术实践——使用containerd作为容器运行时部署k8s集群
kubernetes·k8s的安装部署·开启系统的ipvs支持·安装containerd·containerd配置加速器·安装k8s的工具·安装calico网络插件
2301_7807896614 小时前
手游遇到攻击为什么要用SDK游戏盾手游遇到攻击为什么要用 SDK 游戏盾?
安全·web安全·游戏·架构·kubernetes·ddos
珂玥c15 小时前
k8s集群ingress碎碎念
云原生·容器·kubernetes
佳杰云星16 小时前
如何给大模型集群选“大脑”?智算调度与管理平台 10 维选型指南(附选型评分表)
人工智能·kubernetes·大模型·云计算·gpu·算力调度·智算中心
比特森林探险记17 小时前
context 在 gRPC / Gin / K8s 中的实战
容器·kubernetes·gin
汪汪大队u18 小时前
基于 K8s 的物联网平台运维体系:Ansible+Zabbix 自动化监控与故障自愈(三)—— Zabbix Server 启动排错记
运维·kubernetes·ansible
日取其半万世不竭20 小时前
OpenCost:Kubernetes 成本监控,开源的云资源费用分析
容器·kubernetes·开源
Cat_Rocky20 小时前
k8s zabbix7学习-设置告警
学习·容器·kubernetes
云游牧者21 小时前
K8S-Ingress流量治理全解-Traefik从入门到实战完全指南
云原生·中间件·容器·kubernetes·ingress·traefik
AI云原生1 天前
容器网络模型与服务发现:从踩坑到精通,Kubernetes 网络问题排查全指南
服务器·网络·云原生·容器·kubernetes·云计算·服务发现