7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CentOS 7 の Pacemaker/Corosync で snmptrap やメールで通知

Posted at

CentOS 7 のリポジトリからサクッとインストールできる下記で試しています。

  • corosync-2.3.4-7.el7_2.1
  • pacemaker-1.1.13-10.el7_2.2
  • resource-agents-3.9.5-54.el7_2.9

Pacemaker/Corosync の構成

確認用に次のような構成で Pacemaker/Corosync の環境を構築しています。

corosync

  • pm01
    • 192.168.33.11/24 (enp0s8 / ring0)
    • 192.168.99.11/24 (enp0s9 / ring1)
  • pm02
    • 192.168.33.12/24 (enp0s8 / ring0)
    • 192.168.99.12/24 (enp0s9 / ring1)

pacemaker

sudo pcs property set stonith-enabled="false"
sudo pcs property set no-quorum-policy="ignore"

sudo pcs resource defaults migration-threshold="1"

sudo pcs resource create dummy1 ocf:pacemaker:Dummy state=/tmp/pm-dummy1
sudo pcs resource create dummy2 ocf:pacemaker:Dummy state=/tmp/pm-dummy2

sudo pcs resource group add dummys dummy1 dummy2

/etc/hosts

127.0.0.1       localhost localhost.localdomain localhost4 localhost4.localdomain4
192.168.33.11   pm01
192.168.33.12   pm02
192.168.99.11   pm01-back
192.168.99.12   pm02-back

snmptrapd

snmptrap の確認のために ローカルに snmptrapd をセットアップします。

必要なもろもろをインストールします。

sudo yum -y install net-snmp net-snmp-utils net-snmp-perl mailx

snmptrapd ですべてのトラップをメールで root に転送するように設定します。

sudo tee /etc/snmp/snmptrapd.conf <<'EOS'
disableAuthorization yes
traphandle default /usr/bin/traptoemail root
EOS

root へのメールは自分のメールアドレスに転送させます。

echo ore@example.com | sudo tee /root/.forward

pacemaker や corosync の mib を読み込むために /etc/snmp/snmp.conf を作成します。

sudo tee /etc/snmp/snmp.conf <<'EOS'
mibs ALL
EOS

snmptrapd を開始します。

sudo systemctl start snmptrapd
sudo systemctl enable snmptrapd

試しに適当なトラップを送信します。トラップがメールで送信されれば正しくセットアップされています。

sudo snmptrap -v 1 -c hoge localhost corosync localhost 6 1 ''
sudo snmptrap -v 1 -c hoge localhost pacemaker localhost 6 1 ''

corosync-notifyd

corosync-notifyd は corosync の重要なイベントを dbus や snmptrap で通知するサービスです。ノードの故障や復帰を通知することができますが・・・リソース障害は corosync の管轄じゃないので通知できません。

/etc/sysconfig/corosync-notifyd でコマンドラインオプションを指定できるので 127.0.0.1 にトラップを送信するように設定します。

sudo tee /etc/sysconfig/corosync-notifyd <<'EOS'
OPTIONS="-s -l -m 127.0.0.1"
EOS

corosync-notifyd を開始します。

sudo systemctl start corosync-notifyd

開始した時点で次のようなトラップが送信されました。

                SNMPv2-MIB::snmpTrapOID.0  COROSYNC-MIB::corosyncNoticesQuorumStatus
    COROSYNC-MIB::corosyncObjectsNodeName  "pm01"
      COROSYNC-MIB::corosyncObjectsNodeID  1
COROSYNC-MIB::corosyncObjectsQuorumStatus  "quorate"

pacemaker や corosync を停止・開始したときの通知

片方の pacemaker を停止してみる。

sudo systemctl stop pacemaker

このときはトラップは送信されません。

corosync を停止してみる。

sudo systemctl stop corosync

次のようなトラップが片割れ(pm01 で corosync を停止したので pm02 から)から送信されました。

# from pm02
               SNMPv2-MIB::snmpTrapOID.0  COROSYNC-MIB::corosyncNoticesNodeStatus
   COROSYNC-MIB::corosyncObjectsNodeName  "pm01-back"
     COROSYNC-MIB::corosyncObjectsNodeID  1
