intent

intent的blog

🚴自行车骑的最远的全栈工程师
github

UPS/NUT(ネットワークUPSツール)

UPS/NUT(ネットワーク UPS ツール)#

NUT#

NUT(ネットワーク UPS ツール)は、一連の便利な操作と通知の UPS ツールを統合しています。

Nut は主に 3 つのコアサービスを含んでいます:

  • nut-driver: このサービスは特定のドライバを介して UPS と通信します。
  • nut-server: このサービスは nut-driver を利用して UPS と通信し、UPS の状態をネットワークサービスを通じて公開します。
  • nut-monitor(nut-client): このサービスは nut-server に接続し、UPS の状態に応じて特定の応答を行います。

注意: nut-client は実際には systemd のソフトリンクファイルであり、本質的には nut-monitor です。

             ┌─────────────┐                  ┌────────────┐
       ┌──── nut-monitor ───────────────► nut-server
     └─────────────┘                  └────────────┘




 ┌─────────────┐                              ┌────────────┐
  upssched nut-driver
 └─────────────┘                              └────────────┘





┌────────────────┐                            ┌─────────────┐
  user scripts     UPS
└────────────────┘                            └─────────────┘

NUT のインストール#

pve コンソールから直接インストール

apt install -y nut

UPS に接続するには、次のコマンドを使用します:

# nut-scanner -U
SNMPライブラリが見つかりません。SNMP検索は無効です。
Neonライブラリが見つかりません。XML検索は無効です。
IPMIライブラリが見つかりません。IPMI検索は無効です。
USBバスをスキャン中。
[nutdev1]
	driver = "blazer_usb"
	port = "auto"
	vendorid = "0665"
	productid = "5161"
	product = "USB to Serial"
	vendor = "INNO TECH"
	bus = "001" 

または

/bin/upsc nutdev1@localhost
SSLを証明書データベースなしで初期化
battery.charge: 100
battery.voltage: 13.50
battery.voltage.high: 13.00
battery.voltage.low: 10.40
battery.voltage.nominal: 12.0
...

UPS の状態を確認します。

NUT Server の設定#

Nut のインストールが完了すると、自動的に /etc/nut ディレクトリに設定ファイルが生成されます。次の設定作業は、このディレクトリ内のさまざまな設定ファイルを調整することです。

nut.conf#

この設定は主に nut の実行モードを定義します。設定フィールドは MODE=xxxx のみで、選択可能な値とその意味は以下の通りです:

  • none: Nut が設定されていないか、外部システムで Nut サービスを起動している場合、"何もしない" と理解できます。
  • standalone: 独立モード、一般的に UPS が 1 台のみで、ローカルシステムのみを担当する場合(ネットワークサービスを提供しない)に使用します。
  • netserver: 独立モードに似ていますが、driver、upsd、upsmon サービスを起動し、ネットワークサービスを提供できる点が異なります。他のマシンの nut-monitor はネットワークを介して Nut Server に接続できます。
  • netclient: クライアントモードのみで、nut-monitor のみを起動し、リモートの Nut サービスに接続します。

ここで私が使用している SANTAK TG-BOX 850 は USB で私の pve に接続されており、pve には NUT ツールがインストールされているため、pve はサーバーとして機能し、他のマシンはサーバーの状態を確認するだけです。

# cat /etc/nut/nut.conf
MODE=netserver

ups.conf#

この設定は nut-driver が物理 UPS にどのように接続するかを定義します。この設定ファイルの構成形式は以下の通りです:

# 注意が必要なのは、群晖またはQNAPがネットワークを介してUPSに接続できるようにするには、
# UPSの名前に特別な要件があることです(群晖はupsと名付ける必要があり、QNAPはテストしていないため、qnapupsと呼ばれる可能性があります);
[ups]
	driver = usbhid-ups
	port = auto
	desc = "TG-BOX 850"

upsd.conf#

この設定ファイルは nut-server のネットワークサービスを制御します。たとえば、リスニングポート、最大接続数、証明書設定などです。私は内部ネットワークで使用しているため、ネットワークリスニングのみを設定し、他のパラメータはデフォルトのままで大丈夫です:

LISTEN 0.0.0.0 3493

upsd.users#

upsd.users 設定ファイルは、ネットワークを介して nut-server に接続するためのユーザー名とパスワードを定義します。この設定のサンプルは以下の通りです:

[monuser]
    password = secret
    upsmon master

