Pacemakerでシングルサーバ運用

HA環境を構築してサーバーの可用性を確保するまでもない場合や、そもそもサーバ環境が1台しか確保できない場合、サービスの監視と起動に特化したソフトウェアを使います。

ZabbixやNagiosなどの監視システムを使う方法や、監視スクリプトを自作する方法が良くある方法です。

シングルサーバでのサービス監視の有料の製品としてもNECのシングルサーバセーフや、サイオスのシングルサーバプロテクションなどがあります。

ところでPacemakerでも2ノードの構成のシステムを運用していて、片側のノードが故障して停止した場合は、残ったノードで稼働中のサービス(リソース)は死活監視され、万一サービスが停止してもPacemakerがサービスを起動します。障害時に1ノードで運用が可能なら、最初から1ノードのシステムを構築すれば、Pacemakerでもシングルサーバの監視システムを構築し運用できます。

Pacemakerはマルチノード構成での利用を前提に作られているものの、シングルノードで運用することに技術的な問題ありません。DRBDを開発し、Pacemakerのプロジェクトにも参加しているLINBIT社でもシングルサーバのPacemakerシステムをサポートした実績もあるそうです。なかなか実用性が高いなぁと思い、このBlogで設定方法を発表しようと、LINBIT社の技術担当者に相談したところ、Pacemakerを使うより簡単に、OSの基本機能だけでサービスの監視と再起動ができると教えてもらいました。

例ではCentOS7のApache2を例に説明します。

Apache2のSystemdの設定ファイルは/etc/systemd/system/multi-user.target.wantsや/usr/lib/systemd/system/httpd.serviceにあります。

設定の中に[Service]という項目があるのでここにRestart=alwaysを追加します。

実験環境での例を示します。

[root@ns multi-user.target.wants]# cat httpd.service 
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true

Restart=always  # <--- 追加する
RestartSec=1

[Install]
WantedBy=multi-user.target

この設定を追加してApacheサーバを起動すると、Apacheサービスが停止してもサービスが再起動します。

[root@ns multi-user.target.wants]# vi httpd.service 
[root@ns multi-user.target.wants]# systemctl daemon-reload
[root@ns multi-user.target.wants]# systemctl restart httpd.service

試しに Apacheサービスを強制的に停止ししてみます。

[root@ns ~]# ps axf | grep httpd
32256 pts/1    S+     0:00          \_ grep --color=auto httpd
32249 ?        Ss     0:00 /usr/sbin/httpd -DFOREGROUND
32250 ?        S      0:00  \_ /usr/sbin/httpd -DFOREGROUND
32251 ?        S      0:00  \_ /usr/sbin/httpd -DFOREGROUND
32252 ?        S      0:00  \_ /usr/sbin/httpd -DFOREGROUND
32253 ?        S      0:00  \_ /usr/sbin/httpd -DFOREGROUND
32254 ?        S      0:00  \_ /usr/sbin/httpd -DFOREGROUND
[root@ns ~]# killall /usr/sbin/httpd 
[root@ns ~]# ps axf | grep httpd
32271 pts/1    S+     0:00          \_ grep --color=auto httpd
32264 ?        Ss     0:00 /usr/sbin/httpd -DFOREGROUND
32265 ?        S      0:00  \_ /usr/sbin/httpd -DFOREGROUND
32266 ?        S      0:00  \_ /usr/sbin/httpd -DFOREGROUND
32267 ?        S      0:00  \_ /usr/sbin/httpd -DFOREGROUND
32268 ?        S      0:00  \_ /usr/sbin/httpd -DFOREGROUND
32269 ?        S      0:00  \_ /usr/sbin/httpd -DFOREGROUND

Apacheのプロセスをkillallコマンドで停止するとプロセス番号が更新されていることが判ります。