NVIDIA DCGM 监控落地:从指标采集到 Prometheus 对接
NVIDIA DCGM 监控落地从指标采集到 Prometheus 对接一、GPU 出问题靠用户投诉才发现这不能叫监控多数 AI 平台的第一版 GPU 监控止步于nvidia-smi的整卡利用率和显存使用量。这种粗粒度监控在集群处于 10 张卡以下时够用一旦集群扩展到百卡规模缺乏进程级、SM 级和 PCIe 带宽级的可观测性会让排障变成猜谜游戏。实际场景中推理服务响应变慢可能有数十种根因。是 GPU 过热降频是 ECC 错误触发了显存重映射是 PCIe 链路降级导致数据传输降速没有 DCGM 级别的细粒度指标你只能在 Prometheus 面板上看到GPU 利用率掉了这一条曲线然后逐个节点登录nvidia-smi排查。基础设施不需要漂亮话GPU 的可观测性必须覆盖从硬件传感器到底层驱动再到容器内进程的完整链路。NVIDIA Data Center GPU ManagerDCGM是目前最成熟的开源 GPU 监控方案提供了 70 个覆盖功耗、温度、时钟频率、ECC、PCIe、NVLink 和进程维度的指标。二、DCGM 的指标采集架构与 Prometheus 集成路径DCGM 的架构分为三层内核态的 NVIDIA 驱动暴露 GPU 硬件计数器DCGM Hostengine 作为守护进程运行在节点上收集和聚合硬件指标DCGM-Exporter 将 DCGM 的 C API 转换为 Prometheus 格式的 HTTP 端点。graph TB subgraph GPU 节点 GPU[GPU 硬件br/SM / 显存 / NVLink / 温度传感器 / ECC] Driver[NVIDIA Kernel Driverbr/nvidia.ko / nvidia-uvm.ko] DCGMHost[DCGM Hostenginebr/nv-hostengine 守护进程] DCGMExport[DCGM Exporterbr/HTTP :9400/metrics] GPU --|硬件计数器| Driver Driver --|ioctl / sysfs| DCGMHost DCGMHost --|C API 查询| DCGMExport end subgraph 监控层 Prom[Prometheusbr/指标采集与存储] Grafana[Grafanabr/可视化面板] AlertMgr[Alertmanagerbr/告警路由] end DCGMExport --|HTTP Pull /metrics| Prom Prom -- Grafana Prom -- AlertMgr subgraph 关键指标 M1[DCGM_FI_DEV_GPU_UTILbr/GPU 利用率] M2[DCGM_FI_DEV_FB_USEDbr/显存使用量] M3[DCGM_FI_DEV_ECC_ERROR_COUNTbr/ECC 错误计数] M4[DCGM_FI_DEV_PCIE_TX_THROUGHPUTbr/PCIe 吞吐量] M5[DCGM_FI_DEV_POWER_USAGEbr/功耗] M6[DCGM_FI_PROF_SM_ACTIVEbr/SM 活跃度] end DCGMExport -.- M1 DCGMExport -.- M2 DCGMExport -.- M3 DCGMExport -.- M4 DCGMExport -.- M5 DCGMExport -.- M6 style GPU fill:#4caf50,color:#fff style Prom fill:#ff9800,color:#fff style AlertMgr fill:#f44336,color:#fffDCGM Hostengine 的运行需要 root 权限才能访问 NVIDIA 驱动的内核接口。在生产环境中通过 NVIDIA GPU Operator 的dcgm组件以 DaemonSet 形式自动部署到每个 GPU 节点规避手动安装的管理难题。GPU Operator 同时管理驱动、Container Toolkit 和 DCGM 组件的生命周期和版本兼容性。Prometheus 的采集配置需要为 DCGM Exporter 单独设置 job区别于 Node Exporter 和 kubelet 的 job。DCGM 的指标以DCGM_FI_DEV_为前缀字段 2000 是完整列表但实际生产只需关注 15-20 个核心指标。三、生产级 DCGM 部署与告警配置以下是 DCGM Exporter 的部署 YAML 和配套的 Prometheus 告警规则。# dcgm-exporter-daemonset.yaml — DCGM Exporter DaemonSet 部署 apiVersion: apps/v1 kind: DaemonSet metadata: name: dcgm-exporter namespace: gpu-observability labels: app: dcgm-exporter spec: selector: matchLabels: app: dcgm-exporter template: metadata: labels: app: dcgm-exporter spec: nodeSelector: nvidia.com/gpu.present: true # 仅在 GPU 节点上调度 hostNetwork: true # 使用宿主机网络访问 GPU 驱动 hostPID: true # 需要访问宿主机进程 containers: - name: dcgm-exporter image: nvcr.io/nvidia/k8s/dcgm-exporter:3.3.6-3.4.2-ubuntu22.04 ports: - containerPort: 9400 name: metrics protocol: TCP env: - name: DCGM_EXPORTER_KUBERNETES value: true # 启用 K8s Pod/Namespace 标签注入 - name: DCGM_EXPORTER_LISTEN value: :9400 - name: DCGM_EXPORTER_INTERVAL value: 10000 # 采集间隔 10 秒毫秒 volumeMounts: - name: pod-resources mountPath: /var/lib/kubelet/pod-resources readOnly: true resources: requests: memory: 128Mi cpu: 100m limits: memory: 512Mi cpu: 500m livenessProbe: httpGet: path: /health port: 9400 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /metrics port: 9400 initialDelaySeconds: 10 periodSeconds: 5 volumes: - name: pod-resources hostPath: path: /var/lib/kubelet/pod-resources tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule对应的 Prometheus 告警规则覆盖 GPU 利用率、显存、温度和 ECC 错误四大类// dcgm_alert_generator.go — DCGM 告警规则自动生成器 // 职责根据 GPU 型号和集群配置生成 PrometheusRule CRD // 注意不同 GPU 型号的降频温度和 TDP 差异较大告警阈值需按型号定制 package main import ( fmt time monitoringv1 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1 metav1 k8s.io/apimachinery/pkg/apis/meta/v1 k8s.io/apimachinery/pkg/util/intstr ) // GPUAlertThreshold 定义特定 GPU 型号的告警阈值 type GPUAlertThreshold struct { Model string // 如 A100-SXM4-80GB TempCriticalC float64 // 临界温度摄氏度 TempWarningC float64 PowerCriticalW float64 // 功耗上限 ECCDramThreshold int // DRAM ECC 错误阈值 ECCSramThreshold int // SRAM ECC 错误阈值 } // 常用 GPU 型号阈值参考 var defaultThresholds map[string]GPUAlertThreshold{ A100-SXM4-80GB: { Model: A100-SXM4-80GB, TempCriticalC: 85.0, TempWarningC: 80.0, PowerCriticalW: 400.0, ECCDramThreshold: 10, ECCSramThreshold: 10, }, A100-SXM4-40GB: { Model: A100-SXM4-40GB, TempCriticalC: 85.0, TempWarningC: 80.0, PowerCriticalW: 400.0, ECCDramThreshold: 10, ECCSramThreshold: 10, }, H100-SXM-80GB: { Model: H100-SXM-80GB, TempCriticalC: 85.0, TempWarningC: 80.0, PowerCriticalW: 700.0, ECCDramThreshold: 10, ECCSramThreshold: 10, }, } // GeneratePrometheusRule 为指定 GPU 型号生成 PrometheusRule CR func GeneratePrometheusRule(gpuThreshold GPUAlertThreshold, namespace string) *monitoringv1.PrometheusRule { return monitoringv1.PrometheusRule{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf(dcgm-gpu-alerts-%s, gpuThreshold.Model), Namespace: namespace, Labels: map[string]string{ release: prometheus, role: alert-rules, }, }, Spec: monitoringv1.PrometheusRuleSpec{ Groups: []monitoringv1.RuleGroup{ { Name: fmt.Sprintf(dcgm.gpu.%s, gpuThreshold.Model), Interval: ptrStr(30s), Rules: []monitoringv1.Rule{ // 规则 1GPU 温度告警 { Alert: DCGM_GPU_TemperatureHigh, Expr: intstr.FromString( fmt.Sprintf(DCGM_FI_DEV_GPU_TEMP{gpu_model~\%s\} %f, gpuThreshold.Model, gpuThreshold.TempWarningC)), For: 5m, Labels: map[string]string{ severity: warning, category: gpu-health, }, Annotations: map[string]string{ summary: fmt.Sprintf(GPU 温度超过 %.0f°C, gpuThreshold.TempWarningC), description: GPU {{ $labels.UUID }} 当前温度: {{ $value }}°C, 可能触发降频, }, }, // 规则 2显存使用率告警 { Alert: DCGM_GPU_MemoryHigh, Expr: intstr.FromString( (DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_TOTAL) 0.95), For: 5m, Labels: map[string]string{ severity: critical, category: gpu-memory, }, Annotations: map[string]string{ summary: GPU 显存使用率超过 95%, description: GPU {{ $labels.UUID }} 显存: {{ $value | humanizePercentage }}, 即将 OOM, }, }, // 规则 3ECC 错误告警 { Alert: DCGM_GPU_ECCError, Expr: intstr.FromString( rate(DCGM_FI_DEV_ECC_DBE_VOL_TOTAL[5m]) 0), For: 1m, Labels: map[string]string{ severity: critical, category: gpu-ecc, }, Annotations: map[string]string{ summary: 检测到 GPU 不可纠正 ECC 错误, description: GPU {{ $labels.UUID }}: 出现 Double-Bit ECC 错误, 建议立即检查硬件, }, }, }, }, }, }, } } func ptrStr(s string) *string { return s }四、DCGM 的性能开销与采样精度权衡DCGM Hostengine 采集 GPU 硬件计数器时会产生轻微的性能开销。根据 NVIDIA 的官方数据在 10 秒采集间隔下DCGM 对 GPU 计算性能的影响低于 0.1%几乎可以忽略。但将采集间隔缩短到 1 秒时频繁的 ioctl 调用和 PCIe 总线查询可能导致可观测的性能抖动。采样间隔的选择需要在告警灵敏度和性能影响之间平衡。推荐配置GPU 温度和功耗10-15 秒采样变化缓慢显存使用量5-10 秒采样OOM 前留出反应时间ECC 错误计数30 秒采样错误频率低SM 利用率和 PCIe 吞吐量5 秒采样核心性能指标指标基数的控制。DCGM 的DCGM_FI_PROF_*系列指标是 SM 级别的计数器在一张拥有 108 个 SM 的 A100 上会产生 108 条时间序列。百卡集群仅 SM 指标就可能超过 10000 条对 Prometheus 的存储和查询形成压力。建议在 DCGM Exporter 的default-counters.csv中关闭不需要的 SM 级指标只保留整卡级别的聚合指标。NVLink 监控的补充。多卡训练场景中NVLink 的带宽和错误率直接决定训练效率。DCGM 提供了DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL和DCGM_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_TOTAL指标。NVLink 链路的 CRC 错误通常意味着物理连接松动或损坏这类告警需要在 5 分钟内响应。五、总结DCGM Prometheus Grafana 是 GPU 可观测性的标准组合。落地路径通过 GPU Operator 部署 DCGM避免手动管理 Hostengine 和 Exporter 的版本依赖。关闭不需要的 SM 级指标在default-counters.csv中只保留核心整卡指标。告警规则按 GPU 型号定制A100 和 H100 的功耗、温度阈值不同不能用一套模板。结合 Node Exporter 做关联分析GPU 的 PCIe 带宽下降可能和宿主机的 CPU 节流相关。