群晖と QNAP ユーザーについて:これらの 2 つの NAS が Nut Server に直接接続できることを期待する場合、群晖にはユーザー名が monuser でパスワードが secret のユーザーが存在することを確認する必要があります。QNAP については確認していませんが、オンラインでの情報によれば、ユーザー名が admin でパスワードが 123456 のユーザーが存在する必要があります。

NUT 監視設定#

基本設定に比べて、Nut のコア処理は監視設定を適切に行うことにあります。Nut は監視戦略を大きく 2 つサポートしています:

  • 1、upsmon.confで直接設定し、すべてのイベントをユーザー指定のスクリプトが処理します。タイマーなどの高度な機能はありません。
  • 2、upsmon.confで実行スクリプトをupsschedに設定し、すべてのイベントを最初にupsschedが処理します。upsschedを利用することで、選択的にシャットダウンをトリガーするなどの高度な機能を実現できます。

upsmon.conf#

この設定は主に nut-monitor が UPS をどのように監視するかを設定し、UPS にどのようなイベントが発生した場合にどのような処理を行うかを定義します。以下にコア設定を詳しく説明します。

MONITOR 指令#

MONITOR 指令は監視する UPS の接続アドレスを定義します。 その形式は以下の通りです:

MONITOR <system> <powervalue> <username> <password> ("master"|"slave")
  • <system>: nut-server の接続アドレス、形式は "UPS 名" + "@" + "nut-server アドレス"、例えばmyups@192.168.1.2
  • <powervalue>: UPS の数、大多数の場合、UPS 電源は 1 つだけなので、1 と書けば大丈夫です。
  • <username>/<password>: upsd.usersで定義されたユーザー名とパスワード
  • master/slave: masterはこのシステムが最後にシャットダウンし、従属システムが先にシャットダウンすることを示します。slaveはこのシステムが即座にシャットダウンすることを示します。

以下は私の設定サンプルです:

MONITOR ups@localhost 1 monuser secret master

SHUTDOWNCMD#

SHUTDOWNCMD 指令は UPS の電力が不足している場合や手動でシャットダウンする必要がある場合のシャットダウンコマンドを定義します。完全なパスを記入することをお勧めします。

SHUTDOWNCMD "/usr/sbin/poweroff"

NOTIFYCMD#

NOTIFYCMD指令は非常に重要な指令で、特定のイベント(市電中断、UPS が低電量など)が発生した場合に、nut-monitorが実行するコマンドを設定します。 簡単に言えば、NOTIFYCMDは具体的な実行コマンドを定義し、ここで自分で作成したスクリプトを設定できます。UPS にイベントが発生した場合、このスクリプトが呼び出されます。

NOTIFYCMD指令には大きく 2 つの設定方法があります。1 つは自分のスクリプトを設定する方法で、スクリプトには実行権限が必要で、スクリプト内でNOTIFY環境変数を使用してイベントタイプを取得し、自分で処理します。 この方法は「シンプルで直接的」な意味合いがあり、カスタマイズの程度はスクリプトの書き方に完全に依存します。具体的に使用できる変数は自分でテストしてください。バージョンによって環境変数名が異なる可能性があります。

もう 1 つの方法は、NOTIFYCMDを内蔵のupsschedコマンドを実行するように設定することです。upsschedは Nut が提供する特定の戦略を持つスケジューラです。簡単に言えば、一般的な機能を抽象化したもので、upsschedには独自の設定があり、「市電が 180 秒以内に復旧した場合はシャットダウンしない」といった高度なスケジューリング戦略を実現できます。

ここでは 2 つ目の方法を選択します。

NOTIFYCMD /usr/sbin/upssched

NOTIFYFLAG#

NOTIFYFLAGも重要な設定で、NOTIFYCMDと連携して使用する必要があります。NOTIFYFLAG指令は、UPS の一連のイベントがどのような操作をトリガーすべきかを指定します。この指令の形式は以下の通りです:

NOTIFYFLAG <notify type> <flag>[+<flag>][+<flag>] ...

