作っておぼえるHAシステム5(2022年版)

今回はサービスが停止した時のPacemakerの動作について調べてみましょう。

リソース定義の詳細

Pacemakerはリソースエージェントと呼ばれるスクリプトを使ってリソースの制御を行います。今回設定したMariaDBのリソースを素材に設定を詳しく見てみましょう。リソースの定義は次のようになっています。

primitive res_mysql mysql ¥
	params binary="/usr/bin/mysqld_safe" ¥
	op start interval=0 timeout=120 ¥
	op stop interval=0 timeout=120 ¥
	op monitor interval=20 timeout=30

primitiveの次の”res_mysql”はリソース名になります。命名には英数文字と一部の記号が使えます。
その次のmysqlはリソースエージェント名です。Pacemakerのリソースエージェントは/usr/lib/ocfのディレクトリにあります。

[root@node1 ‾]# cd /usr/lib/ocf/resource.d/heartbeat/
[root@node1 heartbeat]# ls -l mysql 
-rwxr-xr-x 1 root root 35844  8月 18 21:10 mysql

このディレクトリにはMariaDB(mysql)以外にも多くのリソースエージェントがあり、apacheやnginxなど見慣れたプログラムのリソースエージェントが並んでいます。ほとんどのファイルはシェルスクリプトなので、興味のある方はviエディタなどで開いて見て下さい。

リソースの定義の説明に戻ります。
「op start interval=0 timeout=120」、「op stop interval=0 timeout=120」はMariaDBを起動、停止する時に120秒以上リソースエージェントからの応答がない場合にPacemakerがエラーと判断するパラメータになります。

「op monitor interval=20 timeout=30」は監視の設定になります。20秒間隔(interval)でMariaDBの死活監視を行って、30秒以上リソースエージェントからの応答がない場合(timeout)にPacemakerはエラーと判断します。

タイムアウト前に起動や停止に失敗するとその時点でエラーとPacemakerは判断し、監視の場合も失敗するとタイムアウトを待たずにエラーと判断します。

プロセスが停止した時の動作

MariaDBのプログラムに問題が発生して停止した想定で、mysqldプロセスを停止してみましょう。
まず、psコマンドで動作を確認します。

[root@node1 heartbeat]# ps axf
......
......
29808 ?        S      0:00 /bin/sh /usr/bin/mysqld_safe --defaults-file=/etc/my.cnf --pid-file=/
30011 ?        Sl     0:00  ¥_ /usr/libexec/mysqld --defaults-file=/etc/my.cnf --basedir=/usr --
[root@node1 heartbeat]# killall mysqld

次にkillallコマンドでプロセスID 30011のmysqldが停止します。

[root@node1 heartbeat]# killall mysqld

psコマンドでプロセスが停止したことを確認します。
リソースエージェントの監視は20秒間隔で実行されており、プロセスの有無をチェックしますが、停止しているため監視がエラーになります。
エラーの検出により、Pacemakerの状態が次のようになります。

[root@node2 ‾]# crm_mon -frAD
Online: [ node1 node2 ]

Full list of resources:

 Resource Group: rg_mariadb
     res_ipadr  (ocf::heartbeat:IPaddr2):	Started node1
     res_fsmnt  (ocf::heartbeat:Filesystem):    Started node1
     res_mysql  (ocf::heartbeat:mysql): FAILED node1
 Master/Slave Set: ms_drbd_r0 [res_drbd_r0]
     Masters: [ node1 ]
     Slaves: [ node2 ]

Node Attributes:
* Node node1:
    + master-res_drbd_r0                : 10000
* Node node2:
    + master-res_drbd_r0                : 10000

Migration Summary:
* Node node1:
   res_mysql: migration-threshold=1000000 fail-count=1 last-failure='Tue Dec 22 16:04:31 2020'
* Node node2:

Failed Resource Actions:
* res_mysql_monitor_20000 on node1 'not running' (7): call=59, status=complete, exitrea
son='',
    last-rc-change='Tue Dec 22 16:04:31 2020', queued=0ms, exec=0ms

「res_mysql (ocf::heartbeat:mysql): FAILED node1」という表示と、「Migration Summary:」と「Failed Resource Actions:」の表示に注目して下さい。

