第二十篇: Shell脚本 – 将命令串联成“自动化巡检机器人”

内容分享2个月前发布
0 0 0

第二十篇: Shell脚本 – 将命令串联成“自动化巡检机器人”

核心目标

融会贯通。将前面章节学习的
nvidia-smi --query-gpu
,
dmesg
,
grep
等多个核心命令,通过Shell脚本串联起来,打造一个可以一键执行、自动输出结构化报告的GPU节点健康巡检机器人

使用场景

作为运维工程师,我们的终极目标是自动化,将重复性的手动工作交给程序完成。

例行健康检查:通过cron定时任务,每天凌晨对所有GPU节点执行一次全面体检,并将报告输出到日志或发送到通知系统。快速故障 triage:当接到节点故障告警时,无需手动逐一敲打命令,直接运行此脚本,即可在30秒内获得一份关于该节点的全面、标准化的诊断快照。标准化交付:将此脚本作为新节点上架流程(Provisioning)的一部分,确保交付到生产环境的每一台服务器都符合健康标准。

一、巡检机器人的“设计蓝图”

在编写代码之前,我们先规划好这个机器人需要完成哪些检查任务:

[基础检查] 驱动状态
nvidia-smi
命令能否正常执行?这是所有检查的前提。[健康检查] GPU核心指标:遍历服务器上的每一块GPU,检查:
温度 (Temperature):是否超过了危险阈值?ECC错误 (ECC Errors):是否存在无法纠正的ECC错误?
[历史痕迹] 内核日志检查:扫描
dmesg
日志,是否存在致命的
Xid
错误记录?

二、巡检机器人的“源代码”

下面是一个可以直接使用的、功能完备的Bash脚本。

使用方法

将下面的代码保存为一个文件,例如
check_gpu_health.sh
。赋予它执行权限:
chmod +x check_gpu_health.sh
。以root权限运行:
sudo ./check_gpu_health.sh


#!/bin/bash

# =================================================================
# GPU Health Check Script - V1.0
# =================================================================
# This script performs a series of checks to validate the health
# of NVIDIA GPUs on a server.

# --- 配置区 ---
TEMP_THRESHOLD=90 # 温度告警阈值 (摄氏度)

# --- 为输出添加点颜色 ---
RED='33[0;31m'
GREEN='33[0;32m'
YELLOW='33[1;33m'
NC='33[0m' # 无颜色

# --- 脚本主体 ---

echo "================================================="
echo "   GPU Health Check started at $(date)   "
echo "================================================="

# 标志位,用于最终的总结报告
OVERALL_STATUS="PASS"

# 1. 基础检查: 驱动状态
echo -e "
[1] Checking NVIDIA Driver Status..."
if ! command -v nvidia-smi &> /dev/null; then
    echo -e "${RED}FAIL: nvidia-smi command not found. Driver may not be installed.${NC}"
    exit 1
fi

if ! nvidia-smi > /dev/null 2>&1; then
    echo -e "${RED}FAIL: nvidia-smi failed to run. Driver may be unstable or not loaded.${NC}"
    echo "    -> Hint: Check 'dmesg' for NVRM errors."
    exit 1
else
    echo -e "${GREEN}PASS: NVIDIA driver is loaded and nvidia-smi is responsive.${NC}"
    nvidia-smi -L # 打印GPU列表
fi

# 2. 健康检查: 遍历所有GPU的核心指标
echo -e "
[2] Checking Individual GPU Vitals..."
GPU_COUNT=$(nvidia-smi --query-gpu=count --format=csv,noheader)

if [ "$GPU_COUNT" -eq 0 ]; then
    echo -e "${YELLOW}WARN: No NVIDIA GPUs detected in this system.${NC}"
    exit 0
fi