ここではイベントタイプを示し、選択可能なタイプは以下の通りです:

  • ONLINE: UPS がオンライン、つまり市電が復旧したときにトリガーされます。
  • ONBATT: UPS がバッテリー電源を使用している、つまり市電が中断したときにトリガーされます。
  • LOWBATT: UPS が低電量のときにトリガーされます。
  • FSD: UPS がシャットダウン中(強制シャットダウン)。
  • COMMOK: nut-server との接続が成功したときにトリガーされます。
  • COMMBAD: nut-server との接続が失敗したとき(接続が切れた)にトリガーされます。
  • SHUTDOWN: UPS がシャットダウン指令を発したときにトリガーされます。
  • REPLBATT: UPS がバッテリーの交換を必要とするときにトリガーされます。
  • NOCOMM: UPS との接続ができない(UPS が準備できていない)ときにトリガーされます。

flag フラグには通常 4 種類あり、複数の組み合わせはプラス(+)で接続します:

  • SYSLOG: syslog にのみ印刷します。
  • WALL: ターミナルにメッセージを表示します(/bin/wall)。
  • EXEC: NOTIFYCMDで指定されたコマンドを呼び出し、関連するイベントを渡します。
  • IGNORE: 何もしない、無視します。

もし NOTIFYCMD がカスタムスクリプトを使用している場合、ここでは実際にスクリプトが処理する必要があるイベントを設定してください。NOTIFYCMD が upssched を使用するように設定されている場合、すべてのイベントを EXEC として設定し、具体的なフィルタリングは upssched で処理できます。

例えば、NOTIFYCMDで設定されたスクリプトが市電中断と復旧イベントのみを処理し、同時に syslog に印刷する場合、次のように設定できます:

NOTIFYFLAG ONLINE SYSLOG+EXEC
NOTIFYFLAG ONBATT SYSLOG+EXEC

私がNOTIFYCMDで設定したのはupsschedなので、ここではすべてのイベントを upssched に渡します:

NOTIFYFLAG ONLINE SYSLOG+EXEC
NOTIFYFLAG ONBATT SYSLOG+EXEC
NOTIFYFLAG LOWBATT SYSLOG+EXEC
NOTIFYFLAG FSD SYSLOG+EXEC
NOTIFYFLAG COMMOK SYSLOG+EXEC
NOTIFYFLAG COMMBAD SYSLOG+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+EXEC
NOTIFYFLAG REPLBATT SYSLOG+EXEC
NOTIFYFLAG NOPARENT SYSLOG+EXEC

その他の設定#

上記のコア設定に加えて、他の設定は特に問題がない限り、通常はデフォルトのままで大丈夫です。具体的な設定については公式ドキュメントを参照してください:UPSMON.CONF(5)

upssched.conf#

この設定を使用する前提は、upsmon.conf の NOTIFYCMD が upssched を指しており、NOTIFYFLAG が関連イベントに EXEC を設定していることです。 この設定の主な目的は、特定のイベントの処理方法を制御するために upssched の内蔵の高度な構文を使用することです。upssched.conf の設定は主に 2 つの部分から構成されます:ヘッダーのオプション設定と末尾のルール設定。

4.2.1、オプション設定#

ヘッダーオプション設定には 3 つの設定のみが含まれます:

  • CMDSCRIPT: この設定は最初の行に配置する必要があります(推奨、実際には AT 指令の前であれば大丈夫です)。この指令はイベントの処理スクリプトを定義します。スクリプトは一般的にユーザーが自分で作成します。 upsschedはルールに基づいて指定されたパラメータをこのスクリプトに渡して実行します。
  • PIPEFN: プロセス間通信のためのパイプファイルで、AT 指令の前に配置する必要があります。
  • LOCKFN: 排他ロックファイルで、upsmon が同時に複数のファイルをスケジュールするのを防ぐために、AT 指令の前に配置する必要があります。

CMDSCRIPT 設定のスクリプトのサンプルは以下の通りです:

#!/usr/bin/env bash

set -ex

exec >> /var/log/upssched-cmd.log 2>&1

# システムをシャットダウンする主な関数
function xpoweroff(){
    logger -t upssched-cmd 'XPEnologyをシャットダウンする準備中...'
    logger -t upssched-cmd 'TProxy Gatewayをシャットダウンする準備中...'
    logger -t upssched-cmd 'すべての必要なシステムが正常にシャットダウンしました...'
}

# upsschedがトリガーしたイベントを判断
case $1 in
    onbattwarn)
        logger -t upssched-cmd 'UPSがバッテリー電源に切り替わりました。システムを安全にシャットダウンする準備中...'
        xpoweroff
        ;;
    ups-back-on-line)
        logger -t upssched-cmd '市電が復旧しました...'
        ;;
    lowbatt)
        logger -t upssched-cmd 'UPSの電量が不足しています。システムを直ちにシャットダウンします...'
        xpoweroff
        ;;
    *)
        logger -t upssched-cmd "認識できないコマンド: $1"
        ;;
