unoh.github.com

daemontoolsでデーモン管理

Wed Jul 23 19:56:57 -0700 2008

Emacsでbackward-charをC-lに割り当てているbokkoです。「指相撲で相手の指に届かないくらい指が短いので一回も勝ったことがないんです。だからそんな短い指でC-bなんて押してたら指が痛いんです」と言ってもなかなか信じてもらえないのですが、そんな私でも(global-set-key "\C-l" 'backward-char)というelispを評価するだけで快適にプログラミングさせてくれるEmacsが大好きです。


と、タイトルと関係ない話はこれくいらいにしておいて、今日はdaemontoolsのお話です。


daemontools



daemontoolsは異常終了してしまったデーモンプロセスを再起動してくれたり、ログローテートを肩代わりしてくれたりするなど、デーモンの制御や管理、監視を行うプログラムの集まりです。例えば、以下のようなプログラムが含まれています。



ほかにもいろいろありますが、詳しくは本家のマニュアル(日本語版)を見るとよいでしょう。

インストール



ソースコードがこちらで、SRPMがこちらで配布されています。Linuxディストリビューションによってはapt-getでインストールすることもできますが、その場合は名前がdaemontoolsではなく、svtoolsになっているものがあります(Ubuntuは後者でした)。インストールすると、/commandに各プログラムが配置され、/にserviceというディレクトリが作成されます。daemontoolsでデーモンを管理する場合、この/serviceディレクトリにデーモンの起動スクリプトやログ収集のためのスクリプトを配置します。

デーモンの登録



デーモンを登録するには/service以下に登録したいデーモンの起動スクリプトとログ収集のためのスクリプトを配置します。

$ mkdir /var/daemon
$ mkdir /var/daemon/log
$ mkdir /var/daemon/log/main
$ chmod 1755 /var/daemon
$ chmod +x /var/daemon/run
$ chmod +x /var/daemon/log/run
$ chown hoge:fuga /var/daemon/log/main
$ ln -s /var/daemon /service


/var/daemon/run



#!/bin/sh
exec 2>&1 # エラー出力を標準出力へ
exec setuidgid hoge /usr/bin/daemon


/var/daemon/log/run



#!/bin/sh
exec 2>&1 # エラー出力を標準出力へ
exec setuidgid hoge multilog t ./main


runを実行したプロセス自身をデーモン化しなければいかないので、必ずexecを付けます。また、runで実行するプロセスはフォアグラウンドで起動させなければいけません。

追記:(2008/07/24)

/var/daemon/runの内容が/var/daemon/log/runのものになっており、/var/daemon/runの内容が抜けていたのを修正しました。また、現行のdaemontools-0.76ではstickyビットを立てる必要はありません。ご指摘ありがとうございます。>fumiyasさん

デーモンの起動制御



/service以下のデーモンを起動するにはsvscanを使うとよいでしょう。

$ sh -c 'svscan /service &'


↑を実行すると/serviceディレクトリ以下にあるすべてのデーモンに対してsuperviseによるデーモンの監視が行えます。なんらかの原因でデーモンが終了してしまってもsuperviseが自動的にデーモンを再起動してくれます。ただ、デーモンプログラム自体に問題があって起動できない場合、何度も再起動を試み、ずっとログに起動失敗のメッセージを書き込み続けてしまうので注意しましょう。

OS起動時からdaemontoolsに関連するプログラムを起動しておく場合は、/etc/inittabに以下の記述をしておくとよいでしょう。

SV:123456:respawn:/command/svscanboot      


svcでデーモンに命令を発行する



svcコマンドを使うと指定したデーモンに対して以下のような命令を発行することができます。

$ svc -u /service/daemon # 起動
$ svc -d /service/daemon # 一時停止
$ svc -t /service/daemon # 再起動
               ・
               ・
               ・


svstatで状態確認



svstatを使うと指定したデーモンの状態を確認することができます。

$ svstat /service/daemon # 起動中
/service/daemon: up (pid 8131) 3 seconds
$ svstat /service/daemon # 停止中
/service/daemon: down (pid 8131) 57 seconds, normally up


ただ、たまにdaemontools側から起動しているように見えているだけの時があるので注意しましょう。詳しくは後述します。

ロギング



デーモンプログラムの出力は/var/daemon/log/runで実行しているmultilogによって/var/daemon/log/main以下に保存されます。multilogもdaemontoolsに含まれるツールの一つです。保存されるログはそのままでは見づらいので、同じくdaemontoolsに含まれるtai64nlocalで見やすい形式に変換するのがよいでしょう。

$ tai64nlocal < /service/daemon/log/main/current


デーモンが正常に動作しない場合の対処法



最後にdaemontoolsを使用していて実際に遭遇した問題を紹介します。

デーモンがゾンビプロセス化



なんらかの原因でデーモンが異常終了したり、正常に起動しなかった場合、デーモンプロセスがゾンビ化することがあります。daemontools側から見ると正常に動作しているように見えてしまうので、デーモンが正常に動作しているかpsコマンドなどを使って調べてみましょう。特に、異常終了した後に、そのままでは正常に再起動できないようなプログラムをデーモン化している場合は注意が必要です。

superviseがエラーを吐く



supervise: fatal: unable to acquire daemon/supervise/lock: temporary failure


既に指定したデーモンに対してsupervise(もしくはsvscan)が起動していたり、操作ミスなどによりsupervise(もしくはsvscan)自体が異常終了した場合に上記のエラーメッセージが出ることがあります。
この場合、該当するデーモンに対して起動しているsuperviseを終了し(svscanが起動している場合は先にそっちを終了します)、以下のファイルを削除します。

rm /var/daemon/supervise/lock
rm /var/daemon/log/supervise/lock
rm /var/daemon/log/main/lock


追記:(2008/07/24)

一部誤解を与える表現がありましたので、修正しました。

修正箇所

supervise(もしくはsvscan)自体が異常終了した場合に
↓
操作ミスなどによりsupervise(もしくはsvscan)自体が異常終了した場合に


また、lockファイルを削除するよりもいい方法があるようです(コメント
欄参照)。

ご指摘ありがとうございます>fumiyasさん

フォト蔵におけるdaemontoolsの活用例



フォト蔵では今年の7月頃からHyperEstraierによる全文検索を導入したのですが、このHyperEstraierに含まれるestmasterというサーバプログラムの管理にdaemontoolsを活用しています。使い方の一つとしては、estmasterの死活監視があります。estmasterが停止してしまうと検索自体ができなくなってしまいますが、停止してしまってもdaemontools側で自動的に再起動してくれるわけです。


フォト蔵でのHyperEstraierの活用例に関しては、また後日紹介する予定です。


参考ページ