基于 Ubuntu + CyberPower UPS 服务器电源管理方案
这是一个基于 Ubuntu Server 和 官方 CyberPower PowerPanel (pwrstat) 打造的 UPS 电源管理方案。专为监控 CyberPower OLS1000E 等系列 UPS 并在断电时优雅关闭 ESXi 主机及虚拟机而设计。
方案特性
硬件解耦: 监控设备(ThinkPad T450 笔记本)通过笔记本内置电池独立供电,与 UPS 解耦,即使 UPS 耗尽电量也能持续运行监控逻辑。
企业级原生驱动: 由 CyberPower 官方
pwrstatd守护进程接管告警,消除开源轮询方案因协议适配不佳导致的不稳定。断电重确认机制: 断电后进入可配置的延迟等待(默认 60s),期间多次调用
pwrstat反复确认,如市电恢复则自动终止关机。全生命周期日志: 每次断电全程记录
[LIFECYCLE:*]结构化事件、UPS 状态快照、断电持续时长,日志同步写入文件和 systemd journal。双保险硬件干预:
首选方法: SSH 到 ESXi 触发 Guest OS 优雅关机 (ACPI shutdown),随后关闭 ESXi 系统。
最终手段: 如果 SSH 故障/无响应,通过 IPMI (iDRAC) 强制切断电源,确保服务器硬件断电保全数据。
市电恢复检测:
ups-power-monitor服务持续轮询市电状态,恢复后自动记录断电持续时长,写入日志。自动恢复开机: 市电恢复后自动通过 IPMI (iDRAC) 发送开机指令,等待 ESXi 启动后自动退出维护模式,实现无人值守全自动恢复。
系统架构
graph TB
subgraph S_AC["市电供电"]
AC["🔌 市电 220V"]
end
subgraph S_UPS["CyberPower OLS1000E"]
UPS_IN["AC Input"]
UPS_BAT["🔋 UPS 电池"]
UPS_OUT["AC Output"]
UPS_USB["USB 通信口"]
end
subgraph S_T450["ThinkPad T450 - 监控端"]
T450_BAT["🔋 笔记本电池"]
T450_PWR["⚡ T450 电源"]
PWRSTATD["pwrstatd 守护进程"]
LOGGER["power-event-logger.sh"]
SHUTDOWN["shutdown.sh"]
MONITOR["power-restore-monitor.sh"]
HEALTH["healthcheck.sh"]
end
subgraph S_Dell["Dell R720XD - 受保护端"]
DELL_PWR["⚡ Dell 电源"]
ESXI["VMware ESXi"]
VMs["虚拟机群"]
IDRAC["iDRAC 8 Express"]
end
AC -->|供电| UPS_IN
UPS_IN --> UPS_OUT
UPS_BAT -.->|断电时切换| UPS_OUT
UPS_OUT -->|供电| T450_PWR
UPS_OUT -->|供电| DELL_PWR
UPS_USB -->|USB 状态通信| PWRSTATD
T450_BAT -.->|断电时独立供电| T450_PWR
PWRSTATD -->|pwrfail 事件| LOGGER
LOGGER -->|触发| SHUTDOWN
MONITOR -->|轮询检测恢复| LOGGER
SHUTDOWN -->|SSH 优雅关机| ESXI
SHUTDOWN -->|IPMI 降级关机| IDRAC
ESXI --> VMs
LOGGER -->|市电恢复 IPMI开机| IDRAC
style AC fill:#f9c74f,stroke:#f48c06,color:#000
style UPS_IN fill:#90be6d,stroke:#43aa8b,color:#000
style UPS_OUT fill:#90be6d,stroke:#43aa8b,color:#000
style T450_PWR fill:#577590,stroke:#277da1,color:#fff
style DELL_PWR fill:#f94144,stroke:#e63946,color:#fff
style IDRAC fill:#f94144,stroke:#e63946,color:#fff
断电关机流程图
flowchart TD
START(["⚡ 市电中断"])
START --> PWRSTATD["pwrstatd 检测到断电"]
PWRSTATD -->|延迟 60 秒| LOGGER["power-event-logger.sh"]
LOGGER --> SESSION["生成 Session ID & 记录 UPS 快照"]
SESSION --> SD["shutdown.sh 启动"]
SD --> DELAY{"断电重确认 等待 N 秒"}
DELAY -->|市电恢复| CANCEL(["✅ 取消关机"])
DELAY -->|仍在断电| SSH_CHECK{"ESXi SSH 可用?"}
SSH_CHECK -->|可达| GET_VMS["获取运行中 VM 列表"]
SSH_CHECK -->|不可达 120s 超时| IPMI_SOFT
GET_VMS --> SHUTDOWN_VMS["逐个关闭 VM"]
SHUTDOWN_VMS --> WAIT_VMS["等待 VM 全部停止 120s"]
WAIT_VMS --> MAINT["进入维护模式"]
MAINT --> SSH_ESXI["SSH 关闭 ESXi"]
SSH_ESXI --> WAIT60["等待 60s"]
style MAINT fill:#f9c74f,stroke:#f48c06,color:#000
WAIT60 --> CHECK_OFF{"IPMI 检查已关机?"}
CHECK_OFF -->|已关机| DONE(["✅ 关机完成"])
CHECK_OFF -->|仍在运行| IPMI_SOFT
IPMI_SOFT["IPMI Soft Power Off"]
IPMI_SOFT --> WAIT_SOFT{"等待超时后检查"}
WAIT_SOFT -->|已关机| DONE
WAIT_SOFT -->|仍未关机| IPMI_HARD
IPMI_HARD["⛔ IPMI Hard Power Off"]
IPMI_HARD --> VERIFY["验证关机状态"]
VERIFY --> DONE
style START fill:#e63946,stroke:#d62828,color:#fff
style CANCEL fill:#2a9d8f,stroke:#264653,color:#fff
style DONE fill:#2a9d8f,stroke:#264653,color:#fff
style IPMI_HARD fill:#e76f51,stroke:#e63946,color:#fff
全生命周期时序图
sequenceDiagram
participant AC as 市电
participant UPS as UPS
participant PD as pwrstatd
participant LOG as event-logger
participant SD as shutdown.sh
participant ESXI as ESXi
participant VM as VM
participant IDRAC as iDRAC
participant MON as restore-monitor
Note over AC,MON: 阶段一 断电检测
AC-xUPS: 市电中断
UPS->>UPS: 切换至电池供电
UPS->>PD: USB: Power Failure
PD->>PD: 等待60秒
PD->>LOG: pwrfail事件
LOG->>LOG: 生成Session ID
LOG->>LOG: 记录UPS快照
LOG->>SD: 调用shutdown.sh
Note over AC,MON: 阶段二 延迟重确认
loop 每5秒 共N秒
SD->>PD: pwrstat -status
alt 市电恢复
SD-->>SD: 取消关机
else 仍断电
SD->>SD: 继续等待
end
end
Note over AC,MON: 阶段三 优雅关机
SD->>ESXI: SSH检查连通性
SD->>ESXI: SSH获取VM列表
ESXI-->>SD: 返回VM列表
loop 逐个VM
SD->>ESXI: SSH关闭VM
ESXI->>VM: ACPI关机
VM-->>ESXI: 关机完成
end
SD->>SD: 等待VM关闭 120s
SD->>ESXI: 进入维护模式
ESXI-->>SD: 维护模式已启用
SD->>ESXI: SSH关闭ESXi
SD->>SD: 等待60秒
SD->>IDRAC: IPMI power status
alt 已关机
IDRAC-->>SD: off
else 仍运行
SD->>IDRAC: IPMI power soft
SD->>SD: 等待超时
alt 仍未关机
SD->>IDRAC: IPMI power off 强制断电
end
end
Note over AC,MON: 阶段四 市电恢复
AC-->>UPS: 市电恢复
UPS->>UPS: 切回市电供电
loop 每10秒轮询
MON->>PD: pwrstat -status
PD-->>MON: Normal
end
MON->>LOG: active事件
LOG->>LOG: 记录断电时长
LOG->>IDRAC: IPMI power on
IDRAC->>ESXI: 服务器开机
Note over LOG,ESXI: 阶段五 退出维护模式
loop 等待ESXi SSH就绪 最长5分钟
LOG->>ESXI: SSH连接测试
end
LOG->>ESXI: 检查维护模式状态
ESXI-->>LOG: Enabled
LOG->>ESXI: 退出维护模式
ESXI-->>LOG: Disabled
ESXI->>VM: VM自动启动
LOG->>LOG: MONITORING_RESUMED
硬件与软件要求
监控端: ThinkPad T450 笔记本,运行 Ubuntu 22.04,BIOS 配置上电自启,系统禁用休眠/挂起,7x24 运行。
受保护端: Dell PowerEdge R720XD(配备 iDRAC 控制器,IPMI over LAN 开启),运行 VMware ESXi。
UPS: CyberPower OLS1000E,通过 USB 连接至 T450。
环境依赖:
CyberPower PowerPanel for Linux (PPL): 必须事先使用 dpkg 安装(
sudo dpkg -i CyberPower_PPL_Linux...deb)并确认其服务已启动。ipmitool、sshpass
项目文件结构
ups-power-manager/
├── install.sh # 一键安装脚本
├── config/
│ ├── config.env # 主配置文件(ESXi / iDRAC / 参数)
│ └── logrotate.conf # 日志轮转配置(每周轮转,保留 12 周)
└── scripts/
├── shutdown.sh # 核心关机脚本(断电触发)
├── healthcheck.sh # 健康检查脚本(每小时定时运行)
├── power-event-logger.sh # 断电/恢复事件日志记录
├── power-restore-monitor.sh # 市电恢复轮询监控(常驻服务)
└── laptop-setup.sh # 监控端电源配置(禁用休眠等)
快速部署
克隆本仓库到您的 Ubuntu 监控节点:
git clone <https://github.com/erocat/ups-power-manager.git> cd ups-power-manager确保 UPS USB 线已插好,测试 pwrstat 可正确读取 UPS 状态:
sudo pwrstat -status修改
config/config.env,填入 ESXi 地址、iDRAC 地址及相应凭据;按需调整SHUTDOWN_DELAY(断电后观察等待秒数)。以 root 权限执行一键安装(自动部署脚本、绑定 pwrstat 断电事件、注册 systemd 服务):
sudo ./install.sh(首次部署) 配置监控端为永不休眠模式,并安装 logrotate 和 power-restore-monitor 服务:
sudo /opt/ups-power-manager/laptop-setup.sh sudo cp config/logrotate.conf /etc/logrotate.d/ups-power-manager # power-restore-monitor 由 install.sh 自动注册,或手动: sudo systemctl enable --now ups-power-monitor.service⚠️ 还需在 BIOS 中手动设置
After Power Loss → Power On以实现上电自启。
维护与测试
断电场景测试(三段式,从安全到真实)
Level 1:Dry-Run(零风险,推荐先跑)
sudo /opt/ups-power-manager/shutdown.sh --dry-run
不会发送任何关机指令,验证 SSH/IPMI 连通性和脚本逻辑。
Level 2:pwrstat 软件模拟(低风险)
sudo pwrstat -test
触发真实断电事件流程,但 UPS 仍在供电。脚本会进入延迟等待,30 秒内 pwrstat 自动恢复 Normal 状态,脚本自动取消关机,不会实际关机。
Level 3:真实拔电测试(⚠️ 演练前确认服务器数据已保存)
直接将市电插头从 UPS 拔掉,触发完整的真实断电保护流程。
日志查询
按断电 Session 查询完整链路:
# 1. 先找 Session ID(格式:OUTAGE-YYYYMMDD-HHMMSS)
grep "LIFECYCLE:POWER_FAILURE" /var/log/ups-power-events.log
# 2. 用 Session ID 过滤完整流程
grep "OUTAGE-20260305-065407" /var/log/ups-shutdown.log
生命周期关键事件标记:
LIFECYCLE:POWER_FAILURE_DETECTED 断电检测
LIFECYCLE:SHUTDOWN_START 关机流程入口
LIFECYCLE:DELAY_CHECK_START/DONE 延迟确认阶段
LIFECYCLE:VM_SHUTDOWN_START/DONE VM 关闭阶段
LIFECYCLE:ESXI_SSH_SHUTDOWN_START ESXi SSH 关机(含进入维护模式)
LIFECYCLE:IPMI_SOFT_START/FAILED IPMI Soft(降级路径)
LIFECYCLE:IPMI_HARD_START IPMI Hard(最终手段)
LIFECYCLE:SHUTDOWN_END 流程结束(含耗时)
LIFECYCLE:POWER_RESTORED 市电恢复
LIFECYCLE:OUTAGE_DURATION 本次断电持续时长
LIFECYCLE:AUTO_POWER_ON IPMI 自动开机
LIFECYCLE:EXIT_MAINTENANCE 退出 ESXi 维护模式(等待SSH→检查→退出)
LIFECYCLE:MONITORING_RESUMED 恢复正常监控
手动获取 UPS 快照:
sudo /opt/ups-power-manager/power-event-logger.sh snapshot
常用运维命令
pwrstat -status # UPS 当前状态
pwrstat -config # 断电事件绑定配置
systemctl status pwrstatd # pwrstatd 守护进程状态
systemctl list-timers ups-healthcheck.timer # 健康检查 timer 状态
systemctl status ups-power-monitor # 市电恢复监控服务状态
/opt/ups-power-manager/healthcheck.sh # 手动触发健康检查
注意事项
pwrstatd是整个方案的触发核心,务必确保它开机自启且正常运转:systemctl status pwrstatd。T450 笔记本不会因断电而关机(
Enable shutdown system: Off),依靠笔记本内置电池维持运行,全程执行对 ESXi/iDRAC 的远程关机操作。T450 笔记本必须在 BIOS 中配置上电自启 (
After Power Loss → Power On),否则断电恢复后需要手动开机。如需更改触发配置,使用
pwrstat -pwrfail -cmd <脚本路径> -duration <秒> -shutdown设定。如果需要重新配置笔记本节能设置,可重新运行
sudo /opt/ups-power-manager/laptop-setup.sh。
实际部署记录
初次部署: 2026-03-05 14:38(UTC+8)
日志增强更新: 2026-03-05 15:25(UTC+8)
目标服务器: 192.168.1.117(主机名: ups,Ubuntu 6.8.0-100-generic)
已部署文件
已注册 Systemd 服务
pwrstat 断电事件绑定(最终配置)
验证结果
✅
pwrstatd正常运行,UPS 通信正常(OLS1000E 在线)✅
shutdown.sh --dry-run测试通过✅
ups-healthcheck.timerenabled / active(开机自启)✅
ups-power-monitor.serviceenabled / active(市电恢复检测,开机自启)✅
laptop-setup.sh完成:休眠/挂起全部禁用,pwrstatd开机自启✅ T450 断电不关机(
Enable shutdown system: Off)✅ 真实断电事件已验证记录(2026-03-05 06:54 UTC,电池 95%,持续约 30 分钟)
✅ logrotate 配置已安装(每周轮转,保留 12 周)
⚠️
pwrstat -active事件绑定不支持(当前 PPL 版本限制),已由ups-power-monitor.service轮询替代⚠️ BIOS
After Power Loss → Power On需手动在服务器 BIOS 中设置
快速检查命令
# 在服务器 192.168.1.117 上执行
pwrstat -status # UPS 当前状态
pwrstat -config # 断电事件绑定配置
systemctl status ups-power-monitor # 市电恢复监控服务
systemctl list-timers ups-healthcheck.timer # 健康检查 timer
journalctl -t ups-power-manager --since "1 hour ago" # 最近 1 小时所有事件
tail -f /var/log/ups-shutdown.log # 实时关机流程日志
tail -f /var/log/ups-power-events.log # 实时断电事件日志
/opt/ups-power-manager/shutdown.sh --dry-run # 测试关机链路(安全模式)