esac

注意が必要なのは、CMDSCRIPT 設定のスクリプトはデフォルトで nut ユーザーとして実行されるため、nut ユーザーの権限問題を適切に処理する必要があります。

PIPEFN と LOCKFN については、公式に推奨されているのは upssched という名前のディレクトリを別に作成し、その中にファイルを配置することですが、Ubuntu Server 22.04 などの一部のシステムでは、/run/nut/ が tmpfs であり、再起動時にディレクトリが失われて権限の問題が発生する可能性があります。そのため、独立したディレクトリを作成せずに直接設定することをお勧めします:

CMDSCRIPT /opt/scripts/upssched-cmd.sh
PIPEFN /run/nut/upssched.pipe
LOCKFN /run/nut/upssched.lock

4.2.2、ルール設定#

upssched を使用する利点は、内蔵のルールエンジンがあり、簡単な構文を使用して複雑なルールを設定できることです。upssched のルール構文は以下の通りです:

AT notifytype upsname command

ルールは AT で始まり、notifytype は注目するイベントタイプを指定します。upsname は UPS 名を指定し、1 つだけの場合や区別したくない場合は * と書けば大丈夫です。command 部分は実行するアクションを指定し、command には大きく 3 つのタイプがあります:

  • START-TIMER: タイマーを開始します。
  • CANCEL-TIMER: タイマーをキャンセルします。
  • EXECUTE: 即座に実行します。

この部分は一見複雑に見えますが、実際には非常にシンプルです。以下のルールは、市電が切れたとき(UPS がバッテリー電源を使用しているとき)にonbattwarnという名前のタイマーを 180 秒後に実行し、このタイマー内で市電が復旧した場合はスクリプトを実行しないようにキャンセルします。

AT ONBATT * START-TIMER onbattwarn 180
AT ONLINE * CANCEL-TIMER onbattwarn

もちろん、即座に実行する必要があるイベントもあります。例えば、市電中断時に即座に通知を送信します。

# `CMDSCRIPT`で指定されたスクリプトを即座に実行し、`onbattnoti`をスクリプトに渡します。
AT ONBATT * EXECUTE onbattnoti

NUT Server の設定ファイル#

完全な設定は以下の通りです:

nut.conf

MODE=netserver

ups.conf

# 名前は最初に群晖と互換性を持たせるためにUPSとしました。
[ups]
    driver = "usbhid-ups"
    port = "auto"

upsd.conf

LISTEN 0.0.0.0 3493

upsd.users

[monuser]
    password = secret
    upsmon master
[qnapups]
    password = 123456
    upsmon master

upsmon.conf

MONITOR ups@localhost 1 monuser secret master
MINSUPPLIES 1
SHUTDOWNCMD "/usr/sbin/poweroff"
NOTIFYCMD /usr/sbin/upssched
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 30
DEADTIME 15
POWERDOWNFLAG /etc/killpower
NOTIFYFLAG ONLINE SYSLOG+EXEC
NOTIFYFLAG ONBATT SYSLOG+EXEC
NOTIFYFLAG LOWBATT SYSLOG+EXEC
NOTIFYFLAG FSD SYSLOG+EXEC
NOTIFYFLAG COMMOK SYSLOG+EXEC
NOTIFYFLAG COMMBAD SYSLOG+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+EXEC
NOTIFYFLAG REPLBATT SYSLOG+EXEC
NOTIFYFLAG NOPARENT SYSLOG+EXEC
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5

upssched.conf

CMDSCRIPT /opt/scripts/upssched-cmd.sh
PIPEFN /run/nut/upssched.pipe
LOCKFN /run/nut/upssched.lock
AT ONBATT * START-TIMER onbattwarn 180
AT ONLINE * CANCEL-TIMER onbattwarn

upssched-cmd.sh

#!/usr/bin/env bash

set -ex

exec >> /var/log/upssched-cmd.log 2>&1

echo "実行ID: $(id)"

SSH_CMD='ssh -o StrictHostKeyChecking=no'