COROSYNC-MIB::corosyncObjectsNodeAddress  "192.168.99.11"
 COROSYNC-MIB::corosyncObjectsNodeStatus  "left"

pacemaker を開始してみる(corosync も一緒に開始されます)。

sudo systemctl start pacemaker

次のようなトラップが送信されました。

# from pm02
               SNMPv2-MIB::snmpTrapOID.0  COROSYNC-MIB::corosyncNoticesNodeStatus
   COROSYNC-MIB::corosyncObjectsNodeName  "pm01-back"
     COROSYNC-MIB::corosyncObjectsNodeID  1
COROSYNC-MIB::corosyncObjectsNodeAddress  "192.168.99.11"
 COROSYNC-MIB::corosyncObjectsNodeStatus  "joined"

リソース障害

リソース障害を発生させてみる。

sudo rm /tmp/pm-dummy1

が、リソース障害ではなにも通知されませんでした。

通信障害

NIC の 1 つを iptables で塞いでみます。

sudo yum -y install iptables-services
sudo systemctl start iptables
sudo iptables -F
sudo iptables -A INPUT -i enp0s9 -j DROP

次のようなトラップが送信されました。両方のノードから通知が来ると思っていたのですが、、、片方からしか来ませんでした(corosync-cfgtool で見た感じ、両方のノードで faulty になってます)。

# from pm02
             SNMPv2-MIB::snmpTrapOID.0  COROSYNC-MIB::corosyncNoticesRRPStatus
 COROSYNC-MIB::corosyncObjectsNodeName  "pm02"
   COROSYNC-MIB::corosyncObjectsNodeID  2
  COROSYNC-MIB::corosyncObjectsIfaceNo  1
COROSYNC-MIB::corosyncObjectsRRPStatus  "faulty"

塞いでた穴を開きます。

sudo iptables -F

次のようなトラップが送信されました。これも片方のノードからしか送信されませんでした。

# from pm02
             SNMPv2-MIB::snmpTrapOID.0  COROSYNC-MIB::corosyncNoticesRRPStatus
 COROSYNC-MIB::corosyncObjectsNodeName  "pm02"
   COROSYNC-MIB::corosyncObjectsNodeID  2
  COROSYNC-MIB::corosyncObjectsIfaceNo  1
COROSYNC-MIB::corosyncObjectsRRPStatus  "operational"

ノード障害

サーバを強制終了してみます。Vagrant 環境なので次のように強制終了します。

vagrant halt --force pm01

次のようなトラップが送信されました。

# from pm02
               SNMPv2-MIB::snmpTrapOID.0  COROSYNC-MIB::corosyncNoticesNodeStatus
   COROSYNC-MIB::corosyncObjectsNodeName  "pm01-back"
     COROSYNC-MIB::corosyncObjectsNodeID  1
COROSYNC-MIB::corosyncObjectsNodeAddress  "192.168.99.11"
 COROSYNC-MIB::corosyncObjectsNodeStatus  "left"

サーバを起動します。

vagrant up pm01
vagrant ssh pm01
sudo systemctl start corosync-notifyd 
sudo systemctl start pacemaker

次のようなトラップが送信されました。

# from pm02
               SNMPv2-MIB::snmpTrapOID.0  COROSYNC-MIB::corosyncNoticesNodeStatus
   COROSYNC-MIB::corosyncObjectsNodeName  "pm01-back"
     COROSYNC-MIB::corosyncObjectsNodeID  1
COROSYNC-MIB::corosyncObjectsNodeAddress  "192.168.99.11"
 COROSYNC-MIB::corosyncObjectsNodeStatus  "joined"
# from pm01
                SNMPv2-MIB::snmpTrapOID.0  COROSYNC-MIB::corosyncNoticesQuorumStatus
    COROSYNC-MIB::corosyncObjectsNodeName  "pm01"
      COROSYNC-MIB::corosyncObjectsNodeID  1
COROSYNC-MIB::corosyncObjectsQuorumStatus  "quorate"

# from pm01
             SNMPv2-MIB::snmpTrapOID.0  COROSYNC-MIB::corosyncNoticesRRPStatus
 COROSYNC-MIB::corosyncObjectsNodeName  "pm01"
   COROSYNC-MIB::corosyncObjectsNodeID  1
  COROSYNC-MIB::corosyncObjectsIfaceNo  0