for i in $(seq 0 $((GPU_COUNT - 1))); do
    echo "--- Checking GPU ${i} ---"
    
    # 一次性查询所有需要的指标,提高效率
    QUERY_DATA=$(nvidia-smi --id=$i --query-gpu=temperature.gpu,ecc.errors.uncorrected.total --format=csv,noheader,nounits)
    
    # 解析查询结果
    TEMP=$(echo "$QUERY_DATA" | awk -F', ' '{print $1}')
    ECC_ERRORS=$(echo "$QUERY_DATA" | awk -F', ' '{print $2}')
    
    GPU_STATUS="PASS"
    
    # 检查温度
    if [ "$TEMP" -ge "$TEMP_THRESHOLD" ]; then
        echo -e "  - Temperature Check: ${RED}FAIL ($TEMP C >= ${TEMP_THRESHOLD} C)${NC}"
        GPU_STATUS="FAIL"
    else
        echo -e "  - Temperature Check: ${GREEN}PASS ($TEMP C < ${TEMP_THRESHOLD} C)${NC}"
    fi
    
    # 检查ECC错误
    if [ "$ECC_ERRORS" -ne 0 ]; then
        echo -e "  - ECC Error Check: ${RED}FAIL ($ECC_ERRORS uncorrectable errors detected)${NC}"
        GPU_STATUS="FAIL"
    else
        echo -e "  - ECC Error Check: ${GREEN}PASS (0 uncorrectable errors)${NC}"
    fi

    if [ "$GPU_STATUS" == "FAIL" ]; then
        OVERALL_STATUS="FAIL"
    fi
done

# 3. 历史痕迹: 检查内核日志中的Xid错误
echo -e "
[3] Checking Kernel Log for Critical Errors (dmesg)..."
XID_ERRORS=$(dmesg | grep -i "Xid")

if [ -n "$XID_ERRORS" ]; then
    echo -e "${RED}FAIL: Critical Xid errors found in dmesg! This indicates past driver/hardware crashes.${NC}"
    echo "    --- Last 5 Xid Error Lines ---"
    echo "$XID_ERRORS" | tail -n 5
    echo "    ---------------------------------"
    OVERALL_STATUS="FAIL"
else
    echo -e "${GREEN}PASS: No critical Xid errors found in dmesg.${NC}"
fi

# 4. 最终总结
echo -e "
================================================="
echo "            Overall Health Summary"
echo "================================================="
if [ "$OVERALL_STATUS" == "FAIL" ]; then
    echo -e "Result: ${RED}FAIL${NC}. At least one critical issue was detected."
    exit 1
else
    echo -e "Result: ${GREEN}PASS${NC}. All checks passed. The system appears healthy."
    exit 0
fi

三、如何使用与扩展

使用:将脚本保存后,你可以手动运行它,也可以通过
cron
配置一个定时任务,例如每天凌晨3点执行一次,并将输出重定向到日志文件。


# crontab -e
0 3 * * * /path/to/your/check_gpu_health.sh >> /var/log/gpu_health_check.log 2>&1

扩展:这个脚本是一个绝佳的起点。你可以轻松地为其增加更多功能,例如:
发送通知:当
OVERALL_STATUS

FAIL
时,通过curl命令调用Webhook,将告警信息发送到Slack、Teams或企业微信。集成
dcgmi
: 在脚本中加入
dcgmi diag -r 1
的检查,获得更全面的诊断结果。检查MIG状态:增加对MIG模式是否开启的检查。

总结与预告

我们已经成功地将前面学到的零散命令,组装成了一个强大、实用的自动化巡检工具。这正是运维工作的核心价值所在:将经验和知识沉淀为可重复、可扩展的自动化流程

至此,本系列所有关于“术”的探讨都已完成。在最后一篇,我们将回归本源,探讨一个最重要的“道”:如何通过
man

--help
,去终身学习我们今天没有讲到的、以及未来才会出现的任何新命令。“授人以鱼不如授人以渔”。

© 版权声明

相关文章

暂无评论

none
暂无评论...