いますぐ実践! Linuxシステム管理

[バックナンバーのトップへ] [Linux システム管理のトップへ]


いますぐ実践! Linux システム管理 / Vol.093 / 読者数:995名

こんばんは、うすだです。

わたしは、外で食事をするという習慣が、ほとんどありません。
たまにそういう機会があると、どこの店に入ればいいのかわからなくて、 路頭に迷ってしまいます。

ですので、ひとりのときは、いわゆるフランチャイズなお店に入ることが多いです。 マクドとか。気が楽ですよね。
でも、複数のときで、相手にお任せモードに入れないと、ちょい粋なお店にでも、 というありもしないプレッシャーを感じてしまいます。

先日も、大学時代の友人と会う機会があり、 軽く食べようかっていう流れになったのですが、そこから店に入るまでに、 ずいぶんと時間がかかってしまいました。

結局、スタート地点に戻って、 近くにあったアフタヌーンティーに入ってしまいました。
しかし、アフタヌーンティーって、なんであんなに高いんでしょうね。
いやまあ、おいしいのは認めますけど。庶民にはちょっと辛い価格です。

Afternoon Tea.net
http://www.afternoon-tea.net/index.html

…あれ? 結局なにが言いたかったんだろうか、という疑問を残したまま、 今週も、はりきってまいりたいと思います。

今週のお題 - あちこちのサービスを集中監視する

前回は、別のマシンからサービスの監視を行う方法を、ご紹介しました。

Vol.092 - サービスを遠隔監視する
http://www.usupi.org/sysad/092.html

でも、できることなら、1台のサーバのサービスだけじゃなく、 あちこちのサーバのサービスを、まとめて集中監視したいですよね。

また、確認したくなったときに、その都度、telnet コマンドを実行するというのも、 面倒な話です。当メルマガでよくネタにしている、 cron による定期的かつ自動的な確認を行いたいのが、人情ってもんです。

そんな貴兄のため、今週は、複数のサーバのサービスを集中監視する方法を、 ご紹介したいと思います。


今回は、以下の2段階に分けて、ご紹介したいと思います。

  • とあるサーバのサービスを、定期的に監視する。
  • 複数のサーバのサービスを、一括で、定期的に監視する。

自動的に実行…ということは、 前々回にご紹介した expect を使う必要がありそうですね。 (やった! 前々回とつながった!!!)

Vol.091 - 対話型アプリケーションを自動実行する
http://www.usupi.org/sysad/091.html

おっと、これらを行う前に、前回のサービスの監視を行うスクリプトを、 対象のサーバに仕込んでおいてください。


それではまず、1台のサーバのサービスの監視を、 自動的に行えるようにしたいと思います。

というわけで、いきなりではございますが、expect スクリプトを、 以下のような感じで書いてみました。

  #!/usr/bin/expect
  set timeout 10
  log_user 0

  # 引数から、ホスト名とサービスを得る
  if {$argc != 2} {
      puts "Usage: $argv0 host services"
      exit 1
  }
  set host [lindex $argv 0]
  set service [lindex $argv 1]

  # サーバに接続して状態を知る
  spawn telnet $host 12340
  expect {
      default {
          set result "++ cannot connect: NG"
      } -re "Escape.*\.\n" {
          send "$service\r"
          expect {
              default {
                  set result "++ internal error: NG"
              } -re "\n(.*: NG.*)\nConnection" {
                   set result $expect_out(1,string)
              } -re "\n(.*: OK.*)\nConnection" {
                   set result ""
              }
          }
      }
  }

  # 起動していないサービスがあれば、mail コマンドで root に送信
  if {$result != ""} {
      spawn mail root
      expect "Subject:"
      send "Check Services\ for $host\r"
      send [string map {\r\n \r} "$result"]
      send ".\r"
      expect "Cc:"
      send "\r"
      expect eof
  }

引数から、ホスト名とサービスを得て、telnet コマンドを起動して確認を行います。 返事がないか、": NG" という文字が含まれていると、起動していないと判定し、 mail コマンドを用いて root に通知します。
そうではなく、ちゃんと ": OK" と言われた場合は、なにもしません。

このファイルを /usr/local/sbin/servcheck.exp という名前で保存したとしますと、 以下のように実行して確認しましょう。

  # chmod +x /usr/local/sbin/servcheck.exp
  # /usr/local/sbin/servcheck.exp server1 "httpd sshd"

server1 の httpd と sshd が動作していれば、なにも起こりません。
もし起動していないサービスがあれば、 その旨のメールが root に届いている…はずです。

あとは、これを cron に仕込めば、定期的な監視になります。
たとえば、15分毎に確認するなら、以下を /etc/crontab に追加します。
(行末を \ で折り返していますが、実際は1行です。 また、監視する頻度は、サービスの重要度や、 メールの確認頻度などを考慮して決めましょう。)

  0,15,30,45 * * * * root /usr/local/sbin/servcheck.exp server1 \
  "httpd sshd" > /dev/null 2>&1

