「SAVACAN」担当のMKです。
今回はインフラを運用する上で、どうしてもサービスやサーバーを自動で強制再起動させてしまいたいときの方法をご紹介したいと思います。
本ブログでは以下のパターンでの自動再起動方法をご紹介します。
- kernel panicが発生したらサーバーを即自動再起動させてダウンタイムを短くしたい!
- 攻撃を受けてプロセス数が同時接続数を超えた場合はサービスを自動再起動させたい!
- ロードアベレージが運用ルール上の閾値を超えたらサービスを自動再起動させたい!
- 停止してしまったプロセスも起動したい!
kernel panicでのサーバー自動再起動
kernel panicとは何か
そもそもkernelとは、OSの中核となる機能を受け持つソフトウェアで、Linuxはkernelとその他のOSを構成するプログラム郡で出来ています。このkernelが、何らかの問題でハングアップした状態がkernel panicです。ソフトウェアの問題で発生することが多いですが、原因究明に時間がかかることもあります。
kernel panicが発生するとコンソール画面に「kernel panic」の文字列が表示され、一切の操作が出来ず、OSとしての機能も停止しています。Windowsでいう所の「ブルースクリーン」と同じ状態です。
ここからの復旧には電源のOFF/ONなど強制停止/再起動が必要となります。
しかしサーバーが遠方にある場合、電源のOFF/ONは容易ではありません。こんな場合に備えて、Linuxにはkernel panicが発生したらOSを自動再起動させる設定があります。
# kernelパラメーターの設定
vi /etc/sysctl.conf
kernel.panic = 10 # kernel panic発生10秒後に再起動
# 設定反映
sysctl -p
# 確認
cat /proc/sys/kernel/panic
10
以上で、kernel panic発生から10秒後に自動でOSが再起動します。
ただし、問題原因によっては再起動後に再びkernel panicとなる場合があります。こうなると残念ながら現地対応が必要になります。
メーカー製サーバー製品の場合、リモートで電源操作を行うための機能が実装されているものもあります。
弊社にて利用の多いDELL製品ではiDRAGという機能にて実装されています。
サービスの同時接続数を超えた場合にサービス再起動
同時接続数を200に設定しているApacheで、同時接続数が250になったときにApacheを自動再起動する参考例です。
Dos系攻撃によるダウンに対応している間も攻撃が続き、再びサービスがダウン!なんてことよくありますよね?このような場合であってもクライアントからサービスは止めてくれるなと指令が出る事もまたよくある事。そんな時の緊急措置として、人手を攻撃への対応措置に回すためサービスの一時復帰はルールベースでcronに任せてしまう方法です。
以下のシェルをcronで毎分実行するようにしておきます。
#!/bin/bash
#httpsへの接続中の数をカウント
COUNT=`ss|grep https|grep ESTAB|wc -l`
LIMIT=250
result=`echo "$COUNT > $LIMIT" | bc`
#echo $COUNT
#echo $result
if [ $result -eq 1 ]; then
echo "restart!!";
systemctl restart httpd
(echo "restart!")| mail -s "restart httpd!" 通知したいメールアドレス
fi
以上でApacheの同時接続数が250になったら自動でApacheが再起動します。
ロードアベレージの値で特定サービスを自動再起動
同時接続数は低いがロードアベレージが高くサーバーが過負荷状態となる場合にロードアベレージ値を基準にサービスを再起動する方法です。
特定のサービスがロードアベレージを上げていることが分かっているときに、原因が特定できるまでロードアベレージが閾値を超えたら自動でサービスを再起動する場合の参考例です。
シェルのやり方は同時接続数でサービスを再起動させるやり方と同じですので、他にも応用ができます。
ロードアベレージの意味を把握されている方に向けた紹介となります。
以下のシェルをcronで毎分実行するようにしておきます。
#!/bin/bash
#ロードアベレージの直近1分を抽出
COUNT=`uptime | awk -F' |,' '{print $(NF-4)}'`
LIMIT=16
result=`echo "$COUNT > $LIMIT" | bc`
#echo $COUNT
#echo $result
if [ $result -eq 1 ]; then
echo "restart!!";
systemctl restart httpd
(echo "restart!")| mail -s "restart httpd!" 通知したいメールアドレス
fi
以上でロードアベレージが16を超えたら自動でApacheが再起動します。
ダウンしたサービスの起動
予期せずダウン(プロセスも起動していない状態になる)したサービスを自動復旧する方法を紹介します。
この例ではmemcachedが利用するポート11211のプロセスが立ち上がっていなかったらmemcachedを起動する方法になります。
以下のシェルをcronで毎分実行するようにしておきます。
#!/bin/sh
mem=`ps -ef | grep "memcached" | grep 11211 | grep -v grep | wc -l`
if [ ${mem} = 0 ]; then
systemctl restart memcached
echo -e "memcached was started." | mail -s "`hostname` memcached start" 通知したいメールアドレス
fi
以上でmemcachedが起動していなければ自動で起動します。
単純なサービスの死活制御であればSupervisorやsystemd、コンテナ化してオーケストレーションにて運用する形がベターですが、シェルで制御する利点はそれらの制約を超えて何でも出来る点です。
が、その必要が無ければ既存のアプリケーションに任せるのが正解です。
自動再起動を行う際の注意点
最後に自動再起動を行う際の注意点です。
サービスの自動再起動は緊急時など複数の対応に追われている際の一時措置として大変助かりますが、あくまでも一時措置ですので日常的な実行や、多様は避けた方が良いでしょう。
また、対象とするサービスは自動再起動させても問題ないものに限定する事を推奨します。ステートフルなサービスやクリティカルな処理を持つサービスで行ってしまうと、データの破損やロストなど、トラブル拡大の引き金となってしまいます。
自動再起動はあくまで一時措置、用法容量を守って正しくお使いください。