GPU 在虚拟化直通(Passthrough)环境下运行时,偶尔会出现驱动丢失、NVML 报错等问题,导致容器内无法使用 GPU。本文介绍一个轻量级的自动巡检自愈方案,从检测到修复再到飞书通知,全自动闭环。

问题背景 链接到标题

在 PVE 虚拟机中通过 PCIe Passthrough 直通 NVIDIA GPU 时,容器内偶尔会出现:

Failed to initialize NVML: Unknown Error

重启容器后可短暂恢复,但一段时间后再次失效。这类问题在虚拟化环境中难以彻底根治(涉及 ASPM 电源管理、驱动状态等问题),需要一个主动巡检 + 自动修复的兜底机制。

架构总览 链接到标题

graph LR GC[gpu-checker
每 60s 巡检] -->|docker exec nvidia-smi| OS[GPU 应用容器] GC -->|异常| A[自动修复] A -->|1.告警| AT[alert-transformer] A -->|2.重启| OS A -->|3.重检| B{恢复?} B -->|是| AT B -->|否| C[人工介入] AT -->|hooks| OC[OpenClaw] OC -->|飞书机器人| FS[飞书通知]

部署 gpu-checker 链接到标题

巡检容器是一个独立的 Docker 容器,使用 docker:cli 镜像,通过挂载 docker.sock 来操作宿主机上的其他容器:

# /opt/gpu-checker/docker-compose.yaml
services:
  gpu-checker:
    image: m.daocloud.io/docker.io/docker:cli
    container_name: gpu-checker
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./check.sh:/check.sh:ro
    command: sh /check.sh
sudo mkdir -p /opt/gpu-checker
cd /opt/gpu-checker && docker compose up -d

巡检与自愈逻辑 链接到标题

核心脚本 check.sh 实现了一个完整的自动巡检 - 告警 - 修复 - 通知闭环:

主循环 链接到标题

每 60 秒:
  ├─ 冷却检查(距上次操作 < 300s 则跳过)
  │
  └─ 执行 docker exec nvidia-smi
       ├─ 正常 → 静默等待下一轮
       │
       └─ 异常(报错或非零退出码)
            ├─ 1. 发送 warning 告警 → alert-transformer
            ├─ 2. docker compose restart 目标容器
            ├─ 3. 等待 15s 让 GPU 初始化
            ├─ 4. 重检 nvidia-smi
            │    ├─ 恢复 → 发送 resolved 通知
            │    └─ 仍失败 → 发送 critical 告警
            └─ 5. 设置 300s 冷却

三态告警 链接到标题

阶段 告警名 严重度 作用
发现异常 OllamaGPUCheckFailed warning 通知管理员正在自愈
自愈成功 OllamaGPUCheckFailed → resolved info 确认已恢复
自愈失败 OllamaGPUAutoRepairFailed critical 需人工介入

冷却机制 链接到标题

每次触发修复后,设置 300 秒冷却窗口,避免短时间内反复重启导致告警风暴和服务抖动:

COOLDOWN_SECONDS=300
cooldown_file="/tmp/gpu-checker-cooldown"

check_cooldown() {
  if [ -f "$cooldown_file" ]; then
    last_alert=$(cat "$cooldown_file")
    now=$(date +%s)
    diff=$((now - last_alert))
    if [ $diff -lt $COOLDOWN_SECONDS ]; then
      return 1  # 冷却中,跳过
    fi
  fi
  return 0
}

告警流转 链接到标题

巡检脚本直接向 alert-transformer 发送兼容 Alertmanager webhook 格式的 HTTP POST 请求,复用已有的告警链路:

gpu-checker
  │ POST http://alert-transformer:9091/alertmanager
  ▼
alert-transformer ── 格式化中文消息 ──→ OpenClaw ──→ 飞书

不需要额外的告警基础设施(如 Prometheus + Alertmanager),巡检脚本自己就是一个精简的告警源。

与 DCGM-Exporter 的分工 链接到标题

方案 类型 作用
DCGM-Exporter + Prometheus 被动指标采集 温度、显存、功耗等持续监控
gpu-checker 主动功能巡检 定时执行 nvidia-smi 验证 GPU 可用性

两者互补:DCGM 发现异常趋势,gpu-checker 直接验证功能并在故障时自动修复。

验证 链接到标题

# 查看巡检日志
docker logs -f gpu-checker

# 手动触发一次 GPU 检查
docker exec gpu-checker sh -c "docker exec ollama-service nvidia-smi"

# 正常输出示例
[2026-04-23 07:50:43] GPU check OK

# 异常输出示例
[2026-04-23 08:01:12] GPU check FAILED, attempting auto-repair...
[2026-04-23 08:01:15] Sending alert to alertmanager
[2026-04-23 08:01:30] ollama-service restarted, waiting 15s...
[2026-04-23 08:01:45] GPU check PASSED after restart
[2026-04-23 08:01:45] Sending resolved alert

总结 链接到标题

通过一个 100 余行的 shell 脚本 + Docker 容器,实现了 GPU 可用性的自动巡检、故障自愈、飞书通知的完整闭环。这套方案的好处在于:

  • 旁路部署:不侵入现有服务
  • 无外部依赖:只需要 alert-transformer 一个网络端点
  • 幂等安全:反复 restart 不会造成副作用
  • 告警去重:冷却期避免消息轰炸

对于虚拟化环境中的 GPU 直通场景,这是一个实用且经济的兜底方案。