hacks/unix/daemontools

2008年10月01日

このエントリーをはてなブックマークに追加

mongrel_clusterのメモでまとめたとおり


mongrel_clusterは
  • 単に複数mongrel_railsの起動を起動管理
  • 設定をYAML形式で記述可能
  • フォアグラウンドでは起動させられない

mongrel_cluster


daemontoolsを導入するに辺り、
fghackを使ってmongrel_clusterを管理すると言うてがあるのだろうけど、
自分はmongrel_clusterを使わない事にした。

mongrel_clusterが何をやっているのかを知ってからは、
mongrel_clusetr対する熱がすっかり冷めてしまったのだ…。


課題


何を解決しなければ行けないのかを上げてみる
  • serversの扱いをどうするのか
  • YAMLの設定項目はどのように設定するか
こんな所だろう。


解決策


daemontoolsをある程度使っている人ならば恐らく当たり前な事。
  • serversの数だけserviceを作成
  • YAMLの設定項目はenvdirで設定する
図解するとこうなる。

mongrel_cluster


作業内容


サービス追加

# cd /servie/
# ./addsv.sh mongrel_cluster-0
※addsv.shはdaemontoolsの/service/に、サービスを追加するスクリプト「addsv.sh」 を参照。


runファイル設定

# cd /service/.mongrel_cluster-0
# vi run
ここではenvuidgidではなく、USERとGROUPを指定する。
管理の都合など、どうしてもUSERで指定するアカウントで環境変数を指定したいと言う方はenvuidgidを使って下さい。

#!/bin/sh

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin
export PATH

exec 2>&1
sleep 10

exec envdir ./env sh -c '
 [ -d "${CHDIR}" ] || exit 1
 id "${USER}"      || exit 1
 exec mongrel_rails start \
  -e ${ENVIRONMENT:-DEVELOPMENT} \
  -a ${ADDRESS:-127.0.0.1} \
  -p ${PORT:-3000} \
  -c ${CHDIR} \
  -r ${ROOT:-public} \
  --user  ${USER} \
  --group ${GROUP} \
'
envdirディレクトリ作成

# mkdir env
# cd env
envdir用ファイル作成

# echo 127.0.0.1 > ADDRESS
# echo /var/lib/rails/project/ > CHDIR
# echo production > ENVIRONMENT
# echo www-data > GROUP
# echo 8080 > PORT
# echo rails > USER
runの確認

# cd ../
# sh -n ./run
# sh -x ./run
問題無ければサービス対象にする

# cd /service
# mv -i .mongrel_cluster-0 mongrel_cluster-0
同じ作業を繰り返し、
ノード名とPORTファイルの設定が違うmongrelサービスのノードを増加させて行く。

ノード名env/PORT
/service/mongrel_cluster-08080
/service/mongrel_cluster-18081
/service/mongrel_cluster-28082
/service/mongrel_cluster-38083


あくしゅ!はこの仕組みで管理してます。


まとめ


mongerel_clusterを使わないメリット。
  • daemontoolsにより、プロセスが異常終了しても起動してくれる
  • グループの中の特定ノードだけ起動停止が可能になる
  • ログの扱いはmultilog任せ
デメリットは…考えない。
daemontoolsは素敵です。


関連リンク




編集
@hansode at 16:25|PermalinkComments(0)TrackBack(0)

2007年11月08日

このエントリーをはてなブックマークに追加

■本題の前に

▼環境
・Debian GNU/Linux
・spamd(SpamAssassin)をdaemontoolsで管理している。
・設定変更のたびに 「svc -t /service/spamd-ro」をしていた


■「/etc/init.d/spamassassin reload」があるよな

中身を見てみよう

  reload|force-reload)
        echo -n "Reloading $DESC: "
        start-stop-daemon --stop --pidfile $PIDFILE --signal HUP --name $PNAME
        echo "$NAME."
        ;;

なるほど。
HUPシグナルを送っているのか。


■daemontoolsでHUPシグナルを送る

「svc -h」が答え。
# svc -h /service/spamd-ro
これでOK
無駄にTERMを送ってしまっていた。
次回からはTERMではなくHUPだ。


■変更
・[2007/11/08 12:00] タイトルのタイポ修正…ボケボケ



編集
@hansode at 10:30|PermalinkComments(0)TrackBack(0)

2007年09月22日

このエントリーをはてなブックマークに追加

■/service/に新サービスを追加したいけど面倒くさい

daemontoolsはサービスプロセスの起動管理をしてくれる便利ツール。
サービスを新規追加する時、その独特のディレクトリ構成のおかげで、
少々面倒な作業が発生する。毎回覚えてられない。