これで、1台のサーバのサービスを確認できるようになりました。
それでは次に、複数のサーバの確認を、一括して行ってみましょう。

またしても、結果の expect スクリプトを、以下に示します。

  #!/usr/bin/expect
  set timeout 10
  log_user 0

  # 遠隔監視したいサーバ名とサービスを列挙したデータ
  set services {
      server1 {httpd sshd}
      server2 {httpd sshd nfs}
  }

  # サーバに接続して状態を知る関数
  proc check_service {host service} {
      spawn telnet $host 12340
      expect {
          default {
              return "++ cannot connect: NG\r"
          } -re "Escape.*\.\n"
      }
      send "$service\r"
      expect {
          default {
              set ret "++ internal error: NG\r"
          } -re "\n(.*: NG.*)\nConnection" {
              set ret $expect_out(1,string)
          } -re "\n(.*: OK.*)\nConnection" {
              set ret ""
          }
      }
      return $ret
  }

  # $services を1つずつ試し、$result に失敗した結果を追加する
  set result ""
  for {set i 0} {$i < [llength $services]} {} {
      set host [lindex $services $i]
      incr i
      set service [lindex $services $i]
      incr i
      set ret [check_service $host $service]
      if {$ret != ""} {
          set result "$result+++ $host: $service\n$ret"
      }
  }
  # 起動していないサービスがあれば、mail コマンドで root に送信
  if {$result != ""} {
      spawn mail root
      expect "Subject:"
      send "Check Services\r"
      send [string map {\r\n \r} "$result"]
      send ".\r"
      expect "Cc:"
      send "\r"
      expect eof
  }

まず、監視する対象を、変数 $services で指定しています。
そして、実際に確認する箇所を、check_service という関数にしました。
あとは、$services から、サーバとサービスを順番に得て、 check_service で確認を行い、結果を変数 $result に追加しています。
最後に、$result が空でなければ、先ほどと同様にメールで通知します。

というわけで、お気づきの通り、基本的な流れは、 先ほどのスクリプトとほとんど変わりません。

で、同様に、 このファイルを /usr/local/sbin/servcheckauto.exp という名前で保存した場合、 以下のように実行して確認します。

  # chmod +x /usr/local/sbin/servcheckauto.exp
  # /usr/local/sbin/servcheckauto.exp

そして、これを10分毎に起動して確認する場合、以下を /etc/crontab に追加します。 (行末を \ で折り返していますが、実際は1行です。)

  */10 * * * * root /usr/local/sbin/servcheckauto.exp \
  > /dev/null 2>&1

以上、複数のサーバのサービスを集中監視する方法を、ご紹介しました。

もしうまく動作しないときは、exp_internal を用いると、 デバッグ情報をどっと出力してくれますので、スクリプトに挿入してみましょう。
たとえば、以下のように、怪しい箇所を挟みうちしてみてください。

  exp_internal 1
  ...怪しい箇所...
  exp_internal 0

それと、実は、expect スクリプトの中で、tcl のコマンドが使えます。
expect のドキュメントだけではわからないときは、 tcl のドキュメントをさらっと見ると、なにかわかるかもしれません。

宿題の答え

先週の宿題は、

  現在有効になっているすべてのサービスの状態を、遠隔監視できるよう
  にしてみましょう。

でした。

前回の Perl スクリプトをもとにして、以下のようにしてみました。

  #!/usr/bin/perl
  use strict;
  my $INITDIR="/etc/init.d";       # 環境に応じて変更してください
  my $CHKCONFIG="/sbin/chkconfig";

  sub exec_cmd {
      my ($cmd) = @_;
      my $r;
      if(open(EXEC, "$cmd 2>&1 |")) {
          while(<EXEC>) {
              $r .= $_;
          }
          close EXEC;
          return ($?, $r);
      } else {
          return (-1, "cannot execute.\n");
      }
  }

  if(! opendir(INIT, $INITDIR)) {
      print "cannot open.\n";
      exit 1;
  }
  my @scripts = readdir(INIT);
  closedir INIT;
  my $result;
  foreach my $s (@scripts) {
      next unless $s =~ /^[a-zA-Z0-9\-_]+$/;
      my @r = &exec_cmd("$CHKCONFIG $s");
      if(! $r[0]) {
          @r = &exec_cmd("$INITDIR/$s status");
          $result .= "++ $s: " . ($r[0] ? "NG\n$r[1]":"OK\n");
      }
  }
  print $result;
  exit 0;

前半の、exec_cmd というサブルーチンは、実行したいコマンドを渡すと、 終了ステータスと出力結果が得られるものだと思ってください。

