立春とは申しますが、まだ寒さ厳しき日が続いております。皆様のサーバーもお変わりありませんでしょうか。こんにちは、mizuno_asです。
暦の上ではそろそろ春らしいのですが、札幌はまだまだ雪の中。というか今週の金曜日からは雪まつりですよ!
それはさておき、今日はサーバーアラートのお話です。
監視あるある
サーバールームで安定稼動を神に祈る運用担当者の姿は、どこの会社でも長期休暇前の風物詩になっていると思います。しかし大変残念なことに、サーバーやネットワークというものはすべからくダウンするものです。我々はその事実を受け入れた上で、この残酷な現実と戦っていかねばなりません。そのためには、サービスダウンを検知し、運用担当に報せる監視システムの存在が必要不可欠です。
でも、本当にそれで十分でしょうか?
アラート通知の定番といえばメールです。でもそのメール、本当に見ていますか? 最近ではコミュニケーションの速度を上げるため、メールよりチャットを使うのが主流かもしれません。でもコーディングに夢中になっていると、やっぱりチャット窓なんて見ていないんじゃないでしょうか?
監視システムは稼動していた。サービスダウンも検知できた。でも人間が気づかない。
みなさんも心あたりがあるんじゃないでしょうか?
そこでILでは、光と音で障害を全社内に通知しています。こうすることで、社員全員が障害に気づくことができるわけです。そう、障害は他人事じゃないんですよ。
今回は社内に余っていたネットワーク監視表示灯(パトライト)「NHL-3FB1」を使い、アラートを可視化するまでの手順を紹介します(ここまで前フリ)。
パトライトをつけてみよう
念の為、パトライトを使いはじめる前には一度初期化をしておきましょう。VOLスイッチをOFFにした状態で、CLEARボタンとTESTボタンを押しながらACアダプタを接続して電源を投入します。するとパトライトが点灯し、「ピピピピ…」と何度かブザーが鳴ります。ブザーが鳴り止んだらスイッチから手を離してください。その後、パトライトが消灯したら初期化は完了です。
工場出荷状態で、パトライトのIPアドレスは「192.168.10.1」になっています。パトライトとPCをLANケーブルで接続し、WebブラウザからこのIPアドレスに接続してください。筆者は作業用のUSB-NIC経由で設定を行いました。
ログイン画面が表示されたら、初期パスワード「patlite」を入力してログインしましょう。
なにはともあれ、最初にやるべきことは管理用パスワードの変更です。「ユーザー認証設定」を開き、新しいパスワードを設定してください。
次に「システム設定」を開き、固定のIPアドレスを設定します。設定後はパトライトのネットワークの再起動が必要です。「設定」ボタンをクリックして30秒ほど待ったら、LANケーブルを本番のネットワークに繋ぎ変えてください。以後はここで設定したIPアドレスでパトライトにアクセスします。
パトライトにコマンドを送るにはいくつかの方法があるのですが、今回はもっとも簡単なRSHを使うことにしました。
「コマンド受信設定」を開き、RSHサーバーの設定を行ってください。といっても、デフォルトでRSHサーバーは有効になっているため、サーバーの設定でいじる部分はほとんどありません。設定すべきは「接続許可設定」の部分です。ここにアクセスを許可するIPアドレスと、RSHのログイン名のペアを設定します。ただし今回はIPアドレスの制限は設けたくなかったため、「送信元アドレス指定」を「無効」にし、共通のログイン名のみを設定しました。もしも「監視サーバーからのみコマンドの送信を許可したい」というような場合は、適宜IPアドレスを設定してください ((こうしておかないと、社内にいるやんちゃ坊主がイタズラしてしまうかもしれません。)) 。これでパトライト側の準備は完了です。
それではデスクトップPCからコマンドを送信して、パトライトを点灯させてみましょう。クライアントにはUbuntu 15.10を使いましたが、デフォルト状態のUbuntuでは、以下のようにalternativesでrshがsshを指しています。
$ update-alternatives --display rsh rsh - 自動モード リンクは現在 /usr/bin/ssh を指しています /usr/bin/ssh - 優先度 20 スレーブ rsh.1.gz: /usr/share/man/man1/ssh.1.gz 現在の '最適' バージョンは '/usr/bin/ssh' です。
そのため、まずはrsh-clientパッケージをインストールしましょう。これで/usr/bin/rshが/usr/bin/netkit-rshを指すようになります。
$ sudo apt-get install rsh-client
rshコマンドに、「パトライトのIPアドレス」「-l 先ほど設定したログイン名」「送信するコマンド」を引数として渡します。まずはパトライトのステータスを取得したいので、「status」コマンドを送信します。
$ rsh IPアドレス -l ログイン名 status 000000
この6桁の数字が、パトライトの現在のステータスを表しています。各桁の意味は左からそれぞれ
桁 | 意味 | 設定値 |
---|---|---|
1 | 赤色の点灯状態 | 0=消灯、1=点灯、2=点滅パターン1、3=点滅パターン2 |
2 | 黄色の点灯状態 | 0=消灯、1=点灯、2=点滅パターン1、3=点滅パターン2 |
3 | 緑色の点灯状態 | 0=消灯、1=点灯、2=点滅パターン1、3=点滅パターン2 |
4 | 青色の点灯状態 | 0=消灯、1=点灯、2=点滅パターン1、3=点滅パターン2 |
5 | 白色の点灯状態 | 0=消灯、1=点灯、2=点滅パターン1、3=点滅パターン2 |
6 | ブザーの鳴動状態 | 0=消音、1=パターン1、2=パターン2、3=パターン3、4=パターン4 |
となります。実はこのNHLシリーズ、モデルによっては最大で5色のライトを点灯させることができるのです。しかし弊社にあるモデルは物理的に赤黄緑の三色しか実装されていないため ((NHL-3FB1の3は3色という意味です。青と白のライトが追加されたモデルの型番はNHL-5FB1となります。)) 、4桁目と5桁目は常に0になります。
パトライトを点灯させるにはalertコマンドを使います。パラメータとして、パトライトに設定したいステータスと、実行させたい時間を指定してください。たとえば赤、黄、緑の3色すべてを5秒間点灯させるには以下のコマンドを実行します。時間は省略することが可能で、その場合は次のコマンドが発行されるか、ステータスがクリアされるまで、設定されたステータスを維持します。
$ rsh IPアドレス -l ログイン名 alert 111000 5
ライトの点灯やブザーの鳴動をキャンセルし、初期状態に戻すにはclearコマンドを実行します。
$ rsh IPアドレス -l ログイン名 clear
後述するアラートとの連携を考え、以下のようなラッパースクリプトを作成しておきましょう。これは全点滅の例ですが、Thunderbirdのアドオンの仕様上、アラート時の赤点滅、復帰時の緑点滅のような、用途ごとのスクリプトを作っておくと便利です。
#!bin/sh IP=(パトライトのIPアドレス) USER=(RSHのログイン名) /usr/bin/rsh $IP -l $USER alert 222000 10
アラートとの連携
これでコマンドラインからパトライトの制御ができるようになりました。それではいよいよ、アラート発生時にパトライトを光らせる設定を行いましょう。XymonやMuninといった監視システムは、アラートをトリガーにして任意のスクリプトを実行できます。ですので監視システムが社内にあるのでしたら、前述のラッパースクリプトを監視システムから直接キックすることも可能です。しかし、本番環境は異なる複数のクラウドプラットフォーム上に存在するのが一般的でしょう。クラウド上の監視システムから社内のパトライトを直接キックすることはできないため、ILではメールを経由して、すべてのアラートを社内に集約しています。
アラート発生時、各プロジェクトの監視システム ((ILでは主にCacti)) はパトライト用のメールアドレスに対してアラートメールを送信します。社内にはこのメールボックスを常に監視しているPCがあり、メールを受信するとパトライトにコマンドを送るようになっているのです。これはThunderbirdのフィルタとアドオンによって実現されています ((procmailなどを使ってもっとスマートに実装できる気もしますが、歴史的な事情でこうなっています。)) 。
Thunderbirdのアドオンマネージャから、「Mailbox Alert」と「ToneQuilla」」を検索してインストールしてください。「Mailbox Alert」はメール受信をトリガーに特定のコマンドをキックするためのアドオンで、「ToneQuilla」はメール受信時に任意のサウンドを再生するためのアドオンです ((これらはどちらも少々古いアドオンです。現在は同様の、もっと新しいアドオンがあるかもしれません。)) 。
Mailbox Alertに実行するスクリプトを登録します。メニューから「ツール」→「Edit Mailbox Alert alerts」を実行してください。登録されているアラート一覧のダイアログが表示されるので「add」をクリックします。今度はアラートの内容をカスタマイズするダイアログが表示されるので、「Execute a command」にチェックを入れ、先ほど作成したラッパースクリプトを登録します。「Test these settings」をクリックすると、スクリプトが実行されてパトライトが点灯するので、一度確認しておくとよいでしょう。「Name」にはわかりやすい名前をつけておきましょう。
最後にメッセージフィルタを作成します。「ツール」→「メッセージフィルタ」を開き、メッセージフィルタを作成しましょう。フィルタ条件を設定したら、動作に「Mailbox Alert」を設定し、先ほど登録したスクリプトを指定します。また動作を追加して、「Play Sound」に任意のwavファイルを設定しておきます。
「いちいちフィルタしなくても、メールが届いたらとにかくパトライトを点灯させておけばいいじゃないか」と思われるかもしれません。しかしパトライトが点灯しただけでは、一体どこのサーバーで何のアラートが発生したのか判別できません。そこでILではメールの差出人やサブジェクトでプロジェクトごとにフィルタを用意し、カスタマイズしたメール着信音を再生するようにしています。音声を併用することで、画面から目を離していても、あるいはミーティング中であっても、視覚と聴覚でアラートに気づくことができるというわけです。
監視システムだけでなく、Jenkinsと連携しているチームもあります。CIを行う上でも、アラートの視覚化は重要ですね。
Raspberry Piで実装してみた
NHL-3FB1には、サーバーをPingで死活監視し、アラート時に自力でメールを送信したり、SNMP Trapを上げる機能が実装されています。簡易的な監視であればパトライト単体でできるため、別途監視サーバーを立てる必要がありません。小規模なオフィスで、これから新規に監視システムを導入したいというような場合には嬉しい機能でしょう。しかし弊社のように、既にCactiやXymonといった監視システムがある場合は、少し話が違ってきます。
NHL-3FB1は、普通に買うと結構いいお値段がします。我々としては「監視システムからネットワーク経由で制御できるライト」が欲しいだけなので、正直なところオーバースペックすぎるのです。もっとシンプルでいいからもっと安いものを、と考えるのは当然じゃないでしょうか。そこでRaspberry Piを使って、警告灯を自作してみることにしました。やっていることはただのLチカですので、それほど難しい工作ではありません。
使ったのはこれ。札幌市民の心のオアシス、梅澤無線で購入したフルカラーLEDです。
RGBそれぞれのアノードをそれぞれ、Raspberry Piの15番、16番、18番ピン(GPIO22、23、24)に接続します。抵抗はざっくりと100Ωのものを使用しました ((VFは赤が2.2V、青と緑が3.2Vなので、抵抗は微妙に変えた方がよいはずですが、LEDの抵抗なんて適当でも光りますので。よい子のみんなはちゃんと計算しましょう。))。カソードは5番ピンのGNDへ。
OSはRaspbianを使いました。Raspbianといえば、Scratchもプリインストールされた学習用オールインワンデスクトップ環境のイメージが強いですよね。そのためRaspberry Piをお手軽なサーバーとして仕立て上げるには不向き。そう思っていた時期が筆者にもありました。ところが最近ではRaspbian Jessie LiteというMinimalなJessieベースのRaspbianイメージが配布されているのです。今回はこいつをほぼそのまま利用しています。
Raspbianには「python-rpi-gpio」というパッケージがプリインストールされています。このモジュールを使うことで、PythonからGPIOを簡単に制御できるのです。それではコードを書いてみましょう。
#!/usr/bin/python import RPi.GPIO as GPIO import time import sys RED=15 GREEN=16 BLUE=18 def light_on(color): GPIO.output(color, True) def light_off(color): GPIO.output(color, False) def r(): light_on(RED) def rb(): light_on(RED) time.sleep(1) light_off(RED) def b(): light_on(BLUE) def bb(): light_on(BLUE) time.sleep(1) light_off(BLUE) def g(): light_on(GREEN) def gb(): light_on(GREEN) time.sleep(1) light_off(GREEN) def light_off_all(): light_off(RED) light_off(BLUE) light_off(GREEN) if __name__ == "__main__": param = sys.argv if (len(param) != 3): print "Usage: %s pattern sec" % param[0] quit() GPIO.setmode(GPIO.BOARD) GPIO.setup(RED, GPIO.OUT) GPIO.setup(GREEN, GPIO.OUT) GPIO.setup(BLUE, GPIO.OUT) for i in range(int(param[2])): eval(param[1] + "()") time.sleep(1) light_off_all() GPIO.cleanup()
赤青緑、それぞれ点灯と点滅を引数で指定できるようにしてみました。たとえば以下のようにすると、青色が3秒間点灯します。
$ /usr/local/bin/led.py b 3
以下のようにすると、緑色が5回(10秒)点滅します。
$ /usr/local/bin/led.py gb 5
あとは監視システムにラッパースクリプトを用意して、ssh越しにled.pyを叩いてあげましょう。あるいはこのRaspberry Pi自身にXymonやMuninをインストールし、監視サーバーに仕立ててもいいかもしれません。
Raspberry PiといえばAquesTalk Piが動きますから、冒頭の動画のように、LEDの点滅と同時にゆっくりボイスを再生することもできますね!
このように、Raspberry Piで安価にパトライト(もどき)を実装することもできます ((筆者の工作やコードがアレなのは気にしない方向で……。)) 。重要なアラートを見落さないためにも、みなさんもちょっとした工夫をしてみてはいかがでしょうか。