COROSYNC-MIB::corosyncObjectsRRPStatus  "operational"
# from pm01
             SNMPv2-MIB::snmpTrapOID.0  COROSYNC-MIB::corosyncNoticesRRPStatus
 COROSYNC-MIB::corosyncObjectsNodeName  "pm01"
   COROSYNC-MIB::corosyncObjectsNodeID  1
  COROSYNC-MIB::corosyncObjectsIfaceNo  1
COROSYNC-MIB::corosyncObjectsRRPStatus  "operational"

corosync-notifyd を起動すると corosync も起動する

ちなみに corosync-notifyd の systemd のユニットファイルに Wants=corosync.service が書かれているので、corosync-notifyd を開始すると corosync も一緒に開始します。

cat /usr/lib/systemd/system/corosync-notifyd.service
# [Unit]
# Description=Corosync Dbus and snmp notifier
# Wants=corosync.service
# After=corosync.service
# :

サーバのブート時に corosync を起動させたくないのであれば注意が必要です。

crm_mon で snmp-traps とかメール通知

たしか crm_mon--snmp-traps とか --mail-to とかのオプションがあって、リソース障害を snmptrap やメールで通知できるはず、、、なのだけど man crm_mon にも crm_mon --help にもその情報がない。。。

だいぶ前に LinuxHA Japan のリポジトリからインストールした pacemaker-1.0.13-2.el6.x86_64crm_mon 1.0.13 for OpenAIS and Heartbeat (Build: a83fae5) だと --snmp-traps とか --mail-to とかもあるんだけど。。。

とりあえずダメ元で試してみる。

pacemaker のインストール時に crm_mon のための systemd のユニットファイルがインストールされています。

cat /usr/lib/systemd/system/crm_mon.service

内容は次の通り。

:
[Service]
Type=forking
EnvironmentFile=-/etc/sysconfig/crm_mon
ExecStart=/usr/sbin/crm_mon $OPTIONS
Restart=always
:

Type=forking とあるので crm_mon はデーモン化するのが良さそう。EnvironmentFile でファイル名の頭に - がついているのは man systemd.exec によるとファイルが存在しないときには無視するという意味とのこと。

次のように /etc/sysconfig/crm_mon でコマンドライン引数を指定します。

sudo tee /etc/sysconfig/crm_mon <<'EOS'
OPTIONS="--daemonize --snmp-traps=127.0.0.1"
EOS

crm_mon.service を開始します。

sudo systemctl start crm_mon.service
sudo systemctl status crm_mon.service

意図的にリソース障害を発生させてみる・・・が、トラップが送信される気配がない。

ためしに下記でも試してみるも・・・が、メールが送信される気配はない。

sudo tee /etc/sysconfig/crm_mon <<'EOS'
OPTIONS="--daemonize --mail-to=root"
EOS

どうもこれらの機能は CentOS 7 のリポジトリの pacemaker では無効になっているっぽい。

Depending on your system settings and compilation settings, SNMP or email alerts might be unavailable. Check the output of crm_mon --help to see whether these options are available to you. In any case, executing an external agent will always be available, and you can use this agent to send emails, SNMP traps or whatever action you develop.

crm_mon の external-agent でコマンド呼び出し

man crm_mon--external-agent はあったので、こっちを試してみる。

sudo tee /etc/sysconfig/crm_mon <<'EOS'
OPTIONS="--daemonize --external-agent=/vagrant/agent.sh --external-recipient=ore-recipient"
EOS

/vagrant/agent.sh は次のような内容です。

# !/bin/bash
env | sort | /bin/logger -t ore-agent -i

crm_mon.service を再起動します。

sudo systemctl restart crm_mon.service
sudo systemctl status crm_mon.service

意図的にリソース障害を発生させると /var/log/messages に次のようなログが記録されました。

Apr 26 07:25:30 pm01 ore-agent[4553]: CRM_notify_desc=OK
Apr 26 07:25:30 pm01 ore-agent[4553]: CRM_notify_node=pm02
Apr 26 07:25:30 pm01 ore-agent[4553]: CRM_notify_rc=0
Apr 26 07:25:30 pm01 ore-agent[4553]: CRM_notify_recipient=ore-recipient
Apr 26 07:25:30 pm01 ore-agent[4553]: CRM_notify_rsc=dummy2
Apr 26 07:25:30 pm01 ore-agent[4553]: CRM_notify_status=0
Apr 26 07:25:30 pm01 ore-agent[4553]: CRM_notify_target_rc=0
Apr 26 07:25:30 pm01 ore-agent[4553]: CRM_notify_task=monitor
 :