とにかく面倒くさいのだ。

■だったら、スクリプトを作ってしまえ

簡単な事をさせたい場合、シェルスクリプトは非常に便利だ。
面倒な処理をスクリプトにやらせてしまう。

そうして作られたスクリプトは下記の通り。

▼addsv.sh

#!/bin/sh
#
# http://blog.hansode.org/
#
# $0 <service name>
#

PATH=/bin:/usr/bin:/sbin:/usr/sbin
export PATH


#
# usage
#
usage() {
  cat <<EOS
usage:
  $0 <service name>

EOS
  exit 1
}



#
# main
#
[ $# = 1 ] || usage

svdir=/service
svname=$(basename $1)
acct_name=logadmin
acct_group=logadmin

[ -d ${svdir}  ] || usage
[ -z ${svname} ] && usage
[ -d ${svdir}/.${svname} ] && usage
id ${acct_name} 2>&1 >/dev/null || { echo "no such acct: ${acct_name}"; usage; }



# directory, file

mkdir    ${svdir}/.${svname}
chmod +t ${svdir}/.${svname}
mkdir    ${svdir}/.${svname}/log
mkdir    ${svdir}/.${svname}/log/main
touch    ${svdir}/.${svname}/log/status
chown ${acct_name}:${acct_group} ${svdir}/.${svname}/log/main
chown ${acct_name}:${acct_group} ${svdir}/.${svname}/log/status


# run script

cat <<EOS > ${svdir}/.${svname}/run
#!/bin/sh

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin
export PATH

exec 2>&1
sleep 3

EOS
chmod +x ${svdir}/.${svname}/run


cat <<EOS > ${svdir}/.${svname}/log/run
#!/bin/sh
exec setuidgid ${acct_name} multilog t s1000000 n100 ./main
EOS

chmod +x ${svdir}/.${svname}/log/run



exit 0

▼必要に応じて変更

acct_name=logadmin
acct_group=logadmin
log管理用アカウントを設定する。
スクリプトでは「logadmin」と言うUNIXアカウントを設定した場合の例。

■使い方

自分は上記スクリプトを/service/addsv.shとして、
/service/ディレクトリ直下においている。

▼例: 「new-service」と言うサービスを追加

$ cd /service/
$ sudo ./addsv.sh new-service
addsv.shすると、ドット付きディレクトリが作成される。
その後は、追加したサービスディレクトリ直下のrunファイルに管理したいプロセス等を記述。

$ sudo mv -i .new-service new-service
$ sudo svstat ./new-service

■関連リンク
daemontools
半袖野郎 daemontools


編集
@hansode at 15:35|PermalinkComments(2)TrackBack(0)

2007年01月19日

このエントリーをはてなブックマークに追加

daemontoolsコマンド確認シリーズ

▼概要

envdirは環境変数を扱う時に便利なコマンド。 環境変数名をファイル名、値をファイルの内容にした物を環境変数 として設定してくれる。

envdir: usage: envdir dir child

これだけでは何の事なのか良く分からない。 例としてenvdirを使用するtinydnsのrunスクリプトを見てみる。

$ cat /etc/tinydns/run
#!/bin/sh
exec 2>&1
exec envuidgid tinydns envdir ./env softlimit -d300000 /usr/bin/tinydns

envdirに参照されるディレクトリは./envとなっているのを確認出来る。 ./env以下のファイルを確認。

$ head -1 env/*
==> env/IP <==
192.0.2.1

==> env/ROOT <==
/etc/tinydns/root

これらが環境変数としてchildで指定されるコマンドに反映される。 実際に設定されているのかを確認してみる。

$ envdir ./env env | egrep '^(IP|ROOT)='
ROOT=/etc/tinydns/root
IP=192.0.2.1

なるほど。

▼使い所

envdirを使うと良さそうなアプリケーションの特性

  • コマンドラインオプションではなく、環境変数を設定値として使用するコマンド
  • しかも、環境変数が多数あるコマンド

これらに該当するのは…例えばPostgreSQL。 POSTGRES_HOME, PGLIB, PGDATA等、各種環境変数がある。

$ mkdir env
$ cd ./env

$ echo '/usr/local/pgsql'             > POSTGRES_HOME
$ echo `cat POSTGRES_HOME`'/lib'      > PGLIB
$ echo `cat POSTGRES_HOME`'/data'     > PGDATA
$ echo `cat PGLIB`':$LD_LIBRARY_PATH' > LD_LIBRARY_PATH

$ envdir ./env env

あとは起動スクリプトでenvdirを使い、postmasterを実行してやれ ば良い。『起動スクリプトに書いたままで良いじゃない』と言われ てしまえばそれまでだが、起動スクリプト直書きと、envdirによる 変数分離管理との違いは、設定値変更時の影響範囲。

▼まとめ

起動スクリプトはcvsやsubversionによる管理をし、サーバ毎に変 更される可能性がある項目をそれぞれ別管理にすると、サーバ群の メンテナンスをしやすい。




編集
@hansode at 11:55|PermalinkComments(1)TrackBack(0)

2006年12月26日

このエントリーをはてなブックマークに追加

いくつかあるdjbware。

その中で一番使っているのがdaemontools。 しかし、全般的に使いこなせていない事を再認識した。 再確認して行く。

$ dpkg -L daemontools | egrep ^/usr/bin/
/usr/bin/envdir
/usr/bin/envuidgid
/usr/bin/fghack
/usr/bin/multilog
/usr/bin/pgrphack
/usr/bin/readproctitle
/usr/bin/setlock
/usr/bin/setuidgid
/usr/bin/softlimit
/usr/bin/supervise
/usr/bin/svc
/usr/bin/svok
/usr/bin/svscan
/usr/bin/svscanboot
/usr/bin/svstat
/usr/bin/tai64n
/usr/bin/tai64nlocal



編集
@hansode at 21:30|PermalinkComments(0)TrackBack(0)

2006年12月05日

このエントリーをはてなブックマークに追加

/etc/init.d/spamassassinを参考にrunスクリプト作成。 起動オプションは/etc/default/spamassassinに集約。

#!/bin/sh

exec 2>&1
sleep 3

PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/spamd
NAME=spamd
SNAME=spamassassin
DESC="SpamAssassin Mail Filter Daemon"
PNAME="spamd"

export TMPDIR=/tmp
# Apparently people have trouble if this isn't explicitly set...

# Defaults - don't touch, edit /etc/default/spamassassin
ENABLED=0
OPTIONS=""
NICE=

test -f /etc/default/spamassassin && . /etc/default/spamassassin

DOPTIONS=""

if [ "$ENABLED" = "0" ]; then
    echo "$DESC: disabled, see /etc/default/spamassassin"
    exit 0
fi

test -f $DAEMON || exit 0

set -e

exec $DAEMON -- $OPTIONS $DOPTIONS
$ sudo mv /service/.spamassassin /service/spamassassin
$ sudo svstat /service/spamassassin/
/service/spamassassin/: up (pid 2617) 218 seconds
$ ps awx | egrep '[s]pamd'
 2617 ?        S      0:03 /usr/bin/perl -T -w /usr/sbin/spamd -- -u spamd --create-prefs --max-children 5 --helper-home-dir
 2622 ?        S      0:00 spamd child
 2623 ?        S      0:00 spamd child

上手く行った。




編集
@hansode at 12:15|PermalinkComments(0)TrackBack(0)

2006年12月04日

このエントリーをはてなブックマークに追加

Postgreyのman眺めた。

$ man postgrey
        -d, --daemonize         run in the background

オプションを指定しない限りはforegroundと言う事のようだ。 つまり、daemontoolsでの管理が容易だ。

/etc/init.d/postgreyを参考に作ったrunスクリプト。 これで/etc/init.d/postgreyと同様に/etc/default/postgreyを呼び出せる。 役割分担。何が分担されているかと言うと設定項目とプロセス管理。

  • 設定項目は/etc/default/postgrey
  • プロセスの管理は/service/postgrey/run

Debianの起動スクリプトは良く出来てるねぇ。

#!/bin/sh

exec 2>&1
sleep 3

set -e

PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/postgrey
NAME=postgrey
DESC="postfix greylisting daemon"

# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0

# Read config file if it is present.
if [ -r /etc/default/$NAME ]
then
    . /etc/default/$NAME
fi

if [ -z "$POSTGREY_TEXT" ]; then
    POSTGREY_TEXT_OPT=""
else
    POSTGREY_TEXT_OPT="--greylist-text=$POSTGREY_TEXT"
fi

exec $DAEMON $POSTGREY_OPTS "$POSTGREY_TEXT_OPT"

さて、上手く動くかな。

$ sudo mv /service/postgrey /service/.postgrey
$ sudo svstat /service/postgrey
/service/postgrey: up (pid 3000) 11 seconds
$ ps awx | egrep '[p]ostgrey'
 2891 ?        S      0:00 supervise postgrey
 3000 ?        S      0:00 /usr/sbin/postgrey --inet=127.0.0.1:60000

上手く行った。




編集
@hansode at 23:40|PermalinkComments(0)TrackBack(0)