UPS と NAS, Linux サーバを連携させる


やりたいこと

電力供給が途絶えたら、UPS に繋いだ NAS と Linux サーバを自動シャットダウンさせる。

環境

UPS

APC Smart-UPS 500

NAS

QNAP TS-451+ (IP Address: 192.168.1.10)

Linux サーバ

OS: Ubuntu 18.04 LTS (IP Address: 192.168.1.20)

前提として

UPS と何かのマシン 1 台だけ繋いで連携させるのはそれほど難しくない。しかし繋ぐマシンが 2 台以上になると設定が面倒になる。

そもそも、UPS からの電源供給に関する通知(停電したとか)は、USB によるシリアル通信で行われる。しかし UPS と直接シリアル接続できるマシンは、(少なくとも自分の所有する UPS については) 1 台のみである。

では 2 台目以降のマシンはどうやって通知を受け取るのかというと、UPS と 直接シリアル接続しているマシンから受け取る。ここで、UPS と直接シリアル接続しているマシンを master、master から通知を受け取るマシンを slave と呼ぶ。

今回は、NAS を master、Linux サーバを slave とした。

設定手順

master (NAS) 側

やることは
1. UPS と NAS を USB 接続する
2. NAS の設定で UPS との接続方法を USB とし、ネットワーク内の他のマシンへの電源供給に関する通知を有効にする
3. slave が電源供給情報を取得するための nut ユーザ作成
4. NAS の UPS name の確認

以下は QNAP における手順です。他の製品の場合はそれのドキュメントを参照してください。

UPS と QNAP を USB 接続したら QNAP のコントロールパネルを開き、システム → 外部デバイス → UPS と進む。

繋ぎ方は「USB 接続」とする。また「ネットワーク UPS サポート」を有効にし、通知を有効にする IP アドレスには slave のもの (ここでは 192.168.1.20) を入力する。

次に slave が電源供給情報を取得するための nut ユーザを作成する。admin として QNAP に SSH 接続し、/etc/config/ups/upsd.users に以下を追記する。

[monslave]
    password=[好きなパスワード]
    upsmon slave

また /etc/config/ups/ups.conf の中身を参照し、QNAP の UPS name を確認しておく。以下の例では qnapups が UPS name である。

$ less /etc/config/ups/ups.conf
[qnapups] ← []の中身が UPS name
    driver = usbhid-ups
    port = /dev/ttyS1
    desc = "Workstation"
    pollinterval=2

設定が終わったら QNAP を再起動。

slave (Linux サーバ)側

nut の入手

OS が Ubuntu なので、必要なソフトウェアは apt で入手する。使うのは nut というパッケージである。以下のコマンドでインストールする。

$ sudo apt install nut

nut 設定ファイルの編集

Ubuntu の場合設定ファイルは /etc/nut/ にある。ここにあるファイルは以下の通り。

$ ls /etc/nut/
nut.conf  ups.conf  upsd.conf  upsd.users  upsmon.conf  upssched.conf

このうち、slave として機能させるためにいじる必要があるのは nut.conf upsmon.conf upssched.conf の 3 つである。編集する前に必ずコピーをとっておきましょう。

またこれらのファイルの所有グループが nut になっていないと動作しないため、確認しておきましょう。

nut.conf

以下を追記する。(競合する設定はコメントアウトする)

MODE=netclient

upsmon.conf

このファイルは、upsmon というデーモンの設定ファイルである。upsmon は UPS の状態通知を受け取り、その状態によってログを吐いたり wall でブロードキャストしたりする。upsmon.conf に以下を追記する。(競合する設定はコメントアウトする)

MONITOR [email protected]:3493 1 monslave [monslaveのパスワード] slave
NOTIFYCMD /sbin/upssched
NOTIFYFLAG ONLINE       SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT       SYSLOG+WALL+EXEC

一行目の MONITOR で始まる行には、master の情報を記載する。

二行目の NOTIFYCMD で始まる行には、状態通知が来た際に実行する upssched のパスを記載する。このパスは環境によって変わる可能性がある。

四行目の NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC は、電源供給が途絶えてバッテリー駆動になった時の挙動を設定している。最後の EXEC がないと、二行目の upssched が実行されない。

三行目の NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC は同様に、電源が復旧した際の挙動を設定している。

upssched.conf

上の upsmon.conf 設定により、バッテリー駆動 or 電源復旧の通知が来たら、upssched が実行されるようになった。 今度はその upssched の挙動の設定を行う。

upssched.conf に以下を追記する。(競合する設定はコメントアウトする)

CMDSCRIPT /bin/upssched-cmd
PIPEFN /var/run/nut/upssched.pipe
LOCKFN /var/run/nut/upssched.lock
AT ONBATT * START-TIMER upsgone 120
AT ONLINE * CANCEL-TIMER upsgone

一行目の CMDSCRIPT /bin/upssched-cmd は、upssched が実行するスクリプト upssched-cmd のパスである。これも環境により変わる可能性がある。

二、三行目には upssched の実行の際に作られる一時ファイルのパスである。ディレクトリ /var/run/nut/ は、ユーザ nut が書き込めるような権限にしておく必要がある。/var/run/nut/ の所有グループを確認しておき、nut になっていなければ nut に変更すること。

四行目は、バッテリー駆動になったら 120 秒後に upssched-cmd を実行する設定をしている。upsgoneupssched-cmd に渡される引数である。

五行目では、電源復旧したら四行目のタイマーをキャンセルするよう設定している。

/bin/upssched-cmd

最後に upssched-cmd にシャットダウン処理を加える。

case $1 in
        upsgone)
                logger -t upssched-cmd "The UPS has been gone for awhile"
                upsmon -c fsd ←これを追記
                ;;
        *)
                logger -t upssched-cmd "Unrecognized command: $1"
                ;;
esac

追記した upsmon -c fsd により、シャットダウンが行われる。

ここまで設定が終わったら、nut-client を再起動する。

$ sudo service nut-client restart

これで、停電時に NAS と Linux サーバの両方のシャットダウンが行えるようになった。

参考