这个脚本的主要功能是远程监控一组服务器上的显卡状态和磁盘使用率。它通过 SSH 连接到每台服务器,检查显卡的数量和利用率,以及根目录 (`/`) 和 `/data` 盘的磁盘使用率。以下是脚本的详细总结:
### 脚本功能
1. **获取用户密码**:
- 使用 `read -sp` 提示用户输入密码,并隐藏输入内容。密码用于 SSH 远程连接。
2. **定义服务器列表**:
- 定义一个服务器列表 `SERVERS`,包含需要监控的服务器 IP 地址。
3. **定义常量**:
- `TIMEOUT`: 设置 SSH 连接和命令执行的超时时间为 5 秒。
- `EXPECTED_GPU_COUNT`: 预期的显卡数量(设置为 2)。
- `DISK_THRESHOLD`: 设置磁盘使用率的报警阈值为 95%。
4. **循环遍历每个服务器**:
- 对于每个服务器,执行以下检查:
- **显卡状态检查**:
- 使用 `sshpass` 和 `ssh` 通过 SSH 连接到服务器,运行 `nvidia-smi` 命令以获取显卡信息。
- 检查显卡数量是否低于预期数量 `EXPECTED_GPU_COUNT`。
- 如果显卡数量正常,则继续获取 GPU 利用率和 GPU 进程列表:
- 获取 GPU 利用率:通过 `nvidia-smi` 查询 GPU 利用率 (`utilization.gpu`)。
- 获取 GPU 进程列表:通过 `nvidia-smi` 查询当前在 GPU 上运行的进程列表(包括 GPU UUID、PID、进程名称和使用的内存量)。
- 如果无法获取显卡信息或利用率,打印相应的警告信息。
- **磁盘使用率检查**:
- 使用 `df -h` 命令检查服务器的根目录 (`/`) 和 `/data` 盘的磁盘使用率。
- 解析 `df` 输出,提取根目录和 `/data` 盘的使用率(百分比)。
- 如果使用率超过设定的阈值 `DISK_THRESHOLD`,则打印警告信息。
- 如果无法获取磁盘使用率,打印相应的警告信息。
5. **输出和日志**:
- 每次检测完一台服务器后,输出相应的检测结果和警告信息。
- 每个检测模块后面都会有 "**********************************************************************************" 行,以便区分不同服务器和不同检测模块的输出。
6. **等待**:
- 在每次检测完一台服务器后,使用 `sleep 2` 命令等待 2 秒,防止脚本运行过快。
#!/bin/bash
# 提示用户输入密码,使用 -s 选项隐藏输入
read -sp "Enter Password: " PASSWORD
echo
# 远程服务器列表
SERVERS=(
"10.1.1.1"
"10.1.1.2"
*
*
*
)
# 超时时间(秒)
TIMEOUT=5
# 预期的显卡数量
EXPECTED_GPU_COUNT=2
# 设置阈值百分比
DISK_THRESHOLD=95
for SERVER in "${SERVERS[@]}"; do
echo "正在检测服务器 $SERVER 的显卡状态..."
# 使用 sshpass 进行 SSH 连接并执行命令
GPU_INFO=$(sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=$TIMEOUT $SERVER "timeout $TIMEOUT nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null")
# 检查 SSH 或 nvidia-smi 命令是否成功
if [ $? -ne 0 ] || [ -z "$GPU_INFO" ]; then
echo "告警:无法检测服务器 $SERVER 的显卡状态,可能密码错误,nvidia-smi 命令超时、失败或显卡驱动未安装。"
echo "**********************************************************************************"
else
GPU_COUNT=$(echo "$GPU_INFO" | wc -l)
if [ "$GPU_COUNT" -lt "$EXPECTED_GPU_COUNT" ]; then
echo "告警:服务器 $SERVER 上检测到的显卡数量不足。当前检测到的显卡数量为 $GPU_COUNT,预期为 $EXPECTED_GPU_COUNT。"
echo "**********************************************************************************"
else
echo "服务器 $SERVER 上的显卡数量正常,检测到的显卡数量为 $GPU_COUNT。"
echo "**********************************************************************************"
# 获取一次 GPU 利用率
echo "获取服务器 $SERVER 的 GPU 利用率..."
GPU_UTILIZATION=$(sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=$TIMEOUT $SERVER "nvidia-smi --query-gpu=index,name,utilization.gpu --format=csv,noheader,nounits 2>/dev/null")
if [ $? -eq 0 ] && [ -n "$GPU_UTILIZATION" ]; then
echo "服务器 $SERVER 的 GPU 利用率:"
echo "$GPU_UTILIZATION"
# sleep 1
else
echo "告警:无法获取服务器 $SERVER 的 GPU 利用率。"
echo "**********************************************************************************"
fi
echo "获取服务器 $SERVER 的 GPU 进程列表..."
GPU_PROCESSES=$(sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=$TIMEOUT $SERVER "nvidia-smi --query-compute-apps=gpu_uuid,pid,process_name,used_memory --format=csv,noheader 2>/dev/null")
if [ $? -eq 0 ] && [ -n "$GPU_PROCESSES" ]; then
echo "服务器 $SERVER 的 GPU 进程列表:"
echo "$GPU_PROCESSES"
echo "**********************************************************************************"
sleep 1
else
echo "告警:获取服务器 $SERVER 的 GPU 进程列表为空或有问题。"
echo "**********************************************************************************"
sleep 1
fi
fi
fi
# 检查每台服务器的根目录和/data盘的磁盘使用率
echo "检查服务器 $SERVER 的磁盘使用率..."
# 获取根目录和/data盘的使用率
DISK_USAGE=$(sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=$TIMEOUT $SERVER "df -h / /data 2>/dev/null")
#echo "$DISK_USAGE" # 调试信息,检查实际输出内容
ROOT_USAGE=$(echo "$DISK_USAGE" | awk '/\/$/ {print $5}' | sed 's/%//')
DATA_USAGE=$(echo "$DISK_USAGE" | awk '/\/data$/ {print $5}' | sed 's/%//')
#echo "根目录使用率: $ROOT_USAGE%" # 调试信息
#echo "/data 使用率: $DATA_USAGE%" # 调试信息
# 检查根目录使用率是否超过阈值
if [ -n "$ROOT_USAGE" ] && [[ "$ROOT_USAGE" =~ ^[0-9]+$ ]] && [ "$ROOT_USAGE" -ge "$DISK_THRESHOLD" ]; then
echo "告警:服务器 $SERVER 的根目录 (/) 使用率已达到 ${ROOT_USAGE}%!"
elif [ -z "$ROOT_USAGE" ]; then
echo "告警:无法获取服务器 $SERVER 的根目录 (/) 使用率。"
fi
# 检查/data盘使用率是否超过阈值
if [ -n "$DATA_USAGE" ] && [[ "$DATA_USAGE" =~ ^[0-9]+$ ]] && [ "$DATA_USAGE" -ge "$DISK_THRESHOLD" ]; then
echo "告警:服务器 $SERVER 的 /data 盘使用率已达到 ${DATA_USAGE}%!"
elif [ -z "$DATA_USAGE" ]; then
echo "告警:无法获取服务器 $SERVER 的 /data 盘使用率。"
fi
echo "**********************************************************************************"
sleep 2
done
加上了并行处理,优化查询时间,但未加查询盘使用率
#!/bin/bash
# 提示用户输入密码,使用 -s 选项隐藏输入
read -sp "Enter Password: " PASSWORD
echo
# 远程服务器列表
SERVERS=(
"10.1.1.1"
)
# 超时时间(秒)
TIMEOUT=5
# 预期的显卡数量
EXPECTED_GPU_COUNT=2
# 创建临时目录来存储输出文件
OUTPUT_DIR=$(mktemp -d)
# 定义函数用于检测 GPU 信息
check_gpu() {
local SERVER=$1
local OUTPUT_FILE="${OUTPUT_DIR}/${SERVER}.out"
{
echo "正在检测服务器 $SERVER 的显卡状态..."
# 使用 sshpass 进行 SSH 连接并执行命令
GPU_INFO=$(sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=$TIMEOUT $SERVER "timeout $TIMEOUT nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null")
# 检查 SSH 或 nvidia-smi 命令是否成功
if [ $? -ne 0 ] || [ -z "$GPU_INFO" ]; then
echo "告警:无法检测服务器 $SERVER 的显卡状态,可能密码错误,nvidia-smi 命令超时、失败或显卡驱动未安装。"
else
GPU_COUNT=$(echo "$GPU_INFO" | wc -l)
if [ "$GPU_COUNT" -lt "$EXPECTED_GPU_COUNT" ]; then
echo "告警:服务器 $SERVER 上检测到的显卡数量不足。当前检测到的显卡数量为 $GPU_COUNT,预期为 $EXPECTED_GPU_COUNT。"
else
echo "服务器 $SERVER 上的显卡数量正常,检测到的显卡数量为 $GPU_COUNT。"
# 获取一次 GPU 利用率
echo "获取服务器 $SERVER 的 GPU 利用率..."
# GPU_UTILIZATION=$(sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=$TIMEOUT $SERVER "nvidia-smi --query-gpu=index,name,utilization.gpu --format=csv,noheader,nounits 2>/dev/null")
GPU_UTILIZATION=$(sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=$TIMEOUT $SERVER "nvidia-smi --query-gpu=name,utilization.gpu --format=csv,noheader,nounits && nvidia-smi --query-compute-apps=gpu_uuid,pid,process_name,used_memory --format=csv,noheader 2>/dev/null")
if [ $? -eq 0 ] && [ -n "$GPU_UTILIZATION" ]; then
echo "服务器 $SERVER 的 GPU 利用率:"
echo "$GPU_UTILIZATION"
else
echo "告警:无法获取服务器 $SERVER 的 GPU 利用率。"
fi
fi
fi
echo "**********************************************************************************"
} > "$OUTPUT_FILE" 2>&1
}
# 导出函数和变量以便 xargs 使用
export -f check_gpu
export PASSWORD
export TIMEOUT
export EXPECTED_GPU_COUNT
export OUTPUT_DIR
# 并行执行 GPU 检测
printf "%s\n" "${SERVERS[@]}" | xargs -I {} -P 30 bash -c 'check_gpu "$@"' _ {}
#printf "%s\n" "${SERVERS[@]}" | parallel -j 20 --no-notice bash -c 'check_gpu "$@"' _ {}
# 读取并输出所有结果
for SERVER in "${SERVERS[@]}"; do
cat "${OUTPUT_DIR}/${SERVER}.out"
done
# 清理临时目录
rm -rf "$OUTPUT_DIR"
总结
该脚本是一个简单而有效的服务器监控工具,可以帮助管理员实时了解服务器显卡的状态和磁盘使用情况,及时发现并解决潜在的问题。通过定期运行该脚本,可以有效地管理服务器资源,保持系统稳定运行。