首页 >教育信息化 >本期目录>正文

如何在断电后安全关闭服务器

来源:河南工程学院 作者:胡耀东 河南工程学院计算机学院副教授 发表于:2020.09.30  675浏览


文/胡耀东 河南工程学院计算机学院副教授
        意外断电对服务器、虚拟化平台,特别是运行UNIX系统的数据库服务器等简直是灾难性的,轻则数据库回滚、文件系统检查,重则数据信息丢失、崩溃以及系统无法进入等。为防止意外断电,各种类型的数据中心、机房几乎都配备了UPS电源,对关键和重要的服务器加以保护,用来保障电力中断时系统能够正常运行,维持服务的持续性。经过多年发展,数据中心逐步采用了模块化UPS,满足了在线更换、增容等要求,可靠性进一步提高。
        但使用UPS也带来了新的问题,比如:断电后空调无法工作,导致温度过高;断电时间较长,电池耗完后系统断电等。因此,在断电后安全关闭相关的服务器是很必要的。
        一、常规解决方案
        主流的UPS厂商提供了相应的解决方案,常见的有以下两种:
        1.提供RS232或RS485接口
        使用对应的串口线缆和相应的UPS管理软件,可以满足关闭服务器和UPS自身的需求。这种方案的主要问题是需要额外的串口电缆,服务器需要相应的接口,不加扩展只能关闭一个服务器。
        2.提供UPS智能卡接口
        除了提供一些I/O接口、温湿度等接口外,通常提供有网络接口。通过网络接口可以较为完整地控制UPS的行为,也能通过网络接口和相应的软件在发生长时间停电后关闭一定数量的服务器。一般情况下要求服务器和UPS管理卡在同一网段,并安装对应的软件,同时关闭的服务器数量有一定的限制等。
        以上方式通常能够满足一部分需求,但是部分管理人员抵触安装UPS管理软件,且关闭同网段的服务器也有一定的限制等。如何克服以上方式的限制,在不增加硬件成本的情况下获取断电信息、利用系统本身的功能安全关闭服务器是一个值得探讨的有趣问题。
        二、新方案探索
        1.在不增加硬件成本的情况下获取断电信息
        在不增加硬件成本的情况下,我们分三种情景获取断电信息。
        (1)IPMI获取断电信息
        IPMI是智能型平台管理接口(Intelligent Platform Management Interface)的缩写,是管理基于Intel结构的企业系统中所使用的外围设备采用的一种工业标准,该标准由英特尔、惠普、NEC、美国戴尔电脑和SuperMicro等公司制定。用户可以利用IPMI监视服务器的物理健康特征,如温度、电压、风扇工作状态、电源状态等。更为重要的是,IPMI是一个开放的免费标准,用户无需为使用该标准而支付额外的费用。
        IPMI协议被广泛用于服务器监控中,包括采集CPU温度、风扇转速、主板温度以及远程开关机等。IPMI的硬件设备BMC(Baseboard Management Controller)是一个独立的板卡,独立供电。因此IPMI独立于硬件和操作系统,无论是CPU、BIOS,还是OS出现故障,都不会影响它的工作。目前主流的服务器都提供了该接口,只需将该接口接入网络,进行相关配置后即可使用。
        在Linux环境可以联网的环境下只需要敲入命令 “[root@localhost ]# yum install OpenIPMI OpenIPMI-tools OpenIPMI-libs OpenIPMI-devel”,就可以安装相应的软件包。如无法访问外网可以下载相应的软件包安装。
        安装完需要启用IPMI服务,可以敲入“service ipmi start”。开机自动启用服务则可以敲入“chkconfig ipmi on”。
        该方式可以在本地和远程环境下使用。
        本地使用时,在shell环境下直接键入:
        [root@localhost ]#  ipmitool sdr elist | grep -E "(Power1|Power2)"。
        显示信息如下:
        Power1           | 07h | ok  | 10.96 | 123 Watts
        Power2           | 08h | ok  | 10.97 | 96 Watts
        其中Power1是UPS供电,Power2是市电供电。依据此环境,结合grep和awk命令写出脚本如下:
        #!/bin/bash
        power_ipmi=`ipmitool sdr elist | grep -E "(Power2)" | awk '{print $9}'`
        echo "power is: $power_ipmi"
        运行该脚本可以直接获得电源2的即时功率,并打印出功率信息。
        远程环境下使用时,假设远程IPMI的IP地址是192.168.1.100,用户名是root,密码是password,远程IPMI服务器是华为的2288v2,键入“ipmitool -H 192.168.1.100 -U root -P password -I lan sdr elist”即可。
        (2)SNMP获取断电信息
        简单网络管理协议(SNMP,Simple Network Management Protocol)是基于C/S的模型。它实现了这样一种功能:当管理端需要获取被管理端的一个状态信息时,管理端就发送一个获取指令给被管理端,被管理端收到此指令后把管理端要获取的信息封装成报文后返回给管理端;当管理端需要修改被管理端上的一些配置参数时,管理端就发送一个修改指令给被管理端,被管理端收到后修改相应的配置,如果修改成功则返回修改成功的信息给管理端,如果未修改成功则返回相应的错误信息给管理端;如果被管理端自己知道自己发生了故障,那它就主动发送一个消息给管理端,说明自己哪里出现了故障。
        根据对应的mib串,我们可以获得网络设备的信息。下面我们以H3C的三层交换机5820为例,获取电源状态信息。该设备有两个电源模块——电源模块1为ups供电、电源模块2为市电供电,交换机的community只读共同体名字为public,IP地址为192.168.1.1。
        管理机为Linux系统安装了net-snmp管理包,通过对电源模块2的接通电源和断掉电源的状态比较如下:
        接通市电:
        [root@localhost ]# snmpwalk -v 2c -c pubic 192.168.1.1 1.3.6.1.4.1.25506.8.35.9.1.2.1.2
        SNMPv2-SMI::enterprises.25506.8.35.9.1.2.1.2.1 = INTEGER: 1
        SNMPv2-SMI::enterprises.25506.8.35.9.1.2.1.2.2 = INTEGER: 1

        断掉市电:

        [root@localhost ]# snmpwalk -v 2c -c pubic 192.168.1.1 1.3.6.1.4.1.25506.8.35.9.1.2.1.2
        SNMPv2-SMI::enterprises.25506.8.35.9.1.2.1.2.1 = INTEGER: 1
        SNMPv2-SMI::enterprises.25506.8.35.9.1.2.1.2.2 = INTEGER: 2
        结合awk命令写出可以直接获得市电状态标记的脚本:
        #!/bin/bash
        snmp_state=`snmpwalk -v 2c -c pubic 192.168.1.1 1.3.6.1.4.1.25506.8.35.9.1.2.1.2.2 | awk '{print $4}'`
        echo “power state is: $ snmp_state”
        运行该脚本,市电供电的情况下是1,断电的情况下输出为2。
        (3)ping获取断电信息
        我们可以在shell状态下用ping命令,通过简单的shell脚本,获取市电状态信息,其中192.168.1.254是一个市电供电的网络设备,简单脚本如下:
        #! /bin/bash
        ping -c 1 192.168.1.254 > /dev/null 2>&1
        echo “power state is: $?”
        脚本仅检查了ping一个包的情况。对于较稳定的主干设备,ping一个包的可靠性是没有问题的。如果需要更高的可靠性,则可以多ping几个包。
        2.利用系统自身功能安全关闭服务器 
    获取了市电状态,依赖UPS电力供应,结合操作系统的计划任务,我们就可以根据UPS的能力及实际需要,在市电中断的情况下自由选择多长时间关闭服务器。下面我们以Linux系统为例,编写一个简单的shell脚本,添加计划任务,完成安全关闭系统服务器的任务。
        利用IPMI读取连接市电电源的功率,判断市电状态shell。此shell可以判断电源提供的功率是否为0。“0”代表市电中断,则需要测试断电后的状态。测试中断电可以先不使用shutdown关闭系统,可以采用一些命令来测试状态是否与设想一致。如下:
        #! /bin/bash
        power_ipmi=`ipmitool sdr elist | grep -E "(Power2)" | awk '{print $9}'`
        if [$power_ipmi -eq 0 ];then
        echo “power is bad”
        shutdown –h now
        else
            echo “power is ok”
        fi
        利用SNMP函数读取双电源供电的交换机状态,以判断市电状态关闭系统的shell。此shell直接读取市电供电的交换机的电源模块状态,也需要验证是否与设想一致。如下:
        #! /bin/bash
        snmp_state=`snmpwalk -v 2c -c pubic 192.168.1.1 1.3.6.1.4.1.25506.8.35.9.1.2.1.2.2 | awk '{print $4}'`
        if [$snmp_state -eq 2 ];then
        echo “power is bad”
        shutdown –h now
        else
            echo “power is ok”
        fi
        利用ping命令获取市电状态关闭系统的shell。此shell可以判断网络中市电供电的设备状态,如果关闭服务器,也需要验证是否和设想的一致。如下:
        #! /bin/bash
        ping -c 1 192.168.1.254 > /dev/null 2>&1
        if [ $? -eq 0 ];then
            echo “power is ok”
        else
        echo “power is bad”
        shutdown –h now
        fi
        添加到计划任务中,假设上面断电关机的shell名称为power.sh,在linux系统直接可以运行crontab –e,添加一行“*/5 * * * * /sbin/power.sh >> null”即可。
        系统会每5分钟检测一下市电状态。当检测到市电断电后,即可执行关机shell,根据UPS电池和需求灵活调整该时间间隔。该计划任务在最极端情况下市电断电5分钟内关闭系统。
        除了UPS厂商提供的方案,本文至少探讨了三种方法检测市电状态。这些方法在各类机房、数据中心是比较容易实现的,不增加硬件费用,且不需服务器有相关的RS232、RS485等接口,在虚拟机环境下也容易实现,关闭的服务器数量没有限制,没有安装第三方软件,文中大部分是以Linux环境为基础的,实际上在各类Windows系统上,MacOS系统上都可以实现。
        三、注意事项
        1.利用本地IPMI,需要服务器自身有双电源——一路为UPS供电,一路为市电供电。如果读取远程的IPMI信息,在笔者的环境下我们发现,服务器的网段只有和远程的IPMI接口网段在同一网段时,才能够读到具体的电源功率。
        2.利用SNMP读取市电状态,在笔者的环境下,需要一个双电源的交换机——一路UPS供电、一路市电供电,只要服务器和交换机IP可达即可实现。
        3.利用ping命令获取市电状态,这种方式适用的范围更加广泛。在同一机房有市电供电的可网管设备下方便使用。在整个机房供电全部由UPS供电环境下,可以寻找一个在同一变压器供电的比较重要的外围市电供电的网络设备来判断。


相关阅读