esxi停电后自动关机配置教程

in with 0 comment

方案思路

  • 前提条件:您的路由器/交换机等网络设备不连接在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电池容量调整

UPS电池续航

SHUTDOWN_DELAY

CHECK_INTERVAL

说明

5-10分钟

180秒 (3分钟)

20秒

短续航,快速响应

10-20分钟

300秒 (5分钟)

30秒

中等续航

20-30分钟

480秒 (8分钟)

45秒

长续航,更保守

网络稳定性考虑

如果网络偶尔不稳定,建议:

  • MAX_FAILURES=45

  • CHECK_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

故障排除

常见问题解决

  1. 脚本不启动

# 检查脚本权限
chmod +x /vmfs/volumes/datastore1/scripts/*.sh

# 手动测试脚本
/vmfs/volumes/datastore1/scripts/ups-monitor.sh

2.无法ping通网关

# 测试网络连通性
ping 192.168.1.1

# 检查网关IP是否正确
net-stats -l

3.重启后脚本不自动运行

# 重新创建启动脚本
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

注意事项

  1. 确保路由器不接UPS:这是方案有效的前提

  2. 定期测试:每季度测试一次断电保护功能

  3. 监控电池状态:定期检查UPS电池健康状况

  4. 备份重要数据:确保重要虚拟机有备份

  5. 通知相关人员:让团队知道有这个自动关机机制

这个方案已经在很多环境中成功部署,只要确保网络设备不在UPS上,就能可靠地检测市电中断并安全关机。

评论: