方案思路
前提条件:您的路由器/交换机等网络设备不连接在UPS上(根据现场实际情况来设置,博主ping的是内网的录像机)
工作原理:当市电中断时,网络设备立即断电,ESXi无法ping通网络设备,从而判断市电已中断
触发关机:检测到网络中断后,安全关闭所有虚拟机,然后关闭ESXi主机
详细实施步骤
步骤1:创建监控脚本
# 创建脚本目录
mkdir -p /vmfs/volumes/datastore1/scripts
# 创建主监控脚本
cat > /vmfs/volumes/datastore1/scripts/ups-monitor.sh << 'EOF'
#!/bin/sh
# UPS网络监控脚本
# 通过检测网络设备状态判断市电中断
# 配置参数
GATEWAY_IP="192.168.1.1" # 修改为您的路由器IP
CHECK_INTERVAL=30 # 检查间隔(秒)
MAX_FAILURES=3 # 最大失败次数
SHUTDOWN_DELAY=300 # 关机延迟时间(秒),根据UPS电池续航调整
LOG_FILE="/var/log/ups-monitor.log"
# 初始化变量
FAILURE_COUNT=0
IN_SHUTDOWN=0
# 日志函数
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
logger -t UPS "$1"
}
# 关机函数
initiate_shutdown() {
log_message "=== 开始关机序列 ==="
log_message "检测到市电中断,UPS电池供电中..."
log_message "将在 $SHUTDOWN_DELAY 秒后关闭系统"
# 发送关机通知(可选)
/bin/hostdProbe.sh > /dev/null 2>&1 &
# 安全关闭所有虚拟机
log_message "开始安全关闭虚拟机..."
# 首先尝试正常关机
for VMID in $(vim-cmd vmsvc/getallvms | grep -v "Vmid" | awk '{print $1}'); do
VM_NAME=$(vim-cmd vmsvc/get.config $VMID | grep "name =" | awk -F'"' '{print $2}')
POWER_STATE=$(vim-cmd vmsvc/power.getstate $VMID | grep "Powered on")
if [ "$POWER_STATE" ]; then
log_message "正常关闭虚拟机: $VM_NAME (ID: $VMID)"
vim-cmd vmsvc/power.shutdown $VMID
fi
done
# 等待虚拟机关闭
log_message "等待虚拟机正常关闭..."
sleep 180
# 检查并强制关闭仍在运行的虚拟机
log_message "检查未关闭的虚拟机..."
for VMID in $(vim-cmd vmsvc/getallvms | grep -v "Vmid" | awk '{print $1}'); do
POWER_STATE=$(vim-cmd vmsvc/power.getstate $VMID | grep "Powered on")
VM_NAME=$(vim-cmd vmsvc/get.config $VMID | grep "name =" | awk -F'"' '{print $2}')
if [ "$POWER_STATE" ]; then
log_message "强制关闭虚拟机: $VM_NAME (ID: $VMID)"
vim-cmd vmsvc/power.off $VMID
fi
done
# 最终等待
sleep 30
# 关闭ESXi主机
log_message "关闭ESXi主机系统..."
/sbin/poweroff
}
# 主循环
log_message "UPS监控脚本启动 - 目标IP: $GATEWAY_IP, 检查间隔: ${CHECK_INTERVAL}秒"
while true; do
# 检查网络连通性
if ping -c 3 -W 1 $GATEWAY_IP > /dev/null 2>&1; then
# 网络正常
if [ $FAILURE_COUNT -gt 0 ]; then
log_message "网络恢复,重置故障计数器"
FAILURE_COUNT=0
IN_SHUTDOWN=0
fi
else
# 网络中断
FAILURE_COUNT=$((FAILURE_COUNT + 1))
log_message "网络连接失败 #$FAILURE_COUNT (最大允许: $MAX_FAILURES)"
if [ $FAILURE_COUNT -ge $MAX_FAILURES ] && [ $IN_SHUTDOWN -eq 0 ]; then
log_message "达到最大失败次数,判断为市电中断"
IN_SHUTDOWN=1
initiate_shutdown &
fi
fi
sleep $CHECK_INTERVAL
done
EOF
# 设置脚本权限
chmod +x /vmfs/volumes/datastore1/scripts/ups-monitor.sh
步骤2:创建启动脚本
# 创建启动脚本
cat > /vmfs/volumes/datastore1/scripts/start-ups-monitor.sh << 'EOF'
#!/bin/sh
# UPS监控启动脚本
# 等待系统完全启动
sleep 120
# 检查是否已有监控进程在运行
if ps | grep -v grep | grep "ups-monitor.sh" > /dev/null; then
echo "UPS监控已在运行中"
exit 0
fi
# 启动监控脚本
/vmfs/volumes/datastore1/scripts/ups-monitor.sh &
echo "UPS监控脚本已启动"
EOF
chmod +x /vmfs/volumes/datastore1/scripts/start-ups-monitor.sh步骤3:配置自动启动
由于ESXi重启后会重置/etc/rc.local.d,我们需要创建一个持久化的启动机制:
# 创建本地启动脚本
cat > /etc/rc.local.d/start-ups-monitor.sh << 'EOF'
#!/bin/sh
# 启动UPS监控
/vmfs/volumes/datastore1/scripts/start-ups-monitor.sh &
exit 0
EOF
chmod +x /etc/rc.local.d/start-ups-monitor.sh
步骤4:配置参数调整
重要:编辑监控脚本,修改以下参数以适应您的环境:
# 使用vi编辑脚本
vi /vmfs/volumes/datastore1/scripts/ups-monitor.sh需要修改的参数:
GATEWAY_IP="192.168.1.1" # 改为您的路由器IP地址
CHECK_INTERVAL=30 # 检查频率(秒),建议20-60秒
MAX_FAILURES=3 # 连续失败次数,建议2-4次
SHUTDOWN_DELAY=300 # 关机延迟(秒),根据UPS电池续航调整步骤5:手动启动监控(立即生效)
# 手动启动监控脚本
/vmfs/volumes/datastore1/scripts/ups-monitor.sh &步骤6:验证脚本运行
# 检查进程是否运行
ps | grep ups-monitor
# 查看监控日志
tail -f /var/log/ups-monitor.log
# 查看系统日志
tail -f /var/log/syslog.log | grep UPS参数配置建议
根据UPS电池容量调整
网络稳定性考虑
如果网络偶尔不稳定,建议:
MAX_FAILURES=4或5CHECK_INTERVAL=45
测试方案
模拟测试(重要!)
测试前确保所有虚拟机已备份!
# 1. 临时修改脚本,缩短延迟用于测试
cp /vmfs/volumes/datastore1/scripts/ups-monitor.sh /vmfs/volumes/datastore1/scripts/ups-monitor-test.sh
# 编辑测试脚本,修改以下参数:
# SHUTDOWN_DELAY=60 # 改为60秒便于测试
# MAX_FAILURES=2 # 改为2次加快触发
# 2. 启动测试脚本
/vmfs/volumes/datastore1/scripts/ups-monitor-test.sh &
# 3. 模拟网络中断:拔掉路由器电源
# 观察日志,确认脚本正确检测并触发关机流程
# 4. 测试恢复:重新接通路由器电源
# 在关机延迟期间恢复网络,观察是否取消关机日常监控命令
# 查看监控状态
ps | grep ups-monitor
# 实时监控日志
tail -f /var/log/ups-monitor.log
# 检查最近的活动
grep "UPS" /var/log/syslog.log
# 查看脚本是否在启动项中
cat /etc/rc.local.d/start-ups-monitor.sh故障排除
常见问题解决
脚本不启动
# 检查脚本权限
chmod +x /vmfs/volumes/datastore1/scripts/*.sh
# 手动测试脚本
/vmfs/volumes/datastore1/scripts/ups-monitor.sh2.无法ping通网关
# 测试网络连通性
ping 192.168.1.1
# 检查网关IP是否正确
net-stats -l3.重启后脚本不自动运行
# 重新创建启动脚本
cat > /etc/rc.local.d/start-ups-monitor.sh << 'EOF'
#!/bin/sh
/vmfs/volumes/datastore1/scripts/start-ups-monitor.sh &
exit 0
EOF
chmod +x /etc/rc.local.d/start-ups-monitor.sh注意事项
确保路由器不接UPS:这是方案有效的前提
定期测试:每季度测试一次断电保护功能
监控电池状态:定期检查UPS电池健康状况
备份重要数据:确保重要虚拟机有备份
通知相关人员:让团队知道有这个自动关机机制
这个方案已经在很多环境中成功部署,只要确保网络设备不在UPS上,就能可靠地检测市电中断并安全关机。
本文由
我的学习记录
提供,采用 知识共享署名4.0
国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:
2025年11月05日