つまり、指定したコマンドがこれらの環境変数を付けて実行されるということなので、次のようにメール通知を設定してみます。

# !/bin/bash
env | grep ^CRM_notify | sort |
  mail -s "[$CRM_notify_node] $CRM_notify_rsc $CRM_notify_task $CRM_notify_desc" root

意図的にリソース障害を発生させると、メールがだだだっと送信されました。

crm_mon を pacemaker のリソースにする

下記の例のように crm_mon を systemd ではなく pacemaker のリソースとして管理しても良いかもしれません。

systemd の crm_mon.service を停止します。

sudo systemctl stop crm_mon.service
sudo systemctl disable crm_mon.service
sudo systemctl status crm_mon.service

リソースエージェント ocf:pacemaker:ClusterMon の説明を見てみます。

sudo pcs resource describe ocf:pacemaker:ClusterMon

下記のとおりです。

ocf:pacemaker:ClusterMon - Runs crm_mon in the background, recording the cluster status to an HTML file

This is a ClusterMon Resource Agent.
It outputs current cluster status to the html.

Resource options:
  user: The user we want to run crm_mon as
  update: How frequently should we update the cluster status
  extra_options: Additional options to pass to crm_mon. Eg. -n -r
  pidfile: PID file location to ensure only one instance is running
  htmlfile: Location to write HTML output to.

次のように Clone リソースとして設定します。

sudo pcs resource create crm_mon ocf:pacemaker:ClusterMon \
  user="root" extra_options="--external-agent=/vagrant/agent.sh" \
  meta migration-threshold="INFINITY" --clone

crm_mon の external-agent で通知を間引く

すべてを通知すると結構な量のメールが飛んで来るので、下記のように間引きました。

# !/bin/bash

if [ "$CRM_notify_node" != "$(uname -n)" ]; then
  # 自ノード以外は除外
  exit 0
fi

if [ "$CRM_notify_task" == "monitor" ]; then
  case "$CRM_notify_desc" in
    OK|ok)
      # monitor の OK は除外
      exit 0
      ;;
  esac
fi

env | grep ^CRM_notify | sort |
  mail -s "[$CRM_notify_node] $CRM_notify_rsc $CRM_notify_task $CRM_notify_desc" root

このスクリプトを --external-agent に設定すれば概ね以下のようなときだけ通知されます。

  • リソースの開始/停止(失敗でも成功でも)
  • リソースの監視で異常を検出

自ノードのリソース障害しか通知しないため、ノード障害が発生したときにはそのノードで稼働していたリソースの障害は通知されません(通知する crm_mon が死んでいるので)。

Active/Standby のアクティブ側のノード障害なら、スタンバイ側のリソースが開始するので、その通知を持ってノード障害を推測することができますが、Clone リソースしか無い、とか、Active/Standby のスタンバイ側の障害、とかだと、この方法だけではノード障害を検出することができません。

ので、corosync-notifyd と併用するのが良いかもしれません。

あるいは crm_mon を Clone リソースとして設定しているなら crm_mon リソースだけはノードに依らず通知してみるとか。

# !/bin/bash

if [ "$CRM_notify_node" != "$(uname -n)" ]; then
  if [ "$CRM_notify_rsc" != "crm_mon" ]; then
    exit 0
  fi
fi

if [ "$CRM_notify_task" == "monitor" ]; then
  case "$CRM_notify_desc" in
    OK|ok)
      exit 0
      ;;
  esac
fi

env | grep ^CRM_notify | sort |
  mail -s "[$CRM_notify_node] $CRM_notify_rsc $CRM_notify_task $CRM_notify_desc" root

これなら、例えば pm01 のノード障害時に、pm02 から、pm01 の crm_mon が停止した旨の通知が送られてきます。ただし、pm01 が開始したときには pm01 と pm02 の両方から pm01 の crm_mon が開始した旨の通知が送られてきますが。

7
7
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
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?