资讯详情

K8s GPU监控实战:DCGM+Prometheus+告警全链路搭建与踩坑记录

📅 2026/10/1 11:39:51 | 华诺云谱 👁 阅读
K8s GPU监控实战:DCGM+Prometheus+告警全链路搭建与踩坑记录
做平台这套活儿的人最怕听到的一句话是“那个GPU节点是不是挂了我任务提交半天了也没跑起来。”你跑到节点上敲一句nvidia-smiGPU利用率99%显存快占满温度直逼90度。可到底是谁在跑跑了多久为什么事先没有任何人知道如果每次都靠人肉登节点排查那运维这条命就不是自己的了。我在维护Kubernetes集群的过程中把GPU监控从零搭到了能稳定进生产的状态。选型最终落到了DCGM DCGM Exporter Prometheus Grafana这一条链路上配合Alertmanager做告警通知。这篇文章就是把这套方案的完整过程写下来包括组件怎么选、指标怎么定、告警阈值怎么调、踩过哪些坑。适合正在用K8s跑AI训练和推理任务、想真正掌握GPU资源实时状况的运维和平台工程师参考。无论你是第一次接触GPU监控还是已经在用Prometheus但没接GPU这篇都可以帮你少走不少弯路。1. 为什么要在Kubernetes里做GPU监控1.1 先搞懂GPU在K8s里是怎么被使用的要回答“为什么监控这么重要”先得说清楚GPU这种资源在Kubernetes里和CPU、内存有什么本质区别。CPU和内存是标准可压缩资源而GPU是一种“整卡分配”的特殊资源。NVIDIA为K8s实现了一套Device Plugin机制kubelet通过gRPC调用nvidia-device-plugin由插件上报当前节点上有几张卡、每张卡有多少显存。调度器把这个信息当成扩展资源允许用户用nvidia.com/gpu来申请。当某个Pod声明了resources.limits[nvidia.com/gpu]: 1调度器会找到一个“至少有1整张卡空闲”的节点把Pod调度过去。但注意这里说的“空闲”不是指利用率低而是指整张卡没有被别的Pod请求分配。默认情况下Kubernetes不支持一张卡被多个Pod共享要么整卡独占要么不分配。这个机制对监控设计影响很大。调度器只关心“卡有没有被分配”完全不关心“卡用得怎么样”。一张卡被分配出去之后利用率和温度是20%还是已经打满显存有没有泄漏卡是不是正在产生ECC错误这些信息kubelet一概不知。它们不在调度器的视野里自然也不会出现在kubectl top node的输出中。想拿到这些数据必须依赖节点层面的GPU管理组件来采集再通过标准接口暴露出来。1.2 不监控GPU会踩哪些真实的大坑监控这事属于“平时觉得多余出事才后悔没上”的一类。我这里整理了几类高频事故场景基本都是我在真实集群里见过或者处理过的。第一类是显存泄漏。训练任务跑了一天显存被一点点吃满最后进程OOM被系统杀掉。如果没有监控盯着要等到任务失败才发现而前一天的算力已经白瞎了。更难受的是这种问题还不是每次必现没有曲线根本没法判断是代码问题还是数据问题。反过来只要有一条显存随时间增长的曲线哪怕提前半小时告警都能帮你保住一个阶段性的训练结果。第二类是GPU硬件故障。DCGM能捕获XID错误、ECC错误、温度异常等信号。这类故障如果不去主动监控卡会逐渐进入一个“半坏”状态。表面上看nvidia-smi还有输出设备也不算“消失”但一旦调度器把新任务放上去任务就马上崩溃。最麻烦的是这种故障没有固定规律可能是跑三天才触发一次也可能是启动数小时就挂。不靠指标追踪排查成本会非常高。第三类是利用率失真。我见过不少团队按“整卡独占”的方式申请GPU但业务实际只用了30%不到。假如一个集群有100张卡真实算力利用率只有四成那新采购的决策就完全没依据后端支撑团队也讲不清楚资源到底够不够。没有监控数据所谓容量规划全是拍脑袋。我自己的结论是GPU监控不只是“加个大屏”那么表层它是一个基础设施级的可观测性要求和CPU、内存、网络监控平级甚至要更重视因为GPU的故障模式和资源特征更特殊一旦出问题影响的是一个个训练好的模型和一条条线上的推理服务。2. GPU监控方案选型为什么我选了DCGM Prometheus2.1 市面上主流方案对比做监控方案选型没必要重复造轮子。先看看市面上有哪些可选路线再根据团队实际规模做取舍。方案采集层暴露方式优点缺点手写脚本轮询nvidia-sminvidia-smi自定义文本或JSON实现简单适合几个节点快速看指标有限、格式不标准、轮询太频伤GPU、容易漏关键错误DCGM命令行手动执行DCGM命令行输出官方工具健康诊断全面每次都要登录节点不适合集中采集和长期追踪DCGM Exporter PrometheusDCGMPrometheus格式/metrics指标标准化、支持MIG和多卡、配合告警容易需要额外搭建Prometheus和Grafana商业GPU调度与监控平台自带采集器REST API面板开箱即用、常带调度和租户隔离部署较重、成本高、有厂商绑定风险如果你问我的话小规模实验环境用手写脚本也算可以接受但生产集群绝对不要这么干。手写脚本要处理的东西太多了Prometheus格式怎么暴露、Counter类型指标怎么递增、GPU卡换了UUID怎么处理、XID和ECC错误要不要采集还要维护一套和K8s Pod对应的标签映射。这不是脚本能优雅解决的问题。2.2 DCGM能给你哪些nvidia-smi给不了的关键指标DCGM全称NVIDIA Data Center GPU Manager是NVIDIA官方提供的GPU数据中心管理套件。它做的事远不止“看利用率”这么简单。除了我们直觉里能想到的GPU利用率、显存占用、温度、功耗之外它还能输出一批对生产环境极其关键的健康类指标XID错误计数对应DCGM_FI_DEV_XID_ERRORS驱动或硬件层面的错误信号出现即代表有严重问题。ECC错误计数对应DCGM_FI_DEV_ECC_DBE_AGG_TOTAL显存纠错机制开始记录不可纠正错误是硬件衰退的早期信号。NVLink链路CRC错误计数对应DCGM_FI_DEV_NVLINK_LINK_CRC_ERRORS多卡通信如果出现大量CRC错误分布式训练效率会骤降。SM和内存时钟频率对应DCGM_FI_DEV_SM_CLOCK、DCGM_FI_DEV_MEM_CLOCK可以判断GPU是否因为过热或功耗限制发生了降频。MIG设备级指标GPU实例被切分后每个实例单独的利用率和显存数据都能暴露出来。这些指标用普通nvidia-smi脚本很难完整拿到。所以选型时我最看重的一点就是DCGM的数据面足够深能让我在GPU彻底坏掉之前提前发现苗头。2.3 组件分工与整体数据流整个架构用一句话描述就是每个GPU节点上跑一个DCGM Exporter容器通过挂载主机的DCGM库和NVIDIA管理库在9400端口暴露Prometheus格式的指标Prometheus定时抓取这些指标存进时序数据库Grafana负责可视化展示告警规则配置在Prometheus里触发后由Alertmanager发送到钉钉、邮件或企业微信。数据流是单向的GPU硬件 - NVML/DCGM库 - DCGM Exporter - Prometheus - Grafana和Alertmanager。我为什么坚持用Prometheus这套生态而不是自己写个采集服务核心原因是它把“存储、查询、告警”三件事都标准化了。GPU指标一旦进了Prometheus就能复用团队已有的告警渠道、看板权限体系甚至能配合其他基础设施指标做关联分析不用再为某一个监控场景单独造一套系统。另一个考虑是把采集组件做轻DCGM Exporter是无状态容器不依赖外部存储不占用业务Pod资源部署和升级都极其简单。另外有一点设计上的取舍值得一提。我在生产环境里把Prometheus独立部署在集群外的一个专用节点上或者单独放一个namespace并限制资源不让它和业务任务抢CPU和内存。因为如果Prometheus自身资源受限导致抓取超时监控本身就成了最不可靠的环节那告警和数据就都失去意义了。3. 从零搭建环境准备与组件部署3.1 动手前必须检查的三项前置条件第一步先把地基打牢。我通常登录每台GPU节点做三项检查# 检查驱动和可见GPU nvidia-smi --query-gpuindex,name,memory.total,driver_version --formatcsv # 通过kubectl查看节点是否已经上报GPU资源 kubectl get node gpu-node -o json | jq .status.allocatable如果驱动正常nvidia-smi能看到卡但allocatable里没有nvidia.com/gpu说明device plugin还没装或者没生效后面监控无从谈起。另外要确认容器运行时是containerd或Docker并且装好nvidia-container-toolkit否则即使node上报了GPUPod里也访问不到设备。一个容易被忽略的点device plugin的版本要和K8s版本匹配。我早期在K8s 1.26集群里用过较旧的plugin出现过节点上报数量和实际卡数不一致的怪问题。建议安装前到NVIDIA官方GitHub查release兼容矩阵别直接用“最新版”三个字带过。3.2 安装NVIDIA Device Plugindevice plugin本身是官方提供的一个DaemonSet安装非常简单kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.16.0/nvidia-device-plugin.yml装完以后验证两件事。第一Pod是否Runningkubectl -n nvidia-device-plugin get pods -o wide第二节点是否上报了资源kubectl get node gpu-node -o json | jq .status.allocatable如果能看到nvidia.com/gpu: 4这样的字段说明调度器已经认识GPU了。这里我还会额外看一眼kubelet日志里有没有NVML初始化失败之类的内容因为有些节点驱动虽然能在shell里跑nvidia-smi但容器内访问设备时会遇到权限问题。3.3 部署DCGM ExporterDCGM Exporter官方推荐用Helm安装操作起来最省心helm repo add nvidia https://helm.ngc.nvidia.com/nvidia helm update helm install dcgm-exporter nvidia/dcgm-exporter -n gpu-monitoring --create-namespace这条命令会创建一个DaemonSet让每个GPU节点都跑一个Exporter容器。它默认挂载的内容很关键我拆开给你看挂载/usr/local/dcgm这是DCGM自身的库文件目录。挂载/usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1等NVIDIA管理库Exporter初始化NVML需要它。挂载/var/run用于容器运行时与NVIDIA设备通信。这里我必须指出一个我踩过的坑如果你手工写yaml部署别只挂载nvidia-smi这个可执行文件DCGM Exporter真正需要的是共享库而不是命令行工具。我第一次手工精简挂载后容器能启动但/etrics接口返回为空后来排查了一圈才发现是libnvidia-ml.so.1没有挂进去DCGM无法初始化NVML。装完以后可以用端口转发先做一次验证kubectl -n gpu-monitoring port-forward svc/dcgm-exporter 9400:9400 curl localhost:9400/metrics | grep DCGM_FI_DEV_GPU_UTIL能返回类似DCGM_FI_DEV_GPU_UTIL 23这样的数据说明采集链路已经通了。3.4 让Prometheus接入采集目标Prometheus如果部署在集群内可以直接通过ServiceMonitor或者简单的scrape_config发现端点。以我常用的方式为例配置一个基于Kubernetes服务发现的抓取任务scrape_configs: - job_name: dcgm-exporter kubernetes_sd_configs: - role: endpoints relabel_configs: - source_labels: [__meta_kubernetes_endpoints_name] action: keep regex: dcgm-exporter如果Prometheus和K8s集群不在同一网络可以先把Exporter的Service改成NodePort类型然后在Prometheus的静态配置里填节点IP和NodePort端口。两种方式在采集效果上没有本质差别主要看你的部署架构。配置完去Prometheus的Targets页面确认状态是UP。我建议顺手配一个scrape_interval: 15s不要用默认的1分钟。GPU利用率变化非常快一分钟一个点对后面判断“某任务开始跑”这种场景来说太粗了。3.5 配置Grafana可视化面板Grafana导入面板有两种方式。第一种是直接导入社区现成的DCGM Exporter Dashboard去grafana.com搜dcgm-exporter拿到Dashboard ID一键导入。第二种是自己画核心查询无非是几个固定表达式# 利用率 DCGM_FI_DEV_GPU_UTIL # 显存使用 DCGM_FI_DEV_FB_USED # 温度 DCGM_FI_DEV_GPU_TEMP # 功耗 DCGM_FI_DEV_POWER_USAGE维度上建议用instance加GPU_UUID或GPU_I_ID做区分这样多卡节点上哪张卡有问题可以一目了然。我第一次画面板的时候漏了UUID维度的区分结果四张卡的曲线全部叠在一起完全没法看。后来加上维度标签才真正实现了“一卡一线”。4. 生产级实践指标解读、告警规则与资源优化4.1 必盯的GPU指标清单与阈值建议监控搭起来只是第一步真正见功夫的是指标解读和阈值设定。我把生产环境里最常用的指标整理成了一张速查表方便直接对照使用。指标含义为什么盯它建议观察或告警阈值DCGM_FI_DEV_GPU_UTILGPU核心利用率百分比判断算力是否真正打满持续95%以上关注调度长期过低检查业务是否异常DCGM_FI_DEV_FB_USED / FB_TOTAL显存使用量防显存泄漏和OOM使用率超过90%持续5分钟告警DCGM_FI_DEV_GPU_TEMP核心温度散热和硬件老化信号超过85度持续10分钟告警DCGM_FI_DEV_POWER_USAGE实时功耗功耗过高影响散热和成本接近TDP上限时关注并检查负载DCGM_FI_DEV_XID_ERRORSXID错误计数驱动或硬件严重错误信号任何新增计数都应立即告警DCGM_FI_DEV_ECC_DBE_AGG_TOTAL不可纠正ECC错误累计显存硬件健康衰退出现增长即告警并准备换卡DCGM_FI_DEV_MEM_COPY_UTIL显存拷贝引擎利用率部分场景判断IO型瓶颈和GPU_UTIL配合分析单独看意义有限DCGM_FI_DEV_NVLINK_LINK_CRC_ERRORSNVLink链路CRC错误多卡通信可靠性下降持续增长要重点排查阈值本身没有统一标准需要根据你的硬件型号和散热条件调整。A100和RTX 3090的温度容忍度就完全不同千万不要照抄网上某篇文章就直接上。我的建议是先观察一周基线再定阈值一开始宁可宽松一些也不要上来就告警刷屏。4.2 一套可以直接抄的告警规则告警规则我用的是Prometheus原生Rule语法下面这几条是我现在生产环境还在用的核心规则。注意这几个表达式我都已经跑过很长时间没有误报问题。groups: - name: gpu-alerts rules: - alert: GPUHighTemperature expr: DCGM_FI_DEV_GPU_TEMP 85 for: 10m labels: severity: warning annotations: summary: GPU {{ $labels.instance }} 温度过高 - alert: GPUHighMemoryUsage expr: (DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_TOTAL) * 100 90 for: 5m labels: severity: warning annotations: summary: GPU {{ $labels.instance }} 显存使用率超90% - alert: GPUXIDError expr: increases(DCGAM_FI_DEV_XID_ERRORS[5m]) 0 labels: severity: critical annotations: summary: GPU {{ $labels.instance }} 检测到XID错误这里有一个细节值得展开说一下。对XID这种Counter类型的指标用increases()函数比delta()更可靠因为它在计数器重置时也能给出准确的变化量不容易产生“从0变成1就误告”或者“重启后计数器清零导致漏告”的问题。XID错误一旦出现就是实打实的故障信号不需要加for时长所以我故意没写for让它立即触发。4.3 用监控数据反向优化资源分配监控做到位以后最大的红利其实是资源调优。这一步才是让监控从“花钱的运维系统”变成“省钱的管理工具”的关键。我做过几次比较有效的优化。第一是从Grafana聚合视图里按节点排序找出长期利用率低于20%的卡。早期不少业务团队都习惯申请“一张整卡”但实际训练负载根本不饱和我根据两周的曲线说服他们把任务合并或者改用共享调度集群整体吞吐量提升非常明显。第二是配合K8s的GPU共享能力做资源规格化。如果业务方对显存隔离要求不高可以考虑用NVIDIA官方device plugin的time-slicing能力把一张物理卡切分成多个时间片分配给不同Pod。注意time-slicing不隔离显存多个Pod依然共享同一份显存空间出问题时会互相影响。如果业务方需要严格隔离那就得考虑MIG方案。MIG能把A100、H100这类卡切分成多个真正独立的GPU实例每个实例有独立算力和显存配额DCGM Exporter也能按MIG实例输出指标监控维度上完全兼容。第三是从request和limit层面做约束。很多人对GPU资源的request和limit习惯性都设成1但一旦上了共享调度就应该引导业务方按真实需求填写。平台方还能通过准入控制强制声明规范避免有人故意申请整卡却闲置不用。4.4 非NVIDIA GPU的监控补充现在不少团队已经在用AMD GPU或者华为昇腾NPU跑推理这类设备和NVIDIA没法共用DCGM但监控骨架完全一致。AMD这边可以用rocm-exporter它基于ROCm SMI暴露Prometheus格式指标Prometheus接入方式和DCGM Exporter几乎没有差别。昇腾NPU这边比较主流的是基于dcmiDevice Command Management Interface写自定义Exporter或者直接用社区里的ascend-exporter暴露NPU利用率、内存占用、温度等核心指标。架构上我的建议是给每一个设备类型建一个独立job_name比如dcgm-exporter、rocm-exporter、ascend-exporter在Grafana里做下拉筛选。这样一套Prometheus就能同时管多种异构加速设备扩展成本几乎为零。这块的热度这两年涨得很快我预计异构GPU监控会成为平台团队的常规需求。5. 常见问题与排查技巧实录5.1 节点nvidia-smi正常Exporter却采集不到数据这个现象非常典型Pod显示Running日志也没有Fatal错误但curl /metrics返回的结果是空的或者只有少量非GPU指标。排查顺序我一般是这样先进入Exporter容器确认DCGM的库文件是否真的存在kubectl exec -it pod -- ls /usr/local/dcgm kubectl exec -it pod -- nvidia-smi如果容器里没有nvidia-smi说明NVIDIA管理库没挂全。看Exporter日志重点找两句话kubectl logs pod常见错误是Failed to initialize NVML这几乎可以断定是libnvidia-ml.so.1缺失或版本不匹配。检查挂载配置确认挂载的是文件而不是不存在的目录。这里我给出的建议很直接不要自己精简DCGM Exporter的镜像和挂载参数直接用官方Helm Chart部署。它把该处理的环境、挂载、安全上下文都内置好了。我最初手搓yaml在这上面折了好几个小时后来老老实实换回官方Chart半小时搞定。5.2 显存占满但利用率很低是怎么回事现象是FB_USED接近上限但GPU_UTIL不到10%。这种情况大概率是两种原因。第一种是推理服务正常形态。比如一个NLP模型常驻显存但线上请求稀疏显存占用高而算力利用低这是预期行为。这时候不要告警反而应该用显存曲线做容量水位判断看是否还能多塞几个模型副本。第二种是显存碎片化。多租户反复申请和释放显存后就会出现碎片堆积新任务申请不到大块连续显存表现为“明明有剩余空间却分配失败”。这种情况靠重启Pod不一定能解决需要从任务调度角度错开大模型和小请求的混部。判断属于哪一种主要是看显存曲线的形态。如果是一条单调递增且不回落的曲线基本就是泄漏。如果曲线围绕一个水平线波动说明是稳态占用。5.3 GPU利用率突然拉满怎么快速定位是谁在跑遇到这种情况时间就是金钱。我的操作顺序是先在Grafana或Prometheus里查DCGM_FI_DEV_GPU_UTIL最高的instance锁定具体是哪台节点、哪张卡。登录节点执行nvidia-smi -pmon拿到进程级PID和对应显存消耗。这一步能看清卡上的进程但通常只能看到PID看不到业务身份。用kubectl get pods -o wide把GPU节点上的Pod全部列出来结合容器的PID映射过去才能定位到具体业务。更高效的办法是用DCGM Exporter新版自带的标签。它在指标里会附带container_id和pod_name标签你可以在Prometheus里直接按Pod维度聚合GPU利用率sum by (pod_name) (DCGM_FI_DEV_GPU_UTIL)这样可以直接跳过进程PID到Pod的映射步骤。推进团队日常巡检时我还习惯把这张查询做成Grafana面板的TopN视图谁在跑大任务、谁在空转一眼全清楚。5.4 告警刷屏怎么控制告警刷屏是新手最容易遇到的问题处理不好团队会直接对告警脱敏后续真正严重的故障反而没人理会。我常用几个手段来控噪for字段不要设0温度、显存这类有波动的指标至少给5到10分钟的持续期避免瞬时抖动触发。Alertmanager的repeat_interval默认是4小时也可以改成1小时但不要设太短否则同一问题会在群里反复轰炸。在告警规则里对多卡节点进行聚合用instance维度把同一节点多条GPU告警合并成一条不然四张卡同时超温就会有四条告警非常干扰判断。告警文案里不要写死节点名用{{ $labels.instance }}动态填充否则节点扩缩容后过期的告警模板会产生大量无效通知。最后补充一个经验告警规则要定期复盘。GPU硬件的衰退是缓慢过程一周、一个月的趋势比单次告警更有价值。我会让团队每个月抽出半小时拉一次最近30天的XID错误、ECC错误和温度曲线看看有没有“温水煮青蛙”式恶化的卡提前安排更换或下线。我在实际维护这套GPU监控体系的过程中最大的感受是搭建本身不复杂真正花时间的是持续跟进指标变化、调优阈值、梳理告警干扰。GPU故障往往不是“啪一下坏了”而是从某个隐藏指标慢慢崩坏的。DCGM Prometheus这套方案的意义就是把这些隐藏信号在变成事故之前暴露出来。我已经靠这套监控提前拦下过至少两次显存泄漏和一次GPU硬件故障省下的资源重训时间远比搭建监控本身投入的成本更值得。如果你们的集群里也跑着GPU真的建议尽快把监控跑起来。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