LoginSignup
3
1

More than 5 years have passed since last update.

apcupsdで冗長構成を作る話

Last updated at Posted at 2017-03-30

背景

サーバー屋さんで最も数がでていると思われる2ソケットサーバーは大抵PSUが2個、ストレージサーバー等では3個の冗長電源構成になっていて、余程ハイスペックCPUやGPUを搭載してたりしない限り片肺での稼働も可能になっている。

サーバー搭載のPSU(電源ユニット)の故障までの冗長性を確保するのであれば、その上流のPDUやUPSは1系統でいいかもしれないが、できればブレーカから分けてUPSの故障などにも対応できるようにできないか?と考えるのは自然な要求だと思う。世の中には発電所や電力会社から分けたいなんて需要もあるようだけど、ここでは考えない。

Diagram1.png

フリーのapcupsdを用いて、それを実現してみる。

用意

OS 環境
CentOS7.3.1611
UPS
Smart-UPS 3000 RM XL
apcupsd
apcupsd-3.14.12 (epel 由来)
接続
USBx2 (USB/シリアル併用も可能だが、最近のサーバーはシリアルを持ってないことが増えた)

実装

apcupsdは単独では複数のUPSを管理できないため、接続するUPSの数だけ設定を分けて作成し、それぞれapcupsdを立ちあげ、その上で停電時の処理スクリプト内でand条件やor条件を付ける必要がある。

複数USBへの対応

USBケーブルを繋ぐとudevがhidとして認識してデバイスを作り、apcupsdは勝手にそれを認識するため、通常の1台のみ接続の場合apcupsd.confではDEVICE欄を空欄にすることになっている。しかし、厳密に2台を区別したければ、また他のデバイスが同様な認識をする場合にも、別名を割り当てる必要がある。

ケーブルを刺した状態でlsusbコマンドを叩き、バスIDとデバイスナンバーを取得する。

[root@server ~]# lsusb
Bus 002 Device 002: ID 8087:8002 Intel Corp. 
......
Bus 003 Device 046: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Bus 003 Device 047: ID 051d:0002 American Power Conversion Uninterruptible Power Supply

これは接続されるたびに異なる番号になるので、接続した全てのUPSシリアル番号を取得してudevルールを作成する。

[root@server ~]# lsusb -v -s 003:046

Bus 003 Device 046: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x051d American Power Conversion   ←これと
  idProduct          0x0002 Uninterruptible Power Supply  ←これと
  bcdDevice            0.06
  iManufacturer           3 American Power Conversion
  iProduct                1 Smart-UPS 3000 RM XL FW:691.01.M USB FW:7.4
  iSerial                 2 AS170XXXXXXX   ←これを使う
  bNumConfigurations      1

取得した情報をもとに、/etc/udev/rules.d/30-apcups.confを作成し、以下のように記述する。

KERNEL=="hiddev*", ATTRS{idVendor}=="051d", ATTRS{idProduct}=="0002", ,ATTRS{serial}=="AS170XXXXXXX", SYMLINK+="apcups2"
KERNEL=="hiddev*", ATTRS{idVendor}=="051d", ATTRS{idProduct}=="0002", ,ATTRS{serial}=="AS170YYYYYYY", SYMLINK+="apcups1"

このファイルを作成後、ケーブルを抜き差しすると以下のようにリンクが作成される。

[root@server ~] ls -l /dev/apcups*
lrwxrwxrwx 1 root root 11  3月 17 19:26 /dev/apcups1 -> usb/hiddev1
lrwxrwxrwx 1 root root 11  3月 17 19:26 /dev/apcups2 -> usb/hiddev0

監視設定

/etc/apcupsd/apcupsd.confapcupsd-1.conf, apcupsd-2.conf としてコピーして、DEVICEには作成した/dev/apcups1, /dev/apcups2をそれぞれ指定する。UPSNAMEEVENTFILEは分けておくこと。同様にSTATFILE, NISPORTも必要であれば変更しておく。

/usr/lib/systemd/system/apcupsd.serviceを設定と同様 -1, -2 の2つにわけ、それぞれの設定ファイルを読み込むようExecStartを書き換える。

[Service]
ExecStartPre=-/bin/rm -f /etc/apcupsd/powerfail
ExecStart=/sbin/apcupsd -b -f /etc/apcupsd/apcupsd-1.conf

設定を読み込んで enable & start。

[root@server ~] systemctl daemon-reload
[root@server ~] systemctl enable apcupsd-1; systemctl enable apcupsd-2
[root@server ~] systemctl start apcupsd-1; systemctl start apcupsd-2

ToDo

今はどっちが落ちてもシャットダウンする「OR条件」で動作することになる。これを、シャットダウンスクリプト内で互いの生死を確認して、一方が生きていればシャットダウンしない「AND条件」でシャットダウンするようにする。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1