hacks/unix/daemontools
2008年10月01日
mongrel_clusterのメモでまとめたとおり
mongrel_clusterは
- 単に複数mongrel_railsの起動を起動管理
- 設定をYAML形式で記述可能
- フォアグラウンドでは起動させられない

daemontoolsを導入するに辺り、
fghackを使ってmongrel_clusterを管理すると言うてがあるのだろうけど、
自分はmongrel_clusterを使わない事にした。
mongrel_clusterが何をやっているのかを知ってからは、
mongrel_clusetr対する熱がすっかり冷めてしまったのだ…。
課題
何を解決しなければ行けないのかを上げてみる
- serversの扱いをどうするのか
- YAMLの設定項目はどのように設定するか
解決策
daemontoolsをある程度使っている人ならば恐らく当たり前な事。
- serversの数だけserviceを作成
- YAMLの設定項目はenvdirで設定する

作業内容
サービス追加
# 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 envenvdir用ファイル作成
# echo 127.0.0.1 > ADDRESS # echo /var/lib/rails/project/ > CHDIR # echo production > ENVIRONMENT # echo www-data > GROUP # echo 8080 > PORT # echo rails > USERrunの確認
# cd ../ # sh -n ./run # sh -x ./run問題無ければサービス対象にする
# cd /service # mv -i .mongrel_cluster-0 mongrel_cluster-0同じ作業を繰り返し、
ノード名とPORTファイルの設定が違うmongrelサービスのノードを増加させて行く。
| ノード名 | env/PORT |
| /service/mongrel_cluster-0 | 8080 |
| /service/mongrel_cluster-1 | 8081 |
| /service/mongrel_cluster-2 | 8082 |
| /service/mongrel_cluster-3 | 8083 |
あくしゅ!はこの仕組みで管理してます。
まとめ
mongerel_clusterを使わないメリット。
- daemontoolsにより、プロセスが異常終了しても起動してくれる
- グループの中の特定ノードだけ起動停止が可能になる
- ログの扱いはmultilog任せ
daemontoolsは素敵です。
関連リンク
2007年11月08日
■本題の前に
▼環境
・Debian GNU/Linux
・spamd(SpamAssassin)をdaemontoolsで管理している。
・設定変更のたびに 「svc -t /service/spamd-ro」をしていた
■「/etc/init.d/spamassassin reload」があるよな
中身を見てみよう
なるほど。
HUPシグナルを送っているのか。
■daemontoolsでHUPシグナルを送る
「svc -h」が答え。
無駄にTERMを送ってしまっていた。
次回からはTERMではなくHUPだ。
■変更
・[2007/11/08 12:00] タイトルのタイポ修正…ボケボケ
▼環境
・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] タイトルのタイポ修正…ボケボケ
2007年09月22日
■/service/に新サービスを追加したいけど面倒くさい
daemontoolsはサービスプロセスの起動管理をしてくれる便利ツール。
サービスを新規追加する時、その独特のディレクトリ構成のおかげで、
少々面倒な作業が発生する。毎回覚えてられない。
とにかく面倒くさいのだ。
■だったら、スクリプトを作ってしまえ
簡単な事をさせたい場合、シェルスクリプトは非常に便利だ。
面倒な処理をスクリプトにやらせてしまう。
そうして作られたスクリプトは下記の通り。
▼addsv.sh
▼必要に応じて変更
スクリプトでは「logadmin」と言うUNIXアカウントを設定した場合の例。
■使い方
自分は上記スクリプトを/service/addsv.shとして、
/service/ディレクトリ直下においている。
▼例: 「new-service」と言うサービスを追加
その後は、追加したサービスディレクトリ直下のrunファイルに管理したいプロセス等を記述。
■関連リンク
・daemontools
・半袖野郎 daemontools
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=logadminlog管理用アカウントを設定する。
スクリプトでは「logadmin」と言うUNIXアカウントを設定した場合の例。
■使い方
自分は上記スクリプトを/service/addsv.shとして、
/service/ディレクトリ直下においている。
▼例: 「new-service」と言うサービスを追加
$ cd /service/ $ sudo ./addsv.sh new-serviceaddsv.shすると、ドット付きディレクトリが作成される。
その後は、追加したサービスディレクトリ直下のrunファイルに管理したいプロセス等を記述。
$ sudo mv -i .new-service new-service $ sudo svstat ./new-service
■関連リンク
・daemontools
・半袖野郎 daemontools
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による管理をし、サーバ毎に変
更される可能性がある項目をそれぞれ別管理にすると、サーバ群の
メンテナンスをしやすい。
▼概要
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による管理をし、サーバ毎に変
更される可能性がある項目をそれぞれ別管理にすると、サーバ群の
メンテナンスをしやすい。
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
その中で一番使っているのが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
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
上手く行った。
起動オプションは/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
上手く行った。
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
上手く行った。
$ 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
上手く行った。