- 可观测性
- 指标监控
【免费下载链接】nvidia_gpu_exporter
Nvidia GPU exporter for prometheus using nvidia-smi binary OR using NVML
nvidia_gpu_exporter 是一个面向 Prometheus 的 NVIDIA GPU 指标导出器:默认通过调用nvidia-smi二进制完成采集、解析与导出,另可选读 NVML 驱动库的 nvml 后端,以及无需任何 GPU 的 demo 合成数据后端,覆盖 Linux、Windows、macOS 与裸机、Docker、Kubernetes 部署。本文以项目 README 为主线,结合仓库源码逐层讲清它的工作原理、三种采集后端、各平台安装方式、发布物签名验证与安全边界,读完即可在自己机器或集群里把 GPU 指标接入监控栈。
项目定位与适用场景
README 的第一句话概括了它:一个用nvidia-smi(.exe)二进制来收集、解析并导出指标的简单 exporter。由于只依赖nvidia-smi,它不需要 C 语言绑定,因此 Windows 同样能跑——不需要 Docker、也不需要 Linux。
从 README 的 Use cases 一节看,它瞄准的是数据中心的重量级工具链覆盖不到、或成本过高的场景:
- 消费级与专业级显卡(GeForce/RTX):数据中心工具链对它们暴露的信息很少,
nvidia-smi往往是利用率、显存、功耗、温度唯一统一的来源; - 小型 Kubernetes 集群、边缘盒子与家庭实验室:想要 GPU 指标,但不想引入整套 NVIDIA GPU Operator;
- 虚拟化或受限环境(vGPU 客户机、MIG 切片、强管控容器):深层 GPU 计数器不暴露,但
nvidia-smi仍然能回答; - 新旧显卡混编的机群:需要一个在各处行为一致的 exporter;
- 游戏主机:边玩游戏边在仪表盘上看 GPU 状态。
README 也给出了明确的边界:如果你在 Kubernetes 上用 GPU Operator 跑数据中心卡,DCGM-exporter 可能更合适,本项目针对的是上述场景。此外 README 保留了一个诚实的提示:这是一个开发者利用业余时间维护的 side project,issue 和 PR 的响应速度无法保证。
它的核心卖点(Highlights)可以归纳为六点,后文会逐一展开:
- 任何装有
nvidia-smi(.exe)的系统都能跑,Windows、Linux、macOS,无需 C 绑定; - 甚至可以不在被监控机器上运行——把
--nvidia-smi-command指向 SSH 命令即可远程采集; - 自动发现
nvidia-smi能暴露的指标字段(面向未来,新驱动加了字段就能被捡到); - 可选的 per-process GPU 指标:看到哪个进程用了多少显存;
- 可选的后台采集模式:按定时器跑
nvidia-smi,而不是每次 scrape 都跑一次; - 自带两套官方 Grafana 仪表盘:单卡详情视图与多卡总览视图,互相有跳转链接。
工作原理:从 nvidia-smi 的 CSV 到 Prometheus 指标
从源码结构看,整个程序是一条清晰的调用链:
cmd/nvidia_gpu_exporter/main.go // 进程入口,信号处理 └─ internal/app/app.go // 命令行解析、后端装配、HTTP 服务 ├─ internal/nvidiasmi // nvidia-smi 命令执行与输出解析 ├─ internal/collect // 同步/后台采集循环 ├─ internal/exporter // 表格到 Prometheus 指标的转换 └─ internal/nvmlnative // NVML 后端(-nvml 构建)入口 main.go 只做信号处理,把参数交给 app.Run。下面挑几个与日常运维最相关的机制展开。
字段自动发现(AUTO)
--query-field-names默认值AUTO的行为在 resolve.go 中实现:启动时先跑nvidia-smi --help-query-gpu发现可用字段,再跑一次真实的--query-gpu查询建立「查询字段 → 返回列名」的映射。值得注意的是它的降级策略:
- 自动发现失败时,回退到内置字段表(
builtinResolvedFields),保证 exporter 总能起来; - 用户显式指定的字段列表如果内置映射覆盖不了,则直接报错而不是静默替换——「auto 模式必须能启动,显式列表不允许被悄悄改写」是代码注释里写明的原则;
- 无论字段列表来自哪里,都会经过 withRequiredFields 补入一组固定的身份字段(
uuid、name、driver_version、vbios_version、pci_bus_id、serial、index等 11 项,见 infoFields),因为它们支撑nvidia_smi_gpu_info指标,也是所有 GPU 序列按uuid关联的锚点。这也是 CONFIGURE 文档里「nvidia_smi_gpu_info背后的字段不可排除」的原因。
命令执行与防卡死
实际查询在 query.go 中完成:把字段列表拼成--query-gpu=... --format=csv执行,再把 CSV 输出解析成表格。两个防御性细节:
- 命令由 exporter 自己拆分(
SplitCommand)后直接exec,不经过 shell,所以 flag 值无法夹带第二条命令——这是 SECURITY_MODEL.md 里「命令注入」威胁的对策; exec.Cmd.WaitDelay设为 2 秒(query.go 处为waitDelay),即使被杀死的nvidia-smi进程不释放输出管道,采集也不会被永久挂住。
--collect.timeout(默认 10s)约束每个采集周期的总时长,包括启动时的字段发现。超时的周期被记为一次失败采集,而不是挂死 scrape。注意文档也声明了这是 best-effort:卡在不可中断内核等待里的进程杀不死;对 wrapper 命令(如 ssh)只能杀掉 wrapper 本身。
后端选择与参数校验
--collect.backend有三个取值exec/nvml/demo,常量定义在 app.go。参数组合在启动时由 validateBackendFlags 校验,非法组合直接报启动错误而不是静默忽略:
--nvidia-smi-command不能与nvml/demo后端组合(没有命令可定制);--collect.pcie-throughput要求nvml后端;--collect.compute-apps-mig要求nvml或demo后端,且要求开启--collect.compute-apps;--demo-config只在 demo 后端有效。
-nvml发行版构建在构建期把默认后端从exec覆盖为nvml(见 DefaultBackend 的注释),所以-nvml制品开箱即用 NVML 后端,普通静态二进制传这个 flag 会直接报错。
采集模式:同步 vs 后台
--collect.interval=0(默认)时每次 scrape 同步跑一次nvidia-smi,同一时刻到达的多个 scrape 共享同一次运行的结果(多个 Prometheus HA 成员不会放大nvidia-smi进程数)。设置--collect.interval后进入后台模式:nvidia-smi按固定间隔在后台跑,scrape 只读最近一次成功结果,nvidia-smi的进程数从此只取决于间隔。后台模式的注意点(源自 CONFIGURE.md):
- 服务的数据可能陈旧约「一个间隔 + 一次采集时长」,Prometheus 按 scrape 时刻打时间戳,应配合
nvidia_smi_last_collect_success_timestamp_seconds判断数据新鲜度; - 陈旧告警建议留「几个间隔 + timeout」的余量,例如间隔 15s、默认 10s 超时时:
time() - nvidia_smi_last_collect_success_timestamp_seconds > 55 or nvidia_smi_last_collect_success == 0; - 后台运行失败时 GPU 指标会从输出中消失(而不是悄悄变陈旧),
nvidia_smi_last_collect_success报告失败——失败不可见比数据陈旧更糟,这是它的设计取向。
Scrape 侧的三个保护层
从 app.go 可以看到 metrics 端点还内置了两层保护:
- 并发上限:
--web.max-requests默认 40,超限的 scrape 立即收到 503,而不是排队堵在慢采集后面耗尽 goroutine; - 跟随 Prometheus 的超时:scrape 上下文取请求头
X-Prometheus-Scrape-Timeout-Seconds减去--web.timeout-offset(默认 500ms,给响应回传留时间),超时的采集成分被取消,scrape 以nvidia_smi_last_collect_success 0应答,因此不需要手工保证--collect.timeout小于 Prometheus 的scrape_timeout。
/-/healthy与/-/ready是进程级健康检查:只要进程活着就返回 200,与采集成败无关。这样nvidia-smi出问题的机器仍保持可 scrape,故障在健康指标里可见,而不是目标直接从抓取列表里消失。Helm chart 的 liveness/readiness 探针用的就是这两个端点。
快速开始:Docker 五分钟跑起来
在一台装有 NVIDIA 驱动和 NVIDIA Container Toolkit 的 Linux 机器上:
docker run -d --name nvidia_gpu_exporter --restart unless-stopped \ --gpus all -e NVIDIA_DRIVER_CAPABILITIES=utility -p 9835:9835 \ utkuozdemir/nvidia_gpu_exporter:latest curl http://localhost:9835/metrics没有 GPU 也完全可以体验:nvidia_gpu_exporter --collect.backend demo在任何机器上都能服务逼真的合成指标。Windows、macOS、各平台包管理与 Kubernetes 的完整步骤见 docs/INSTALL.md。
三种采集后端详解
exec(默认):跑 nvidia-smi
就是上面机制一节描述的路径。它的独特优势在于:可以用--nvidia-smi-command换成任意命令(sudo、ssh wrapper、甚至测试用的 fake),并且对卡死的驱动调用有最强的隔离——子进程可以被杀掉。
远程采集是 exec 后端的独有能力:exporter 只要求命令的输出「长得像nvidia-smi的输出」,所以可以这样在一台树莓派上采集家里 PC 的 GPU:
nvidia_gpu_exporter --nvidia-smi-command "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null SSH_USER@SSH_HOST nvidia-smi"macOS 的典型用法正是如此:Mac 上没有 NVIDIA GPU,exporter 跑在 Mac 上、通过 SSH 去采集另一台机器的nvidia-smi。注意容器镜像里没有ssh和 shell(distroless),远程采集只适用于二进制安装,或基于官方镜像自建的 fuller base 镜像。
排除慢字段:AUTO 模式下如果某些字段读得慢或触发告警(例如部分 vGPU 客户机里remapped_rows.histogram.*会触发内核告警),可以:
nvidia_gpu_exporter --query-field-names-exclude "remapped_rows.histogram.*" # 或排除多个具体字段 nvidia_gpu_exporter --query-field-names-exclude "inforom.checksum_validation,fan.speed"名称按字面匹配,*是任意字符序列通配。支撑nvidia_smi_gpu_info的身份字段不可排除。
nvml(实验性):直读驱动库
--collect.backend=nvml不再执行nvidia-smi,而是直接读驱动库libnvidia-ml.so.1。对两个后端共同服务的所有查询字段,指标在名称、标签和取值上完全一致(文档说明这已逐字段在真实硬件上核对过),所以现有仪表盘和告警无缝可用。在此之上它提供nvidia-smi给不了的指标族:
- 总能耗计数器
nvidia_smi_energy_joules_total(Volta 及以前的卡没有); - PCIe 吞吐
nvidia_smi_pcie_throughput_{tx,rx}_bytes_per_second,需--collect.pcie-throughput显式开启——驱动对每个方向各用一个 20ms 计数器窗口采样,每 GPU 每次采集约增加 40ms(8 卡节点约 320ms),两个方向是先后采样而非同时成对; - 每个 MIG 实例的指标:
nvidia_smi_mig_info、nvidia_smi_mig_memory_{total,used,free,reserved}_bytes、nvidia_smi_mig_{graphics_activity,sm_activity,sm_occupancy,tensor_activity}_ratio等,无需配置,MIG 实例存在即出现; - XID 错误计数器
nvidia_smi_xid_errors_total与nvidia_smi_xid_last_timestamp_seconds:XID 是驱动层的编号错误事件(卡死的 kernel、ECC 故障、掉线的 GPU),nvidia-smi完全看不到,它们只通过驱动事件或内核日志暴露; - per-process 指标的 MIG 归因标签(
--collect.compute-apps-mig)。
CONFIGURE.md 给出的后端能力对照表值得原样保留:
| 能力 | exec | nvml | demo |
|---|---|---|---|
| 查询字段指标(名称/标签/取值一致) | 是 | 是 | 合成数据 |
带cuda_version标签的gpu_info | 是 | 是 | 是 |
per-process 指标(--collect.compute-apps) | 是 | 是 | 是 |
| 采集状态指标 | command_exit_code | nvml_return_code | nvml_return_code |
| 自定义命令、远程采集(ssh、sudo) | 是 | 否 | 否 |
| 对卡死驱动的最强隔离(可杀子进程) | 是 | 否 | 不适用 |
| 目录追赶前的新驱动字段(AUTO) | 是 | 否 | 否 |
| 总能耗计数器 | 否 | 是 | 是 |
| PCIe 吞吐 | 否 | 是(--collect.pcie-throughput) | 默认开启 |
| per-MIG-instance 指标 | 否 | 是 | 是 |
| per-process MIG 归因 | 否 | 是 | 是 |
| XID 错误计数器 | 否 | 是 | 是 |
它标记为实验性的原因(也即使用它的限制):
- 目前仅 Linux x86_64、glibc 系统,且只存在于专门的
-nvml发行档与-nvml镜像 tag 中;普通二进制保持完全静态,传--collect.backend=nvml会得到错误; - 可查询字段来自编译进二进制的内置目录而非运行时发现,因此不自动是 exec 的超集:少数字段尚无可靠映射而被故意不服务;新驱动加的字段会先出现在默认后端;
- 卡住的驱动调用无法像子进程那样被杀死,
--collect.timeout只约束 scrape 等待时长; - 在 590 分支以前的驱动上,时钟原因指标族在两个后端之间可能一个叫
clocks_throttle_reasons_*一个叫clocks_event_reasons_*(文档说明尚未锁定确切改名版本)。
-nvml构建不需要nvidia-smi二进制,容器里 NVIDIA 运行时注入驱动库即可。它用独立的发布 flavor 分发,镜像 tag 自带该后端并默认启用,无需任何 flag:
docker run -d \ --name nvidia_gpu_exporter \ --restart unless-stopped \ --gpus all \ -e NVIDIA_DRIVER_CAPABILITIES=utility \ -p 9835:9835 \ utkuozdemir/nvidia_gpu_exporter:latest-nvml两个实践提醒:nvidia_smi_*这个指标前缀在两个后端保持不变——它命名的是数据 schema 而非采集机制;如果你的镜像自动化基于 semver 过滤 tag(例如 FluxImagePolicy),-nvml后缀会被解析成 semver pre-release,需要显式过滤 flavor tag,例如filterTags: {pattern: '^(?P<version>\d+\.\d+\.\d+)-nvml$', extract: '$version'}。
demo:无 GPU 的完整体验
--collect.backend=demo在没有 GPU、没有驱动、甚至不是 Linux 的机器上服务一份模仿 nvml 后端完整指标面的合成数据,适合试用 exporter、开发仪表盘和告警。启动时它会打印一条 warn 日志,防止 demo 实例被误认为真实实例:
nvidia_gpu_exporter --collect.backend demo内置配置由 default-config.yaml 定义:回放一份真实捕获的 H200 输出(state: load),仿真 2 张 H200,第一张卡上有 MIG 拓扑,并预置了 XID 79 的历史与 10 分钟间隔的随机事件,使所有指标族开箱就有内容。
NVML-only 指标族在合成时保持自洽:能耗计数器对表格里报告的功耗做积分;MIG 实例构成一致的拓扑(繁忙实例温度高、其余空闲);PCIe 吞吐在可配置范围内抖动;XID 计数器随时间累积。per-process 指标(含 MIG 归因标签)同样可用。
用--demo-config换成自己的场景:
# 内置捕获二选一: # linux-x86_64__nvidia-h200__590.48.01.txt # linux-x86_64__nvidia-geforce-rtx-4080-super__595.71.05.txt capture: linux-x86_64__nvidia-h200__590.48.01.txt state: load # 服务捕获的哪个状态:idle 或 load gpus: 4 # 把捕获的 GPU 复制成这么多 fluctuate: true # scrape 之间抖动自然变化的值 extras: # demo 专属部分,每个键都可省略 seed: 42 # 固定随机性以复现数值 energy-fallback-power-watts: 120 # 功耗字段被排除时使用的兜底值 pcie: tx-bytes-per-second: {min: 0.2e9, max: 3e9} rx-bytes-per-second: {min: 0.5e9, max: 8e9} mig: - gpu: 0 # 仿真 GPU 列表中的索引 instances: - {gi: 2, profile: 3g.71gb, cis: 2, busy: true} - {gi: 7, profile: 1g.18gb} xids: initial: [{gpu: 1, xid: 79, count: 2}] # 预置错误历史 interval: 10m # 后续随机事件的平均间隔,省略即关闭 codes: [13, 31, 79] # 后续事件抽取的码池extras以上部分与仓库里 fakenvidia-smi(cmd/fake-nvidia-smi)共用同一份配置 schema,完整键参考随其文档提供;fake 的故障注入键(exit、delay、stderr-msg、fail-arg)在 demo 模式被忽略,因为它们测的是子进程处理,而 demo 是进程内路径。
配置文件在每个采集周期都会重读:编辑即时生效、无需重启;编辑坏了就表现为一次失败采集(nvidia_smi_last_collect_success 0)直到修好;编辑同时会重置合成状态(能耗/XID 计数器、随机序列),类似驱动重载;唯一例外是cuda_version标签只在启动时读一次。两个容易踩的细节:demo 模式 PCIe 族默认全开,而 nvml 后端需--collect.pcie-throughput——用 demo 数据验证过的仪表盘在 nvml 默认部署上 PCIe 面板会是空的;要完全可复现的数值,设extras.seed并关闭fluctuate。
可视化:两套官方 Grafana 仪表盘
项目提供两套官方仪表盘,它们在 Grafana 里互相有跳转链接:
- Nvidia GPU Metrics(ID
14574):单卡详情视图,覆盖利用率、功耗、温度、时钟、ECC、进程列表、MIG 面板等; - Nvidia GPU Overview(ID
25547):把一台节点上的所有 GPU 并排对比,并可下钻到详情仪表盘。
使用方式有两种:在 Grafana 里按 ID 导入(Dashboards → New → Import),或在 Helm chart 中启用grafanaDashboard让两套仪表盘被自动 provision。两套仪表盘的 JSON 也随仓库发布,位于 docs/grafana(dashboard.json 与 dashboard-overview.json)。
上面文章开头的截图即单卡详情仪表盘:顶部是 Health 状态条,中部为利用率/功耗/风扇/温度的仪表盘组与时钟原因(throttle reasons)时间线,下方依次是显存、ECC、按进程统计的 GPU 进程表、Fabric 状态、XID 事件面板以及 MIG 库存与活动面板。多卡总览仪表盘则把同一节点每张卡的利用率、内存、功耗、时钟、温度、throttle 状态码、ECC、PCIe 吞吐等以多序列曲线并排展示,并在底部保留每张卡的内存条与 MIG 活动条——它是从nvidia_smi_gpu_info按uuid关联所有序列的典型用法。
注意官方仪表盘同时包含 NVML-only 面板(能耗、MIG、XID):在默认 exec 后端下这些面板是空的,在 nvml 后端下会自动填满——这正是 README 所说「同一套仪表盘,换后端即得新指标」的落地形态。
安装:每个平台怎么装
完整分平台步骤在 docs/INSTALL.md,这里按 README 的指针整理关键决策点。
前提:被监控机器上要有 NVIDIA 驱动,且 exporter 能跑nvidia-smi——「nvidia-smi能打出你的 GPU,exporter 就能工作」。例外是-nvmlflavor:它直读驱动库,不需要nvidia-smi,仅存在于 Linux x86_64。装好后监听9835端口,curl http://localhost:9835/metrics自检。文档反复提醒:示例里的latest与X.Y.Z只是占位,生产请锁定具体版本。
Linux(x86_64 与 arm64 都有构建)有三种方式:
- deb/rpm 包:二进制装到
/usr/bin,创建系统用户nvidia_gpu_exporter,安装 systemd unit 并设为开机自启,systemctl status nvidia_gpu_exporter检查。包只支持 systemd; - 纯二进制:从 releases 下对应架构的归档,
tar解出后移入PATH; - 二进制 + 手工 systemd:创建系统用户,把仓库里的 nvidia_gpu_exporter.service 复制到
/etc/systemd/system/,daemon-reload后enable --now。
Docker:镜像不含任何 NVIDIA 组件,GPU 设备、驱动库与nvidia-smi由 NVIDIA Container Toolkit 在容器启动时注入,因此同一镜像适配任意驱动版本、任意 GPU 数量与任意 CPU 架构。容器以 uid 65534(nobody)运行而非 root。三个高频坑:
NVIDIA_*环境变量是配置 NVIDIA 运行时的,不是选择运行时的;没有--gpus/设备预留/runtime: nvidia时容器拿不到 GPU,exporter 仍会启动但只服务自身健康指标,nvidia_smi_last_collect_success 0;- 镜像是 distroless:没有 shell、没有包管理器,
docker exec进不去,也不要在派生镜像里用 shell 写RUN步骤。需要额外工具时基于更完整的 base 拷贝二进制即可,且注意派生镜像的用户由 base 决定; - 无法装 toolkit 的宿主机可手工挂载
/dev/nvidia*、nvidia-smi与libnvidia-ml.so*到默认库目录,但驱动升级会断符号链接,能用 toolkit 就用 toolkit。
Kubernetes:以 DaemonSet 运行,靠 NVIDIA 运行时注入 GPU 访问。最重要的一条红线:不要为 exporter 申请nvidia.com/gpu资源——设备插件按整卡独占分配,监控 pod 申请一张卡等于把卡从真实工作负载手里拿走;环境变量方式让 exporter 看到节点上所有 GPU 而不占用任何一张。Helm chart 即仓库内的 charts/nvidia-gpu-exporter:
helm install nvidia-gpu-exporter oci://ghcr.io/utkuozdemir/charts/nvidia-gpu-exporter \ --set runtimeClassName=nvidia不用 Helm 时可用最小 DaemonSet:镜像 +NVIDIA_VISIBLE_DEVICES=all/NVIDIA_DRIVER_CAPABILITIES=utility环境变量 +runtimeClassName: nvidia(若 NVIDIA 运行时不是默认),端口 9835。托管平台(AKS/GKE/EKS)的 GPU 节点镜像自带驱动与 toolkit,DaemonSet 可直接用。chart README 提供完整 values 参考、ServiceMonitor/PodMonitor/告警/仪表盘等可选项,以及restrictedPod Security Standard 命名空间的 security context 配置——默认安装即可在 restricted 命名空间被准入。
Windows(仅 x86_64 构建):
- all-in-one PowerShell 脚本(install/windows-all-in-one.ps1)在一台机器上装好 exporter、Prometheus 和 Grafana,数据源与两套仪表盘直接 provision 好,重跑安全;
winget install utkuozdemir.nvidia_gpu_exporter(或 Scoop bucket);- 原生 Windows 服务:exporter 自己实现了服务控制管理器协议,
nvidia_gpu_exporter install注册服务,无需 NSSM 等第三方 wrapper;传给install的 flag 会固化进服务命令行(如nvidia_gpu_exporter install --web.listen-address=:9836),重跑install原地重配置,日志写入 Application 事件日志。
macOS:只有 Intel 构建(Apple Silicon 走 Rosetta)。Mac 通常没有 NVIDIA GPU,典型用法即上文提到的远程采集。
发布物验证与供应链安全
README 用一整节强调:发布物都经过签名,可以核实它确实来自本项目的发布流水线:
- release 附带的
checksums.txt有一个 keyless cosign 签名包(checksums.txt.sigstore.json),覆盖所有二进制、归档与包;没有该文件的旧 release 改用 GPG 签名。容器镜像与 Helm chart 同样 keyless 签名并绑定 release workflow 身份;经典 Helm 仓库额外携带 GPG provenance 文件(因为 Helm 只认 GPG); - docs/INSTALL.md 给出确切验证命令,核心是先用 cosign 验签名再校 checksum(
&&保证签名失败不会走到 checksum 那步):
cosign verify-blob checksums.txt \ --bundle checksums.txt.sigstore.json \ --certificate-oidc-issuer=https://token.actions.githubusercontent.com \ --certificate-identity-regexp='^https://github\.com/utkuozdemir/nvidia_gpu_exporter/\.github/workflows/release\.yml@refs/tags/v.*$' && sha256sum --ignore-missing -c checksums.txt- 此外,自 v1.15.1 起 release 文件可复现构建:同一 commit 在任何机器上产出逐字节相同的二进制、归档与包(
-nvml是 cgo 构建,只有匹配的 C 工具链才能复现,发布 runner 是 Ubuntu 24.04 默认 GCC);release workflow 本身会在第二台 runner 上从零重建所有 release 并在校和不一致时失败。你可以用goreleaser release --clean --skip=publish,sign,sbom,docker,announce自建一份再diffchecksums 验证。
安全模型详见 docs/SECURITY_MODEL.md,与本文主题强相关的要点:exporter 只读不写、不改任何 GPU 设置;默认配置下没有任何出站连接(自定义--nvidia-smi-command除外,远程采集就是 ssh);采集失败时它不提供 GPU 数据而不是陈旧数据,失败在自身健康指标里可见;指标端点默认明文 HTTP(与其他 Prometheus exporter 一致),能到达端口的人能看到全部导出内容——包括 GPU 清单(UUID、序列号、PCI 地址、驱动与 VBIOS 版本)以及开启--collect.compute-apps后的进程名与 PID,因此端口应保持在可信网络内,或用--web.config.file启用 TLS 与 basic auth。解析器全部有 fuzz target 且种子语料每次测试重放,未知状态值被跳过并记日志而不是猜测。问题报告走 SECURITY.md。
指标速览
完整的指标说明在 docs/METRICS.md,每块被抓取到的 GPU × 驱动版本 × 负载状态各有一份期望输出文件放在 internal/integration/testdata,是集成测试逐字节对比的基准,也是「一次真实 scrape 长什么样」的最权威样例。结构上:
- 每 GPU 序列都带
uuid标签,与nvidia_smi_gpu_info(携带name、driver_version、vbios_version、cuda_version等身份标签的恒为 1 的 gauge)关联; - 采集健康指标不带
uuid:nvidia_smi_last_collect_success、nvidia_smi_last_collect_success_timestamp_seconds、nvidia_smi_last_collect_duration_seconds、nvidia_smi_failed_scrapes_total(注意它统计的是失败采集而非失败 scrape,名字因兼容保留)、nvidia_smi_command_exit_code(exec 后端;nvml/demo 后端换成nvidia_smi_nvml_return_code,-1表示采集根本没拿到 NVML 状态——超时、被拒、或零可见 GPU,零 GPU 被故意判为失败,防止坏的设备挂载看起来像健康的空闲 scrape)。
摘一段单卡机器的真实 scrape 输出形态(来自 METRICS.md):
# HELP nvidia_smi_gpu_info A metric with a constant '1' value labeled by gpu uuid, name, driver_model_current, driver_model_pending, vbios_version, driver_version, pci_bus_id, serial, compute_cap, pci_sub_device_id, index, cuda_version. # TYPE nvidia_smi_gpu_info gauge nvidia_smi_gpu_info{uuid="df6e7a7c-7314-46f8-abc4-b88b36dcf3aa",name="NVIDIA GeForce RTX 2080 SUPER",driver_version="471.11",cuda_version="11.4",pci_bus_id="00000000:71:00.0",index="0",...} 1 # HELP nvidia_smi_utilization_gpu_ratio utilization.gpu [%] # TYPE nvidia_smi_utilization_gpu_ratio gauge nvidia_smi_utilization_gpu_ratio{uuid="df6e7a7c-7314-46f8-abc4-b88b36dcf3aa"} 0.42 # HELP nvidia_smi_memory_used_bytes memory.used [MiB] # TYPE nvidia_smi_memory_used_bytes gauge nvidia_smi_memory_used_bytes{uuid="df6e7a7c-7314-46f8-abc4-b88b36dcf3aa"} 7.06740224e+08 # HELP nvidia_smi_power_draw_watts power.draw [W] # TYPE nvidia_smi_power_draw_watts gauge nvidia_smi_power_draw_watts{uuid="df6e7a7c-7314-46f8-abc4-b88b36dcf3aa"} 28.07 # HELP nvidia_smi_temperature_gpu temperature.gpu # TYPE nvidia_smi_temperature_gpu gauge nvidia_smi_temperature_gpu{uuid="df6e7a7c-7314-46f8-abc4-b88b36dcf3aa"} 34几个写告警时需要知道的语义:
- 枚举型字段被映射为数值:两态字段(
Enabled/Disabled、Yes/No、Active/Not Active等,涵盖persistence_mode、ecc.mode.*、mig.mode.*、全部clocks_event_reasons.*限频标志)变成 1/0;N/A、[Not Supported]、[Insufficient Permissions]与未识别的值直接不导出并记日志; nvidia_smi_pstate是裸性能状态号(P0 最高性能到 P15),不是负载 gauge;nvidia_smi_gpu_recovery_action > 0是现成的「GPU 不健康」告警源(0 None、1 GPU Reset、2 Node Reboot、3 Drain P2P、4 Drain and Reset);- XID 告警优先用时间戳加显式码白名单而不是 rate:
time() - nvidia_smi_xid_last_timestamp_seconds{xid=~"48|62|64|74|79|95|119|120"} < 300,因为它能覆盖一个序列的首个事件(Prometheus 从未观测过它的 0,increase(...) > 0会漏掉);对所有码告警是噪音——13、31、43 多为应用故障,63、92 属信息性事件。Helm chart 自带按此方式构建好的告警规则。
贡献一份 GPU capture
nvidia-smi的输出随 GPU 型号、驱动版本、操作系统与空闲/负载状态变化很大,项目的应对方式是维护一个真实输出语料库 internal/captures:每个捕获是一个自包含的.txt文件,按<os>-<arch>__<model>__<driver>.txt命名,内容含元数据头与分段命令输出(--help-query-gpu、完整 CSV、--query-compute-apps、idle 与 load 两态等)。这些捕获是「可执行的」:cmd/fake-nvidia-smi 按字面回放捕获文件,internal/integration 的集成测试对语料库里的每个捕获跑真实 exporter 并与 checked-in 的期望输出逐字节比对——所以贡献一份捕获会自动扩展测试套件。
对拥有仓库尚未见过的硬件(新 GPU 型号、全新驱动)的读者,README 给出的贡献流程只需要一条命令:
./internal/captures/collect.sh # 加 --load 再采一份负载样本它只需nvidia-smi、bash与标准 coreutils,只跑只读命令,默认掩码会破坏机器指纹的标识(GPU UUID、序列号、主机名)。生成一个.txt文件后提交并开 PR,或附到 issue 上。Windows 上在 Git Bash / WSL2 里跑同样的命令即可。
参考入口
- 主文档:README.md
- 配置:docs/CONFIGURE.md(完整 flag 参考、后端对照、demo 模式)
- 指标:docs/METRICS.md
- 安装:docs/INSTALL.md
- 安全模型:docs/SECURITY_MODEL.md
- Helm chart:charts/nvidia-gpu-exporter/README.md
- 仪表盘 JSON:docs/grafana/dashboard.json、docs/grafana/dashboard-overview.json
- 集成测试期望输出(真实 scrape 样例):internal/integration/testdata
- 贡献:CONTRIBUTING.md、路线图 docs/ROADMAP.md、治理 GOVERNANCE.md
- 可观测性
- 指标监控
【免费下载链接】nvidia_gpu_exporter
Nvidia GPU exporter for prometheus using nvidia-smi binary OR using NVML
相关推荐
【亲测免费】 Nvidia GPU Exporter for Prometheus: 监控GPU的新维度
Nvidia GPU Exporter for Prometheus: 监控GPU的新维度 项目基础介绍及编程语言 Nvidia GPU Exporter是一款
可观测性指标监控Zephyr RTOS 快速上手指南:无需硬件 10 分钟跑通第一个嵌入式程序
Zephyr RTOS 快速上手指南:无需硬件 10 分钟跑通第一个嵌入式程序 第一次运行 Zephyr RTOS(面向资源受限设备的实时操作系统)应用时,你会
操作系统嵌入式RTOS物联网Nvidia GPU Exporter 教程
Nvidia GPU Exporter 教程 1. 项目介绍 Nvidia GPU Exporter 是一个用于Prometheus监控的工具,通过调用nvid
可观测性指标监控
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考