Postmortem: UPS 测试导致系统停机故障的事后回顾

• 本文约 2384 字,阅读大致需要 5 分钟 | Life | #CyberPower | #nut

摘要

事故影响

由于 UPS 测试触发了系统停机,导致 delphij.net 部分服务停止了约40分钟。服务从 2023-01-16 15:46:20 开始受到影响,至 16:26:55 完全恢复。 如果服务未能及时修复,潜在地将会进一步影响包括权威DNS(有多个独立的冗余,但依赖于持续的数据更新)在内的一些其他关键服务。

问题根源

在测试时对于 CyberPower UPS 测试特性的认识不足导致电池电量消耗至临界值, 由于对 nut 的配置未考虑这种情况直接将服务器关闭, 这使得必须亲自到机房才能完成服务的恢复。

故障背景

nut 是在2023年1月13日开始近采用的,用来替换配合 APC UPS 使用的 apcupsd 的 UPS 管理软件。与 apcupsd 类似, 它也提供了在电池电量低于警戒线时关闭系统的功能。

nut 提供的针对 CyberPower SX650G UPS 的驱动中提供了 test.battery.start.deep 指令, 对于大部分其他 UPS 而言,该指令的作用是将 UPS 的电池消耗到 low battery 水平之后再恢复从交流电充电。

为了验证在使用 nut 时系统仍然可以像在使用 apcupsd 时那样正确关闭和重启系统, 于2023年1月16日对其一系列 UPS 和 nut 特性进行了测试。

问题根源及触发过程

此测试过程中,对于 UPS 的深度电池测试导致电池的电量低于了此前设置的 20% 水平,而 UPS 的控制器并未如其他 UPS 那样在此时恢复从交流电供电进行充电, 并且此时 nut 的 upsmon 由于收到了电池电量过低的信号,如配置那样地开始了关机过程。

影响

本次故障导致 delphij.net 部分服务从 2023-01-16 15:46:20 开始受到影响,直至 16:26:55 完全恢复,共计约40分钟。 由于受影响的服务器提供了到某些其他服务的隧道,导致家中的网络也受到了影响。

教训

较顺利的部分

不顺利的部分

幸运的部分

总结、后续及其他发现

试验未能达到预想的测试 UPS 电池深度测试的目标,操作人员到达机房时的首要任务是恢复服务,因此选择破坏了部分现场并导致无法获得完整的试验数据;此外,测试未能证明在实际发生长时间断电之后在供电恢复时,系统是否能在没有人在现场手工干预的情况下重新启动,这需要在后续的测试中加以解决。

作为一款消费级的产品,CyberPower SX650G UPS 的 USB 接口协议,以及其控制器的 datasheet 不易获得,这意味着想要确切了解其指令行为并不容易。nut 提供的开源驱动中,也只是简单地实现了相关接口,对于其行为是否能够达到与文档或代码预期的全部目标并无充分的测试,这并不是开源项目的责任,但作为用户应该对此有所认知,并在使用时考虑这一因素。

测试证明此前配置的关机的部分能够在需要时正确触发,并且工作正常(尽管这本身导致了服务中断)。

配置的数据采集系统在放电测试过程中记录了放电数据,证实了目前配置能够达到系统对于后备电源的需要,而这些是最初打算进行这些测试想要达到的核心目标,故而可以认为此次试验的主要目的达成了。

后续计划

  1. 关机应由命令改为脚本,并考虑 UPS 的交流电决定是否真的实施关闭系统的操作。
  2. 在生产环境中进行测试时,应更好地遵守一系列原则,例如:a) 不要在生产环境中进行测试,b) 必须进行此类测试时,应提前设计方案,以非破坏性的命令替代实际的破坏性操作。
  3. 需要对真实的断电场景进行单独的测试。
  4. 对 nut 的 LOWBATT 事件处理部分进行改进,加入对于是否正在充电的处理:只有在处于 LOWBATT 并且电池处于放电状态时的情形,才应触发 shutdown。

时间线(所有时间为当地,即太平洋标准时间PST,或协调世界时UTC -08:00)