dcgm-exporter部分指标

dcgm-exporter相关指标丢失排查

目录

  • 官方文档先放前面
  • 背景
  • 现象
  • 排查过程
    • [1. 宿主机 GPU 正常](#1. 宿主机 GPU 正常 "#1-%E5%AE%BF%E4%B8%BB%E6%9C%BA-gpu-%E6%AD%A3%E5%B8%B8")
    • [2. 容器内 NVML 失败](#2. 容器内 NVML 失败 "#2-%E5%AE%B9%E5%99%A8%E5%86%85-nvml-%E5%A4%B1%E8%B4%A5")
    • [3. 设备文件还在](#3. 设备文件还在 "#3-%E8%AE%BE%E5%A4%87%E6%96%87%E4%BB%B6%E8%BF%98%E5%9C%A8")
    • [4. dcgm-exporter 主进程还在](#4. dcgm-exporter 主进程还在 "#4-dcgm-exporter-%E4%B8%BB%E8%BF%9B%E7%A8%8B%E8%BF%98%E5%9C%A8")
    • [5. NVML/DCGM 库已经加载](#5. NVML/DCGM 库已经加载 "#5-nvmldcgm-%E5%BA%93%E5%B7%B2%E7%BB%8F%E5%8A%A0%E8%BD%BD")
    • [6. 进程曾经打开过 GPU 设备](#6. 进程曾经打开过 GPU 设备 "#6-%E8%BF%9B%E7%A8%8B%E6%9B%BE%E7%BB%8F%E6%89%93%E5%BC%80%E8%BF%87-gpu-%E8%AE%BE%E5%A4%87")
    • [7. strace 抓到 EPERM](#7. strace 抓到 EPERM "#7-strace-%E6%8A%93%E5%88%B0-eperm")
    • [8. runtime 配置命中风险组合](#8. runtime 配置命中风险组合 "#8-runtime-%E9%85%8D%E7%BD%AE%E5%91%BD%E4%B8%AD%E9%A3%8E%E9%99%A9%E7%BB%84%E5%90%88")
  • 复现和取证
  • 不跑脚本时的手工命令
  • 根因
  • 解决方案
  • 经验总结
  • 适用场景

官方文档先放前面

NVIDIA 官方文档里有一个对应章节:

Containers losing access to GPUs with error: Failed to initialize NVML: Unknown Error

官方描述的核心点是:

  • 使用 NVIDIA Container Runtime Hook,也就是 legacy 模式注入 GPU 和驱动库时,hook 会修改容器配置,包括 cgroup device 访问权限,但底层 runtime 例如 runc 不一定知道这些修改。
  • 后续容器被更新时,可能会丢失已经请求到的 GPU 访问能力。
  • 使用 systemd 管理容器 cgroup 的环境里,执行 systemctl daemon-reload 就可能触发这种容器更新,导致运行中的容器丢失 GPU 访问权限。
  • 故障出现后,容器需要删除并重建,重建后会重新获得 GPU 访问权限。
  • 规避方向包括:显式请求 device nodes、Kubernetes device plugin 使用 compatWithCPUManager=true、使用 CDI 注入 GPU 设备。

这次现场现象和官方文档能对上:dcgm-exporter Pod 还在,但容器内 NVML 失败,删除 Pod 后恢复。后面继续往下查,是为了把"命中官方场景"落到本机证据上。

背景

集群里 dcgm-exporter 通过 Helm 以 DaemonSet 方式部署,每个 GPU 节点上有一个 cce-aihc-dcgm-exporter-* Pod,负责采集 GPU 指标并暴露给 Prometheus。

节点环境:

text 复制代码
GPU: NVIDIA H20-3e
Runtime: containerd
GPU runtime: nvidia-container-runtime
Exporter: dcgm-exporter
Cgroup: systemd cgroup

链路大致是:

text 复制代码
Kubernetes
  -> nvidia-device-plugin
  -> containerd
  -> nvidia-container-runtime
  -> dcgm-exporter / DCGM / NVML
  -> Prometheus / Grafana

这次不是业务容器直接报错,而是监控侧部分 DCGM profiling 指标断了。业务训练/推理不一定立刻中断,但 GPU 利用率分析、容量判断和告警都会失真。

现象

Grafana 上部分节点的 profiling 指标消失,主要是这几个:

text 复制代码
DCGM_FI_PROF_SM_ACTIVE
DCGM_FI_PROF_DRAM_ACTIVE
DCGM_FI_PROF_PIPE_TENSOR_ACTIVE

问题节点本地查 /metrics

bash 复制代码
curl -s http://127.0.0.1:9400/metrics \
  | grep -E "DCGM_FI_PROF_SM_ACTIVE|DCGM_FI_PROF_DRAM_ACTIVE|DCGM_FI_PROF_PIPE_TENSOR_ACTIVE"

异常时没有输出。

但 Pod 还在,进程也还在,不是 dcgm-exporter 整个挂掉。普通 GPU 指标有时也还能看到,所以一开始不能简单按"exporter 不可用"处理。

排查过程

1. 宿主机 GPU 正常

先看宿主机:

bash 复制代码
nvidia-smi

宿主机能正常看到 8 张 H20 GPU,驱动返回正常。这个结果把方向从 GPU 硬件、驱动整体故障,收敛到"容器访问 GPU 的链路"。

2. 容器内 NVML 失败

节点上不能用 kubectl,直接用 crictl 找 dcgm-exporter 容器:

bash 复制代码
CID=$(crictl ps | awk '/cce-aihc-dcgm-exporter/ && !/hook/ {print $1; exit}')
echo "$CID"

在容器内执行:

bash 复制代码
crictl exec "$CID" nvidia-smi

异常输出:

text 复制代码
Failed to initialize NVML: Unknown Error

dcgm-exporter 依赖 DCGM/NVML 采集 GPU 信息,容器内 nvidia-smi 也依赖 NVML。这里失败后,问题就不是 Prometheus 没抓到,而是容器里访问 GPU/NVML 已经出问题。

3. 设备文件还在

继续看容器内设备文件:

bash 复制代码
crictl exec "$CID" sh -c 'ls -l /dev/nvidia*'

能看到类似:

text 复制代码
/dev/nvidia0
/dev/nvidia1
...
/dev/nvidia7
/dev/nvidiactl
/dev/nvidia-uvm
/dev/nvidia-uvm-tools

这一步很关键。/dev/nvidia* 存在,只能说明设备节点还在容器里,不能说明容器进程一定有权限访问。GPU 字符设备最终还要过 cgroup device 权限。

4. dcgm-exporter 主进程还在

拿容器主进程在宿主机上的 PID:

bash 复制代码
PID=$(crictl inspect "$CID" | grep -E '"pid":[[:space:]]*[0-9]+' \
  | awk -F: '{gsub(/[^0-9]/,"",$2); if ($2>100) print $2}' | head -1)

echo "$PID"

看进程命令:

bash 复制代码
tr '\0' ' ' < /proc/$PID/cmdline

输出类似:

text 复制代码
/usr/bin/dcgm-exporter -f /etc/dcgm-exporter/metrics

进程没有退出。

再看 cgroup:

bash 复制代码
cat /proc/$PID/cgroup

正常能看到:

text 复制代码
0::/kubepods.slice/kubepods-burstable.slice/.../cri-containerd-<container-id>.scope

说明进程还在 Kubernetes/containerd 管理的 cgroup 下。

5. NVML/DCGM 库已经加载

bash 复制代码
grep -Ei 'nvidia|cuda|nvml|dcgm' /proc/$PID/maps | head

能看到:

text 复制代码
libnvidia-ml.so.535.261.03
libdcgm.so.4.4.1

镜像缺库、程序没加载 NVML/DCGM 这条线基本排掉。

6. 进程曾经打开过 GPU 设备

bash 复制代码
ls -l /proc/$PID/fd | grep -Ei 'nvidia|nv|dcgm'

能看到它之前打开过 GPU 设备:

text 复制代码
8  -> /dev/nvidiactl
9  -> /dev/nvidia0
10 -> /dev/nvidia1
...

这说明 dcgm-exporter 启动时 GPU 权限是有效的,不是一开始就没有权限。问题是在运行过程中发生的。

7. strace 抓到 EPERM

对主进程抓系统调用:

bash 复制代码
timeout 20 strace -p "$PID" -f -e openat,ioctl 2>&1 \
  | grep -Ei "nvidiactl|EPERM|EACCES|ioctl"

关键输出:

text 复制代码
openat(AT_FDCWD, "/dev/nvidiactl", O_RDWR|O_CLOEXEC) = -1 EPERM (Operation not permitted)
openat(AT_FDCWD, "/dev/nvidiactl", O_RDWR) = -1 EPERM (Operation not permitted)

这条证据把问题打到权限层。/dev/nvidiactl 文件存在,但 open 被拒绝。不是文件不存在,也不是库不存在,而是内核权限策略拒绝访问。对容器来说,最可疑的就是 cgroup device 权限。

8. runtime 配置命中风险组合

看 containerd 和 NVIDIA runtime 配置:

bash 复制代码
containerd config dump 2>/dev/null \
  | grep -Ei "default_runtime_name|nvidia|SystemdCgroup|enable_cdi|EnableCDI|BinaryName|cdi|runc"

关键输出:

text 复制代码
enable_cdi = false
default_runtime_name = "nvidia"
BinaryName = "/usr/bin/nvidia-container-runtime"
SystemdCgroup = true

这个组合和 NVIDIA 官方文档里的风险点一致:

  • SystemdCgroup=true:容器 cgroup 由 systemd 管理。
  • enable_cdi=false:未启用 CDI。
  • nvidia-container-runtime:GPU device 仍依赖 NVIDIA runtime legacy hook 注入。

legacy hook 在容器创建阶段补 GPU device、驱动库和 cgroup device 权限。后续 systemd reload 触发 cgroup 状态同步时,这部分后置注入的 device 访问权限可能丢掉。

复现和取证

1. daemon-reload 前正常

bash 复制代码
CID=$(crictl ps | awk '/cce-aihc-dcgm-exporter/ && !/hook/ {print $1; exit}')

crictl exec "$CID" nvidia-smi

curl -s http://127.0.0.1:9400/metrics \
  | grep -E "DCGM_FI_PROF_SM_ACTIVE|DCGM_FI_PROF_DRAM_ACTIVE|DCGM_FI_PROF_PIPE_TENSOR_ACTIVE" \
  | head

此时容器内 nvidia-smi 正常,profiling 指标也能查到。

2. 触发 systemd reload

bash 复制代码
systemctl daemon-reload

再查:

bash 复制代码
crictl exec "$CID" nvidia-smi

输出变成:

text 复制代码
Failed to initialize NVML: Unknown Error

继续抓 strace:

bash 复制代码
PID=$(crictl inspect "$CID" | grep -E '"pid":[[:space:]]*[0-9]+' \
  | awk -F: '{gsub(/[^0-9]/,"",$2); if ($2>100) print $2}' | head -1)

timeout 20 strace -p "$PID" -f -e openat,ioctl 2>&1 \
  | grep -Ei "nvidiactl|EPERM|EACCES|ioctl"

再次出现:

text 复制代码
openat(AT_FDCWD, "/dev/nvidiactl", O_RDWR|O_CLOEXEC) = -1 EPERM (Operation not permitted)

到这里,链路已经闭环:

text 复制代码
daemon-reload 前:容器内 nvidia-smi 正常,DCGM_FI_PROF_* 正常
触发动作:systemctl daemon-reload
daemon-reload 后:容器内 NVML 失败
直接证据:open /dev/nvidiactl = EPERM
恢复动作:重建 dcgm-exporter Pod 后恢复

3. 继续看 cgroup/device BPF

为了确认不是容器重建导致的错觉,我继续抓了 before/after 的容器、PID、cgroup。

bash 复制代码
CID=$(crictl ps | awk '/cce-aihc-dcgm-exporter/ && !/hook/ {print $1; exit}')
PID=$(crictl inspect "$CID" | grep -E '"pid":[[:space:]]*[0-9]+' \
  | awk -F: '{gsub(/[^0-9]/,"",$2); if ($2>100) print $2}' | head -1)

cat /proc/$PID/cgroup
bpftool cgroup tree
bpftool prog show

本次复现抓到:

text 复制代码
before cid  : f774c55955543
after cid   : f774c55955543
before pid  : 1449239
after pid   : 1449239
before cg   : /kubepods.slice/.../cri-containerd-f774c5595554392c98507bbd330e59f9f8941a69ef26947746a8ebabcb5ff830.scope
after cg    : /kubepods.slice/.../cri-containerd-f774c5595554392c98507bbd330e59f9f8941a69ef26947746a8ebabcb5ff830.scope

同一个容器、同一个 PID、同一个 cgroup,没有发生 Pod 重建。

bpftool cgroup tree 的 diff 显示,daemon-reload 后目标容器 cgroup 新增了一个 device BPF program:

text 复制代码
/sys/fs/cgroup/kubepods.slice/.../cri-containerd-f774c5595554392c98507bbd330e59f9f8941a69ef26947746a8ebabcb5ff830.scope
    1578     device          multi
    1579     device          multi
+   1597     device          multi

bpftool prog show 里能看到新增 program 的加载时间:

text 复制代码
1597: cgroup_device  tag c692d192a4d1a516  gpl
        loaded_at 2026-06-11T16:18:05+0800  uid 0
        xlated 440B  jited 272B  memlock 4096B

同一时间段里,容器内 nvidia-smi 从成功变失败:

text 复制代码
before container nvidia-smi rc: 0
after  container nvidia-smi rc: 1
after strace: /dev/nvidiactl = -1 EPERM

这个证据足够把问题写成:同一个运行中容器,在 systemctl daemon-reload 后 cgroup device/BPF 访问控制状态发生变化,随后访问 /dev/nvidiactl 被拒绝。

这里不把结论写成"已经证明 systemd 内部覆盖了哪一条 NVIDIA 规则"。要证明到那一步,需要继续解码 BPF program 或抓 systemd/runc 内部调用日志。现场复盘写到 cgroup device/BPF 状态变化导致 NVIDIA device 访问被拒绝,已经够准确。

不跑脚本时的手工命令

下面这组命令可以直接在问题节点上执行。适合现场不能上传脚本,只能一条条命令排查的情况。

1. 固定目标容器

bash 复制代码
TARGET_PATTERN="cce-aihc-dcgm-exporter"

CID=$(crictl ps | awk -v p="$TARGET_PATTERN" '$0 ~ p && $0 !~ /hook/ {print $1; exit}')
PID=$(crictl inspect "$CID" 2>/dev/null \
  | grep -E '"pid":[[:space:]]*[0-9]+' \
  | awk -F: '{gsub(/[^0-9]/,"",$2); if ($2>100) print $2}' \
  | head -1)
CG=$(awk -F: 'NR==1 {print $3}' /proc/$PID/cgroup)

echo "CID=$CID"
echo "PID=$PID"
echo "CG=$CG"

看点:

text 复制代码
CID 是否是 dcgm-exporter 容器
PID 是否能取到
CG 是否是 kubepods...cri-containerd...scope

2. 采集 daemon-reload 前状态

bash 复制代码
mkdir -p /tmp/dcgm_manual_check/before /tmp/dcgm_manual_check/after

date '+%F %T %Z' | tee /tmp/dcgm_manual_check/before/time.txt

crictl exec "$CID" nvidia-smi > /tmp/dcgm_manual_check/before/container_nvidia_smi.txt 2>&1
echo $? > /tmp/dcgm_manual_check/before/container_nvidia_smi.rc

curl -s --max-time 5 http://127.0.0.1:9400/metrics \
  | grep -E 'DCGM_FI_PROF_SM_ACTIVE|DCGM_FI_PROF_DRAM_ACTIVE|DCGM_FI_PROF_PIPE_TENSOR_ACTIVE' \
  | head -50 > /tmp/dcgm_manual_check/before/dcgm_prof_metrics.txt

cat /proc/$PID/cgroup > /tmp/dcgm_manual_check/before/proc_cgroup.txt
ls -l /proc/$PID/root/dev/nvidia* > /tmp/dcgm_manual_check/before/proc_root_dev_nvidia.txt 2>&1

bpftool cgroup tree > /tmp/dcgm_manual_check/before/bpftool_cgroup_tree.txt
bpftool prog show > /tmp/dcgm_manual_check/before/bpftool_prog_show.txt

看点:

text 复制代码
container_nvidia_smi.rc 是否为 0
dcgm_prof_metrics.txt 是否有 DCGM_FI_PROF_* 输出
proc_cgroup.txt 记录当前 cgroup
proc_root_dev_nvidia.txt 确认 /dev/nvidiactl 是否存在
bpftool_cgroup_tree.txt 记录当前 cgroup device BPF 状态

3. 执行触发动作

bash 复制代码
systemctl daemon-reload

4. 采集 daemon-reload 后状态

bash 复制代码
date '+%F %T %Z' | tee /tmp/dcgm_manual_check/after/time.txt

crictl exec "$CID" nvidia-smi > /tmp/dcgm_manual_check/after/container_nvidia_smi.txt 2>&1
echo $? > /tmp/dcgm_manual_check/after/container_nvidia_smi.rc

curl -s --max-time 5 http://127.0.0.1:9400/metrics \
  | grep -E 'DCGM_FI_PROF_SM_ACTIVE|DCGM_FI_PROF_DRAM_ACTIVE|DCGM_FI_PROF_PIPE_TENSOR_ACTIVE' \
  | head -50 > /tmp/dcgm_manual_check/after/dcgm_prof_metrics.txt

cat /proc/$PID/cgroup > /tmp/dcgm_manual_check/after/proc_cgroup.txt
ls -l /proc/$PID/root/dev/nvidia* > /tmp/dcgm_manual_check/after/proc_root_dev_nvidia.txt 2>&1

bpftool cgroup tree > /tmp/dcgm_manual_check/after/bpftool_cgroup_tree.txt
bpftool prog show > /tmp/dcgm_manual_check/after/bpftool_prog_show.txt

5. 抓系统调用

bash 复制代码
timeout 20 strace -p "$PID" -f -e openat,ioctl 2>&1 \
  | grep -Ei "nvidiactl|nvidia[0-9]|EPERM|EACCES|ENOENT|ioctl" \
  | tee /tmp/dcgm_manual_check/after/strace_nvidia_device_access.txt

关键输出:

text 复制代码
openat(AT_FDCWD, "/dev/nvidiactl", O_RDWR|O_CLOEXEC) = -1 EPERM (Operation not permitted)

6. 对比 before/after

bash 复制代码
diff -u /tmp/dcgm_manual_check/before/proc_cgroup.txt \
        /tmp/dcgm_manual_check/after/proc_cgroup.txt

diff -u /tmp/dcgm_manual_check/before/bpftool_cgroup_tree.txt \
        /tmp/dcgm_manual_check/after/bpftool_cgroup_tree.txt \
  | grep -E "cri-containerd-$CID|device|^[+-]" -A3 -B3

diff -u /tmp/dcgm_manual_check/before/bpftool_prog_show.txt \
        /tmp/dcgm_manual_check/after/bpftool_prog_show.txt \
  | grep -E "cgroup_device|loaded_at|^[+-]" -A3 -B3

echo "before rc=$(cat /tmp/dcgm_manual_check/before/container_nvidia_smi.rc)"
echo "after  rc=$(cat /tmp/dcgm_manual_check/after/container_nvidia_smi.rc)"

判断标准:

text 复制代码
1. before/after 的 CID、PID、cgroup 不变
2. before 容器内 nvidia-smi 返回 0
3. after 容器内 nvidia-smi 返回非 0,并出现 Failed to initialize NVML
4. /proc/$PID/root/dev/nvidia* 里仍能看到 /dev/nvidiactl
5. strace 抓到 /dev/nvidiactl 返回 EPERM
6. bpftool 显示目标 cgroup 的 device BPF 状态发生变化,新增 program 的 loaded_at 与 daemon-reload 时间窗口一致

满足这几条,就可以定性为:systemctl daemon-reload 后,同一个运行中容器的 cgroup device/BPF 访问控制状态发生变化,导致 NVIDIA device 访问被拒绝。

根因

直接原因:

text 复制代码
dcgm-exporter 容器运行过程中,GPU device 访问权限失效。进程重新 open /dev/nvidiactl 时被 cgroup/device 策略拒绝,返回 EPERM,导致 NVML/DCGM profiling 指标采集失败。

触发机制:

text 复制代码
节点使用 nvidia-container-runtime legacy hook 模式,containerd 配置为 SystemdCgroup=true 且 enable_cdi=false。systemctl daemon-reload 后,systemd 重新加载并同步 cgroup 状态,运行中容器的 NVIDIA device 访问权限失效。

这次证据能确认到这一层:

text 复制代码
daemon-reload 后,同一个 dcgm-exporter 容器的 cgroup device/BPF 状态发生变化;
容器内 nvidia-smi 从成功变为失败;
dcgm-exporter 访问 /dev/nvidiactl 被 EPERM 拒绝。

不是 /dev/nvidia* 文件没了,也不是 dcgm-exporter 进程没了。设备文件还在,进程也还在,问题出在运行态 device 访问权限。

解决方案

临时恢复

删除问题节点上的 dcgm-exporter Pod,让 DaemonSet 重建:

bash 复制代码
kubectl delete pod <cce-aihc-dcgm-exporter-pod> -n kube-system

新 Pod 创建时会重新经过 nvidia-container-runtime 初始化,GPU device 文件和访问权限重新注入,容器内 NVML 恢复,DCGM profiling 指标恢复。

恢复后验证:

bash 复制代码
NEW_CID=$(crictl ps | awk '/cce-aihc-dcgm-exporter/ && !/hook/ {print $1; exit}')
crictl exec "$NEW_CID" nvidia-smi

curl -s http://127.0.0.1:9400/metrics \
  | grep -E "DCGM_FI_PROF_SM_ACTIVE|DCGM_FI_PROF_DRAM_ACTIVE|DCGM_FI_PROF_PIPE_TENSOR_ACTIVE" \
  | head

多个节点同时异常时,不建议全量重装 Helm,也不建议重启所有节点。只删除问题节点上的 dcgm-exporter Pod 即可。

示例:

bash 复制代码
#!/bin/bash
set -euo pipefail

NS="kube-system"
POD_PREFIX="cce-aihc-dcgm-exporter-"
IP_FILE="/root/bad_node_ip.txt"

while read -r ip; do
  [ -z "$ip" ] && continue

  node=$(kubectl get nodes -o wide --no-headers | awk -v ip="$ip" '$6 == ip {print $1}')
  if [ -z "$node" ]; then
    echo "未找到 Node IP: $ip"
    continue
  fi

  pod=$(kubectl get pod -n "$NS" -o wide --no-headers \
    | awk -v node="$node" -v prefix="$POD_PREFIX" '$1 ~ "^"prefix && $7 == node {print $1}')

  if [ -z "$pod" ]; then
    echo "Node $node / $ip 上未找到 ${POD_PREFIX} Pod"
    continue
  fi

  echo "删除问题 Pod: $pod Node: $node IP: $ip"
  kubectl delete pod "$pod" -n "$NS"
done < "$IP_FILE"

长期规避

后续不能只靠手工删 Pod。

可以做几件事:

  1. 生产 GPU 节点避免无控制地执行 systemctl daemon-reload
  2. 必须 reload 时,提前评估运行中 GPU 容器影响。
  3. 按 NVIDIA 官方建议评估 CDI,减少 legacy hook 对运行中 cgroup/device 修改的依赖。
  4. 评估 device-plugin 配置,例如 Helm 场景下的 compatWithCPUManager=true
  5. 增加自愈巡检:发现 DCGM_FI_PROF_* 缺失且容器内 NVML 失败时,只重建该节点上的 dcgm-exporter Pod。

经验总结

这次最容易误判的点有三个。

第一,Pod Running 不代表指标链路健康。dcgm-exporter 进程还在,但后端访问 GPU/NVML 失败,Prometheus 看到的就是指标缺失。

第二,/dev/nvidia* 存在不代表 GPU 权限正常。设备文件只是入口,真正能不能访问还要看 cgroup device 权限。这次 /dev/nvidiactl 文件存在,但 open 返回 EPERM

第三,宿主机 nvidia-smi 正常不代表容器内 NVML 正常。宿主机和容器走的是不同权限边界。宿主机正常只能说明硬件和驱动基本可用,不能说明容器运行态权限没问题。

现场排查顺序可以固定下来:

text 复制代码
1. 查 /metrics,确认 DCGM_FI_PROF_* 是否真的缺失
2. 查宿主机 nvidia-smi
3. 查容器内 nvidia-smi
4. 查 /dev/nvidia*
5. 查进程 fd/maps/cgroup
6. 用 strace 抓 /dev/nvidiactl 是否返回 EPERM
7. 查 containerd/nvidia-runtime/systemd cgroup 配置
8. 必要时用 bpftool 对比 daemon-reload 前后 cgroup device BPF 状态

这次最终定性靠的不是"重启 Pod 恢复了",而是这几条证据连起来:

text 复制代码
同一 CID/PID/cgroup
daemon-reload 前 nvidia-smi 成功
daemon-reload 后 nvidia-smi 失败
/dev/nvidiactl 文件存在
open /dev/nvidiactl = EPERM
cgroup device BPF 状态发生变化

适用场景

这类故障通常出现在以下环境:

  • Kubernetes GPU 集群;
  • dcgm-exporter 以 DaemonSet/Helm 部署;
  • 节点使用 containerd;
  • GPU 容器通过 nvidia-container-runtime 访问设备;
  • containerd 配置里 SystemdCgroup=true
  • 未启用 CDI,enable_cdi=false
  • 生产节点上发生过 systemctl daemon-reload、systemd reload、runtime reload 或类似系统服务变更;
  • 表现为 Pod 仍 Running,但容器内 nvidia-smiFailed to initialize NVML: Unknown Error
  • /dev/nvidia* 文件存在,但 strace 显示 /dev/nvidiactl 返回 EPERM
  • 删除并重建 dcgm-exporter Pod 后指标恢复。

如果现场搜索到的是"dcgm-exporter Pod 存在但 DCGM_FI_PROF_* 指标丢失"、"容器内 nvidia-smi Failed to initialize NVML"、"systemctl daemon-reload 后 GPU 容器失去访问权限",这套排查链路基本适用。

相关推荐
Patrick_Wilson4 小时前
K8s 探针避坑:Next.js 不同部署模式下的健康检查实践
kubernetes·node.js·next.js
Plastic garden4 小时前
K8s(10)NFS 的动态 PV 创建数据库给k8s的mysql和redis
docker·容器·kubernetes
Plastic garden5 小时前
k8s(11) Pod 控制器,服务发现与存储管理
kubernetes
武子康6 小时前
调查研究-167 Docker Compose 详解:从单容器到多服务编排的工程化入口
运维·docker·云原生·容器·kubernetes·k8s·docker-compose
Shacoray8 小时前
K8s 中 Ingress 的 HTTPS 证书 如何生成?
容器·https·kubernetes
开发者联盟league8 小时前
使用Jenkins整合Sonarqube/Gitlab/Harbor/Kubernetes的Demo工程
kubernetes·gitlab·jenkins
Patrick_Wilson8 小时前
Node.js SSR 内存治理:为什么 --max-old-space-size 不等于进程内存
kubernetes·node.js·v8
开发者联盟league8 小时前
使用k8s安装Jenkins
容器·kubernetes·jenkins