Happy Elements 株式会社 カカリアスタジオ Advent Calendar 2016 の 6 日目です.本日の担当はインフラグループの @nagizero です.よろしくお願いします.
はじめに
弊社では停電トラブルに備えて社内サーバを UPS に接続しています. APC 製の UPS を使っているので apcupsd を利用して UPS の電源状態とサーバの状態を連動させることができて便利です1.停電時にはサーバが自動的にシャットダウンし,復電時にはサーバが自動的に起動するように設定しています2.以下,本稿では UPS の導入方法についてざっくりと記述していきます.
UPS 接続
UPS をサーバに接続します (電源の接続にあらず).弊社ではシリアル接続していますが, USB 接続でもよいでしょう.
apcupsd 導入
サーバで UPS の状態を取得できるようにするために apcupsd を導入します.
インストール
Debian 系は apt, RHEL 系は yum, Mac は brew でインストールできます.
# apt-get install apcupsd
# yum install apcupsd
% brew install apcupsd
設定
サーバは複数台ありますが, UPS と直接シリアル通信できるサーバは 1 台のみです.ではシリアル接続していないサーバはどのように UPS の情報を取得するかというと,シリアル接続しているサーバから情報を共有してもらいます (apcupsd にはイーサネット経由で UPS の情報を共有する仕組みが用意されています).以下,シリアル接続しているサーバを master, シリアル接続していないサーバを slave と記述します.
master
シリアル接続のデバイス名を確認して設定ファイルを修正します.
$ dmesg | grep tty
[    0.000000] console [tty0] enabled
[    1.196111] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[    1.402765] 00:0a: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
-PSCABLE usb
+UPSCABLE smart     # シリアル接続
-UPSTYPE usb
+UPSTYPE modbus     # 新型 UPS (前面に LCD ありのモデル) では modbus を使用
-DEVICE
+DEVICE /dev/ttyS0  # シリアル接続のデバイス
-TIMEOUT 0
+TIMEOUT 60         # 停電状態が 60 秒継続するとシャットダウン開始
-NISIP 127.0.0.1
+NISIP 0.0.0.0      # UPS 情報を他のサーバと共有するためのアクセス許可
設定を反映すると apcaccess コマンドで UPS の情報を取得できるようになります.
$ apcaccess
UPSNAME  : APCUPS
CABLE    : Custom Cable Smart
DRIVER   : MODBUS UPS Driver
UPSMODE  : Stand Alone
STATUS   : ONLINE
LINEV    : 105.8 Volts
LOADPCT  : 33.8 Percent
BCHARGE  : 100.0 Percent
TIMELEFT : 38.0 Minutes
.
.
.
slave
master ではシリアル接続のデバイスを指定しましたが, slave では master の IP アドレスとポートを指定します.
-PSCABLE usb
+UPSCABLE ether  # イーサネット経由でデータを取得
-UPSTYPE usb
+UPSTYPE net     # 同上
-DEVICE
+DEVICE 172.16.1.1:3551  # master の IP:port を指定
-TIMEOUT 0
+TIMEOUT 60      # 停電状態が 60 秒継続するとシャットダウン開始
こちらも設定を反映すると apcaccess コマンドで UPS の情報を取得できるようになります. CABLE, MASTER, STATUS を見ると, slave として動作しており master からイーサネット経由で情報を取得していることがわかります.
$ /sbin/apcaccess
UPSNAME  : APCUPS
CABLE    : Ethernet Link
UPSMODE  : Stand Alone
MASTER   : 172.16.1.1:3551
STATUS   : ONLINE SLAVE
LINEV    : 104.4 Volts
LOADPCT  :  34.4 Percent Load Capacity
BCHARGE  : 100.0 Percent
TIMELEFT :  39.0 Minutes
.
.
.
以上で apcupsd の設定は完了したので,次はサーバの BIOS を設定します.
サーバの自動起動設定
通電時には問答無用でサーバが起動するように設定します.
Mac 以外
BIOS の設定を変更します.大抵のマシンの電源オプションには ON, OFF, Restore の 3 つの設定があると思います (Restore は last state などの表現の場合もあります). これを ON にします.
- ON: 通電時に起動する
 - OFF: 通電時に起動しない
 - Restore: 停電前の状態を維持する
 - 起動中に停電した場合は通電時に起動する
 - 停止中に停電した場合は通電時に起動しない
 
Mac
Mac では BIOS を触れないのですが,同様の設定は可能です.
まず,システム環境設定の省エネルギー設定で 停電後に自動的に起動 にチェックを入れます.これで Restore を指定した場合と同じ状態になります.
次に,シャットダウンコマンドを書き換えます. shutdown に -u オプションを渡すことで,正常にシャットダウンさせつつもステータスとしては異常終了させたことにできます.この結果,復電時には元の状態 (起動) を復元しようとして自動起動するようになります. apcupsd を利用した場合のシャットダウン動作は /usr/local/etc/apcupsd/apccontrol で定義されているので,下記のようにコマンドを書き換えます.
-SHUTDOWN=/sbin/shutdown
+SHUTDOWN="/sbin/shutdown -u"
以上でサーバを自動起動するように設定できました.
電源接続
サーバとネットワーク機器の電源を UPS に接続します. UPS の情報をイーサネット経由で共有しますので,サーバだけでなくルータやスイッチなどのネットワーク機器も忘れずに UPS に接続しておきます.
動作確認
最後に UPS とサーバの動作を確認します. UPS への電源供給を絶ったり戻したり (コンセントを抜いたり差したり) して停電時の動作を再現します.下記項目を確認します.
停電時
- UPS への電源供給が絶たれたことが全サーバに共有されること
 - タイムアウトするとサーバがシャットダウンされること
 - タイムアウトしなければサーバがシャットダウンしないこと
 - サーバのシャットダウンをトリガーとして UPS がシャットダウンすること
 
復電時
- 指定時間が経過すると UPS からの電源供給が開始されること
 - 指定時間が経過しなければ UPS からの電源供給が開始されないこと
 - UPS からの電源供給が開始されるとサーバが起動すること
 
おわりに
UPS を導入して停電に備える方法をざっくりと記述しました.停電は頻繁に起きるものではありませんが,不意に訪れるトラブルなのでできるだけ早く対策しておきたいですね.
最後に, UPS を導入するに当たり参考にさせていただいたページを列挙します.たいへん助かりました.どうもありがとうございました.
- UPS for Linux
 - apcupsd で APC 製 UPS を電源管理する方法 - maruko2 Note.
 - APC SmartUPS の新型 (SmartUPS-XXX LCD) タイプで apcupsd を使うときのメモ - Qiita
 - APC Smart-UPS+apcupsd で復電後にサーバが再起動しない問題について
 - pc.casey.jp » [UPS] Apcupsd で UPS 連携 (1)
 - http://www.hyperdyne.co.jp/contents/ShutDownEx/apcupsd02.htm