* Node node1:
   res_mysql: migration-threshold=1000000 fail-count=1 last-failure='Tue Dec 22 16:04:31 2020'

Pacemakerはリソースのエラーを検知すると内部に持っている「fail-count」という変数の値に1を加えます。次に停止したリソースの起動を試みます。起動に成功した場合はサービスが再開されます。これがPacemakerのプロセスの自動復旧機能です。

Pacemakerでは「migration-threshold」という値が設定でき、「fail-count」の値がこの「migration-threshold」の値を超えると、エラーが発生したノードでのリソースの起動を諦めて、別のノードでの実行を試みます。系切り替えの重要なパラメータですが、ネットに公開されているPacemakerの設定で「migration-threshold=1」とする例を多く見かけます。この場合1回のエラーでフェールオーバーとなり、自動復旧が働かなくなりため推奨されません。最新のLINBITの設定例でも「migration-threshold=3」となっています。3にした場合は3回エラーが発生するまで、リソースの起動を繰り返します。

migration-thresholdの設定と動作確認

「migration-threshold=3」にした場合の動きを確認してみます。crmコマンドで値を設定します。

[root@node1 heartbeat]# crm configure rsc_defaults migration-threshold="3"
[root@node1 heartbeat]# crm configure show
node 1: node1
node 2: node2
primitive res_drbd_r0 ocf:linbit:drbd ¥
....
....
rsc_defaults rsc-options: ¥
	resource-stickiness=200 ¥
	migration-threshold=3

 

crmコマンド(crm configure show)で設定を確認します。「migration-threshold」が3になりました。

設定が終わったら、MariaDBのプロセスを3回停止します。停止後にPacemakerが復旧するのを待ってから、次の停止を実行して下さい。

[root@node1 heartbeat]# killall mysqld

2回までは復旧しますが、3回目のプロセス停止によりPacemakerはnode1からnode2へフェールオーバーします。

Online: [ node1 node2 ]

Full list of resources:

 Resource Group: rg_mariadb
     res_ipadr  (ocf::heartbeat:IPaddr2):	Started node2
     res_fsmnt  (ocf::heartbeat:Filesystem):    Started node2
     res_mysql  (ocf::heartbeat:mysql): Started node2
 Master/Slave Set: ms_drbd_r0 [res_drbd_r0]
     Masters: [ node2 ]
     Slaves: [ node1 ]

Node Attributes:
* Node node1:
    + master-res_drbd_r0                : 10000
* Node node2:
    + master-res_drbd_r0                : 10000

Migration Summary:
* Node node1:
   res_mysql: migration-threshold=3 fail-count=3 last-failure='Tue Dec 22 16:47:46 2020'
* Node node2:

Failed Resource Actions:
* res_mysql_monitor_20000 on node1 'not running' (7): call=98, status=complete, exitrea
son='',
    last-rc-change='Tue Dec 22 16:47:46 2020', queued=0ms, exec=0ms

Pacemakerでは「migration-threshold」と「fail-count」でリソースの再起動と、その回数による系切り替えが出来ることがわかりました。

ところで「migration-threshold」の初期値は1000000になっています。これは系切り替えに1000000回の再起動が必要ということでしょうか?

リソースの実行時に致命的な障害が発生すると、「fail-count」の値はただちに1000000になります。「fail-count」が「migration-threshold」と同じ値になるためnode2に系切り替えされます。

以下の出力は、テストとしてmysqldの実行権を一時的に無効にして、リソースが再起動しないようにした場合の結果です。

Migration Summary:
* Node node1:
   res_mysql: migration-threshold=3 fail-count=1000000 last-failure='Tue Dec 22 16:55:47 2020'
* Node node2:

プロセスの停止後、MariaDBは起動されましたが、実行権が無いためエラーとなり、ただちに「fail-count=1000000 」となります。この結果、node2への系切り替えが発生しています。

「fail-count」の値を削除するには、crmコマンドを次のような引数で実行します。

[root@node1 heartbeat]# crm resource failcount res_mysql delete node1

コマンドの実行により、「fail-count」の値はゼロになります。