Введение в Daemontools
Copyright © 2004 М. Альхименко.
Оригинал (и самая последняя версия) этого документа находится на http://lithium.opennet.ru.
По всем вопросам обращайтесь на articles <at> lithium.opennet.ru
Содержание:
Введение
Как пишет сам DJB: "daemontools — это набор инструментов для управления UNIX-сервисами". Основными отличиями от обычных средств запуска (структуры каталогов rcx.d или rc.d или rc.local и пр.) является способность перезапускать сервис в случае его падения и наличие программы ведения и ротации логов (multilog). Преимущества первого отличия и так imho очевидны, а автоматическая ротация логов, кроме всего прочего, хороша тем, что не позволит исчерпать (случайно или умышленно) свободное место в разделе с /var/log/ разросшимися логами. Также, multilog позволяет вести лог вывода программ, не умеющих отдавать вывод в syslog. Таким образом, можно запускать как сервис программы, вообще не предназначенные для этого. Есть опыт использования этого пакета для запуска djbdns, qmail, squid и apache. Первый расчитан на работу именно в связке с daemontools, второй imho тоже был изначально рассчитан DJB для запуска через daemontools, хотя многие его запускают традиционным способом.
Сразу следует уточнить: изложенное ниже — вольный перевод официального описания с http://cr.yp.to/daemontools.html, приправленое собственными комментариями. К тому же, не все удалось попробовать лично... Поэтому, ничто не заменит вам чтения оригинала документации.
Все команды и пути даются из расчета на работу с RH-based Linux (RH9, ASP9), т.к. пока нет опыта работы с другим ОС. Если у вас другая система, и пути/команды не подходят, пишите — соответствующие поправки будут по возможности включены.
Установка
Создаем каталог /package:# mkdir -p /package
# chmod 1755 /package
# cd /package
Скачиваем исходники daemontools-0.76.tar.gz в /package:
# wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
(версия программы, как и её адрес со временем может поменяться)
Распаковываем:
# gunzip daemontools-0.76.tar
# tar -xpf daemontools-0.76.tar
# rm daemontools-0.76.tar
# cd admin/daemontools-0.76/src
Текущая версия daemotools, также как и qmail и djbdns, дает ошибку при сборке с версией glibc выше 2.3.1. Поэтому надо наложить патч, исправляющий эту несовместимость, если у вас она появляется. Сам патч можно найти на http://www.qmail.org/moni.csi.hu/pub/glibc-2.3.1/. Создаем папку для патча, скачиваем его туда и накладываем на исходники:
# mkdir patch
# cd patch
# wget http://www.qmail.org/moni.csi.hu/pub/glibc-2.3.1/daemontools-0.76.errno.patch
# cd ..
# cd ..
# patch -p1 < src/patch/daemontools-0.76.errno.patch
Собираем и устанавливаем пакет:
# package/install
После сборки и установки, программа svscanboot прописывается в inittab (SV:123456:respawn:/command/svscanboot) и демону init дается команда перечитать этот файл. Init запускает svscanboot (он теперь будет запускаться всегда при старте системы и перезапускаться, если он вдруг упадет (или вы его убьете сами)). Проверяем, все ли прошло удачно:
# pstree
...skip...
|-svscanboot-+-readproctitle
`-svscan
...skip...
это обозначает, что svscanboot запущен и готов обслуживать сервисы.
Принцип работы
Теперь кратко о том, как все это работает. На запущенной системе дерево процессов, имеющих отношение к daemontools выглядит примерно так:init-+
|-svscanboot-+-readproctitle
| `-svscan-+-supervise---dnscache
| |-supervise---multilog
| |-supervise---qmail-send-+-qmail-clean
| | |-qmail-lspawn
| | |-qmail-rspawn
| | `-splogger
| |-supervise---tcpserver
| |-supervise---splogger
| `-supervise---squid-+-redirector
| |-10*[redirector]
| `-unlinkd
(лишние процессы вырезаны)
Svscanboot запускается при старте системы демоном init из inittab. Svscanboot запускает программу svscan в каталоге
/service, который мы создали. В нем будут содержаться сведения о сервисах, которые daemontools будет контролировать - это подкаталоги,
по одному для каждого сервиса. В случае падения svscanboot он перезапускается демоном init. Вывод запущенного svscan svscanboot перенаправляет
в процесс readproctitle. Выглядит это так:
svscan /service2>&1 | readproctitle service errors: .....Далее следуют 400 точек, так что не пугайтесь, увидев их в выводе ps — так задумано. Последние 400 байт вывода svscan заменяют эти точки. Сделано это для того, чтобы можно было узнать о проблемах, запустив ps -auxww.
Svscan служит для запуска и слежения за сервисами. Он запускает по отдельному процессу supervise, который и будет контролировать сервис, для каждого обнаруженного каталога в /service (кроме тех, чьи имена начинаются с точки). Svscan каждые 5 секунд проверяет каталог /service на наличие новых подкаталогов. Если такие будут обнаружены, запускается новая копия supervise для каждого каталога. Если в подкаталоге сервиса содержится каталог log, то будет запущена еще одна копия supervise и создан pippeline между ними. Это сделано для использования логирования выводу программ минуя syslog — используя вывод программы из stdout и stderr. В daemontools для этих целей испольуется программа multilog — замена syslog от DJB, хоть и работает она по другим принципам. Так, например, dnscache из пакета djbdns выводит информацию о своей работе не в syslog, а в stdout. Этот вывод перенаправляется в multilog, который создает в своем подкаталоге main лог-файлы и осуществляет их ротацию. Также, svscan перенаправляет вывод всех дочерних supervise в readproctitle через pipeline, созданный svscanboot.
Supervise является процессом, непосредственно контролирующим сервис. Он вызывается с параметром, в котором содержится имя каталога для контролируемого сервиса в /service. В этом каталоге он ищет скрипт run, который и запускает. Если процесс, обслуживаемый supervise падает, supervise перезапускает его. Supervise создает в каталоге сервиса подкаталог supervise, в котором содержатся сведения о процессе. Эти сведения могут быть прочитаны с помощью программы svstat. Для управления сервисом служит программа svc.
Svc это средство для управления сервисами. Формат его вызова
svc opts servicesгде opt — параметр, воздействующий на сервис, а services имя каталога сервиса, обслуживаемого supervice. Основные параметры, используемые с svc:
- -u: Up. Если сервис не запущен, он запускается. Если сервис останавливается, он будет перезапущен.
- -d: Down. Если сервис запущен, ему посылается сигнал TERM и затем сигнал CONT. После остановки, сервис не перезапускается.
- -o: Once. Если сервис не запущен, он запускается. Если сервис останавливается, он не будет перезапущен.
- -p: Pause. Посылает сервису сигнал STOP.
- -c: Continue. Посылает сервису сигнал CONT.
- -h: Hangup. Посылает сервису сигнал HUP.
- -a: Alarm. Посылает сервису сигнал ALRM.
- -i: Interrupt. Посылает сервису сигнал INT.
- -t: Terminate. Посылает сервису сигнал TERM.
- -k: Kill. Посылает сервису сигнал KILL.
- -x: Exit. supervise завершит работу как только сервис завершится. Если вы используете этот параметр на стабильной системе, вы делаете что-то не так; supervise разработан, чтобы быть запущенным всегда.
Readproctitle запускается программой svcscanboot. При запуске svscan, его stderr и stdout перенаправляется в readproctitle.
Вторым параметром его запуска являются некоторое количество точек (до 400). При получении на stdin какого-либо ввода, он выводит его вместо
этих точек. Это позволяет сразу видеть ошибки при выводе списка процессов с помощью ps -auxww. (Опыт показывает, что это
довольно полезная функция). Чтобы очистить cmdline процесса readproctitle после устранения ошибки можно запустить скрипт
следующего содержания:
#!/bin/sh
echo -n \
"service errors: \
............................................................\
(вырезано 18 одинаковых строк)
............................................................\
"
> /proc/`pidof readproctitle`/fd/0
Этот скрипт посылает строку "service errors: " и 400 точек на stdin процесса через специальный файл в /proc. Можно
просто создать исполняемый скрипт dots в /root/bin, т.к. этот путь обычно есть в PATH.
Multilog читает последовательность строк из stdin и добавляет выбранные строки в лог-файл. В качестве его
параметров запуска выступают несколько операторов, каждый из них определяет действие, производимое с полученной строкой.
Каждая строка по умолчанию заносится в журнал.
Выбор:
Оператор-шаблонисключает сроку, содержащую шаблон.
Оператор
+шаблонвыбирает сроку, содержащую шаблон.
В этих правилах применяется символ подстановки "*".
Предупреждения:
Операторeвыводит первые 200 символов в stderr (которые, судя по всему, попадут в вывод readproctitle).
Файлы состояния:
Оператор=файлзаменяет содержимое файл каждой выбранной строкой (первыми 1000 байтами).
Временные метки:
Операторtдобавляет в начало каждой строки символ @, точную временную метку (в формате TAI64) и пробел. Этот оператор должен быть первым. Перевести временную метку в удобочитаемую форму можно с помощью программы tai64nlocal.
Лог-файлы:
Если оператор каталог начинается с точки или слэша, то оператор
каталогдобавляет каждую выбранную строку в лог-файл в определенном каталоге (если каталог не существует, multilog его создаст). Ведение логов осуществляется следующим образом:
в каталоге содержится некоторое количество старых логов, лог с именем current (текущий лог), и другие файлы, с помощью которых multilog отслеживает свои действия. Имя каждого лога начинается с @, продолжается временной меткой, обозначающей, когда запись в лог была завершена и завершается следующими символами:
- s: Файл полностью завершен и нормально записан на диск.
- u: Запись в файл была завершена некорректно и он может быть усечен. Этот файл не был обработан с помощью оператора !processor
sразмерявляется максимальным размером файла для последующего оператора каталог. Когда current достигает этого размера multilog начинает новый файл. Размер должен быть между 4096 и 16777215 байт. Размер по умолчанию — 99999 байт.
Оператор
nколичествоопределяет максимально количество лог-файлов для последующего оператора каталог. Этот параметр должен быть не меньше 2. Значение по умолчанию — 10. При переименовании файла current multilog удаляет самый старый лог-файл в каталоге, если их количество равно или больше значения этого оператора.
Оператор
!processorопределяет processor (программу-обработчик) для последующего оператора каталог. Этой программе будет передан файл current на stdin перед перед началом нового файла. Вывод программы сохраняется в старом файле current, после чего он переименовывается и создается новый файл current.
Остальные программы
Здесь описаны основные программы из состава daemontools, но не все. С назначением остальных можно ознакомиться на http://cr.yp.to/daemontools.html. Вот их краткое описание:- svok — проверяет, запущен ли определенный сервис. Ничего не выводит на stdout и stderr, результат проверки представлен в виде кода завершения.
- svstat — сообщает, запущен ли определенный сервис и выводит некоторую информацию о его работе.
- fghack — не позволяет уйти сервису в фоновый режим. Используется для запуска демонов, не способных работать в no-daemon mode.
- tai64n — добавляет timestamp в формате TAI64 к каждой полученной строке.
- tai64nlocal — переводит timestamp из формата TAI64 в удобочитаемую форму.
- setuidgid — запускает программу под определенными uid и gid.
- envuidgid — запускает программу с переменными окружения, указывающими на определенные uid и gid ($UID и $GID).
- envdir — запускает программу с измененными переменными окружения, полученными из файлов в определенном каталоге.
- softlimit — запускает программу с новыми ограничениями ресурсов.
- Что делает pgrphack и зачем нужна setlock — так и осталось неясным. Предоставляю вам разобраться в этом самим и написать автору ;) .