後半は、前回とほぼ同じです。
違うところは、サービス名を標準入力から得るのではなく、 /etc/init.d を opendir,readdir で得るところです。
そして、chkconfig コマンドで有効かどうかを確認し、 有効である場合にのみ status を確認しています。

これを、servcheckall.pl というファイル名にした場合は、 以下のように実行してみてください。

  # chmod +x servcheckall.pl
  # ./servcheckall.pl
  ++ inet: OK
  ++ portmap: OK
  ++ atd: OK
  ...中略...
  ++ kudzu: OK
  ++ anacron: NG
  anacronは停止しています
  ...後略...

実行には、やや時間がかかりますね。
あと、サービスによっては、状態を間違えて教えるひとがいます。
無理矢理結論づけますと、時間や手間を考えたら、 必要なサービスだけを監視したほうがよさそうだ、と言えるのではないかと思います。

今週の宿題

今週の宿題は、

  今週ご紹介した expect スクリプトを、以下のように変更して下さい。

  - 監視するサーバとサービスを引数で指定する。
  - 起動しているかどうかにかかわらず、標準出力に結果を表示する。

です。

一番最後にご紹介したスクリプトですが、確認するサーバとサービスを、 引数で指定できると、汎用的になるかもしれないですよね。
また、スクリプトから直接メールを送信していましたが、 別のコマンドで処理したいというときには、標準出力に出力させる必要があります。

そんな可能性を踏まえて、変更を試みていただけますと幸いです。

あとがき

いま、最初からここまで、じっくり確認していたのですが、 300行を軽く越えてしまっているのは、スクリプトばっかりだからですね。

でも、システム管理ネタとなりますと、どうしても、コマンドの使い方、 設定ファイルやスクリプトの書き方的な話になりますので、 日本語でない言語の羅列が増えるのは、仕方のないことではないかと思います。

まあ、もともと、日本語はあまり得意ではありませんので、 そんな日本語の部分はすっ飛ばして、スクリプトなどをちゃちゃっと試してみる、 てな使い方でも、全然問題なさそうです。(ちょっとさみしいですが…。)

なにはともあれ、 「百聞は一見に如かず、百見は一試に如かず」という諺があるくらいですので、 是非、実際に動かして、体験してくださいませ。

 

今週も、ここまで読んでいただき、ありがとうございました。
それでは、また来週に、お会いしましょう!

 

「いますぐ実践! Linux システム管理」の解除は、以下からできます。
http://www.usupi.org/sysad/ (まぐまぐ ID:149633)

バックナンバーは、こちらにほぼ全部そろっています。
http://www.usupi.org/sysad/backno.html

「栗日記」−「栗日記2.0」ってどうでしょう。単なる思いつきですが。
http://www.usupi.org/kuri/ (まぐまぐ ID:126454)
http://usupi.seesaa.net/ (栗日記ブログ)
http://www.fumido.co.jp/kuriniki/ (栗日記ぎゃらりー)


[バックナンバーのトップへ] [Linux システム管理のトップへ]

トップ

バックナンバー
    [日付順] [目的別]

プロフィール

▼ リンク

独学Linux
Linuxデスクトップ環境に関する情報が満載です。 メルマガもありますよ。
Server World
CentOS 6をサーバとしたときの設定例が、これでもかというくらいたくさん載っています。 CentOS以外のディストリビューション(Fedora, Ubuntu)も充実しています。
LINUXで自宅サーバーを構築・導入(Fedora9)
Fedora9のインストールの仕方から管理方法まで、詳しく載っています。 SearchManには情報がもりだくさんです。
マロンくん.NET
〜サーバ管理者への道〜
Linuxをサーバとして使用するための、いろいろな設定方法が載っています。 マロンくんもかわいいです。 なんといっても、マロンくんという名前がいいですね!!
日経Linux
今や数少なくなってしまったLinuxの雑誌。ニュースやガイドもあります。
Linux Square − @IT
@ITが提供する、Linux の情報が満載。 載っていない設定方法はないんじゃないでしょうか。
gihyo.jp…技術評論社
Linuxに限らず様々な技術情報が満載のサイト。 SoftwareDesign誌も、 ソフトウェア技術者は必見です。
SourceForge.JP Magazine
Linux に限らず、オープンソース関連の記事が網羅されています。
ITmediaエンタープライズ:Linux Tips 一覧
Tips というより FAQ 集でしょうか。わからないことがあれば覗きましょう。
IBM developerWorks : Linux
開発者向けですが、勉強になりますよ。
Yahoo!ニュース - Linux
Yahoo!のLinuxに関するニュース一覧です。
栗日記
システム管理とかと全然関係ありませんが、毎日栗の絵を描いています。
システム管理につかれちゃったとき、癒されたいときに、ご覧ください。:-)
WEB RANKING - PC関連
ランキングに参加してみました。押してやってください。

▼ 作ってみました

Add to Google

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本