case $1 in
    onbattwarn)
        logger -t upssched-cmd 'UPSがバッテリー電源に切り替わりました。システムを安全にシャットダウンする準備中...'
        ;;
    ups-back-on-line)
        logger -t upssched-cmd '市電が復旧しました...'
        ;;
    lowbatt)
        logger -t upssched-cmd 'UPSの電量が不足しています。システムを直ちにシャットダウンします...'
        ;;
    *)
        logger -t upssched-cmd "認識できないコマンド: $1"
        ;;
esac

NUT Server の再起動#

systemctl restart nut-server.service
systemctl restart nut-driver.service
systemctl restart nut-monitor.service

NUT Client の設定#

nut クライアントの設定#

/etc/nut/nut.conf ファイルを編集し、MODE を netclient モードに設定します。

MODE=netclient

upsmon の設定#

/etc/nut/upsmon.conf ファイルを編集し、以下の設定項目を追加します:

MONITOR UPSの名前@UPSのIPアドレス 1 ユーザー名 パスワード slave
MINSUPPLIES 1
SHUTDOWNCMD "/usr/sbin/poweroff"
NOTIFYCMD /usr/sbin/upssched
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 30
DEADTIME 15
POWERDOWNFLAG /etc/killpower
NOTIFYFLAG ONLINE SYSLOG+EXEC
NOTIFYFLAG ONBATT SYSLOG+EXEC
NOTIFYFLAG LOWBATT SYSLOG+EXEC
NOTIFYFLAG FSD SYSLOG+EXEC
NOTIFYFLAG COMMOK SYSLOG+EXEC
NOTIFYFLAG COMMBAD SYSLOG+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+EXEC
NOTIFYFLAG REPLBATT SYSLOG+EXEC
NOTIFYFLAG NOPARENT SYSLOG+EXEC
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5
RUN_AS_USER root

ここで注意が必要なのは RUN_AS_USER で、upsmon.conf ファイル内では通常 upsmon が実行されるユーザーが定義されます。特定のシステムでは、upsmon がデフォルトで一般ユーザーとして実行されるため、シャットダウンコマンドを実行できない可能性があるため、root が必要です。

upssched の設定#

wall コマンドは、システム内で全てのログインユーザーにメッセージをブロードキャストするために使用されます。upsmon のデフォルト設定では、wall コマンドを使用して全てのユーザーに通知メッセージを送信します。

ここで wall ツールをインストールする必要があります。Gentoo のインストールプロセスは以下の通りです:

echo "sys-apps/util-linux tty-helpers" >> /etc/portage/package.use
sudo emerge -v sys-apps/util-linux
# インストールされているか確認
which wall

upssched ツールは、特定の条件下でスクリプトを実行することを許可します。/etc/nut/upssched.conf ファイルを編集し、以下の内容を追加します:

CMDSCRIPT /etc/nut/upssched-cmd.sh
PIPEFN /run/nut/upssched.pipe
LOCKFN /run/nut/upssched.lock
AT ONBATT * START-TIMER onbattwarn 600
AT ONLINE * CANCEL-TIMER onbattwarn
AT ONLINE * EXECUTE ups-back-on-line
AT LOWBATT * EXECUTE lowbatt

これにより、UPS が供電を開始してから 600 秒後に onbattwarn イベントがスクリプトに送信され、その後スクリプトで定義されたコマンドが実行されます。

/etc/nut/upssched-cmd.sh の内容は以下の通りです:

#!/usr/bin/env bash

set -ex

exec >> /var/log/upssched-cmd.log 2>&1

echo "実行ID: $(id)"

function xpoweroff(){
        /sbin/shutdown -h +0 "UPSが1分間バッテリーで動作しています。シャットダウンします。"
}

case $1 in
    onbattwarn)
        logger -t upssched-cmd 'UPSがバッテリー電源に切り替わりました。システムを安全にシャットダウンする準備中...'
        xpoweroff
        ;;
    ups-back-on-line)
        logger -t upssched-cmd '市電が復旧しました...'
        ;;
    lowbatt)
        logger -t upssched-cmd 'UPSの電量が不足しています。システムを直ちにシャットダウンします...'
        xpoweroff
        ;;
    *)
        logger -t upssched-cmd "認識できないコマンド: $1"
        ;;
esac

実行権限を付与します。

sudo chmod +x /etc/nut/upssched-cmd.sh

NUT Client の再起動#

systemctl enable nut-monitor.service
systemctl restart nut-monitor.service
systemctl status nut-monitor.service

設定の検証#

以下のコマンドを使用して UPS の状態をテストできます:

upsc <UPS>@IP

参考#

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。