-
Notifications
You must be signed in to change notification settings - Fork 56
Supervisord
Supervisord - это демон, написанный на Python, который используется для слежением за работой процессов.
Фактически основная задача Supervisord - это запуск, перезапускать и слежение за процессами. А ещё он имеет консоль, в которой доступны основные команды (список процессов, статус, запуск, останов, перезапуск и т.д. ), web-консоль доступную через HTTP, HTTP-API, он умеет перехватывать вывод в STDOUT или STDERR, перенаправлять потоки в файлы, отображать логи в web-интерфейсе и т.д.
- Очень простой файл конфигураций
- Доступен в репозиториях Debian / Ubuntu и других ОС (ставится через
apt-get
илиpip
) - Имеет систему плагинов и event-listener'ов - т.е. расширяем
- Достаточно простой, но мощный
- Он знает о процессах
- Знает о pid-файлах
- Знает о приоритетах и именах процессов
- Знает о группах, пользователях, umask
- Умеет запускать группы процессов
- Имеет настройки по автоматическому запуску, перезапуску, рабочей директории для процессов, переменных окружения, таймаут на запуск, количество попыток перезапуска, кодах завершения и т.д.
- Умеет запускать от пользователя
- Умеет rotate-ить файлы логов (потоки STDERR и STDOUT)
- Достаточно легковесный
- Умеет работать с потоками ввода/вывода
- Есть консоль для администратора с основными командами (консоль, кстати, умеет работать с удалёнными машинами)
- Есть WEB-интерфейс
- Поддерживает аутентификацию
- Умеет работать через UNIX SOCKETS
- Есть XML-RPC-API
- Версия из репозиториев придерживается debian-way, а это значит, что supervisord можно использовать совместно с установкой DEB-пакетов
Suervisord есть в стандартных репозиториях debian, соответственно нужно просто выполнить команды
$ sudo apt-get update
$ sudo apt-get install supervisor
все зависимости будут подтянуты автоматически (а это python и т.д.).
проверим, что supervisor запустился
$ ps -uxa | grep supervisor
root 439 0.0 0.1 52436 13128 ? Ss 19:00 0:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
Если не запустился (например, при запуске из-под docker), то просто запустим его
$ sudo /etc/init.d/supervisor start
Ещё он поддерживает вот такие команды:
$ sudo /etc/init.d/supervisor
Usage: /etc/init.d/supervisord {start|stop|restart|force-reload|status|force-stop}
Если посмотреть на наименование процесса, то можно увидеть конфигурационный файл, который использует supervisor. Файл конфигурации находится по адресу /etc/supervisor/supervisord.conf
Конфиг очень простой. Важно в конфиге увидеть следующее:
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor/conf.d/*.conf
То есть, файлы с расширением *.conf
из /etc/supervisor/conf.d/
тоже используются в конфигурации, а это означает что наш конфиг нужно просто положить в директорию, чтобы он "подцепился" после перезапуска. Очень удобно для наведения порядка в конфигах или, например, в случае, если мы создаём deb-пакет с информацией для supervisor.
Для начала создадим простой долгоживущий процесс, который будет выводить в STDOUT текущее время.
В моём случае это будет /root/cmd1.sh
#!/bin/bash
while sleep 1; do
date
done
Теперь создадим файл конфигурации для запуска процесса /etc/supervisor/conf.d/cmd1.conf
.
[program:prg1]
command=/root/cmd1.sh
Файл конфигурации очень похож на INI-файл Windows.
- Секция
program
описывает программу для старта - Секция описывается как
[program:<Имя программы>]
- Имя программы - это значащее для нас имя, так как это имя будет отображаться в списке процессов, участвовать в имени логов и т.д.
-
command=
- это команда для запуска
Теперь перезапустим supervisor и посмотрим, что получилось.
$ sudo /etc/init.d/supervisor restart
$ ps -uxa
...
root 1290 0.0 0.0 17688 2744 ? S 19:19 0:00 /bin/bash /root/cmd1.sh
root 2066 0.0 0.0 4112 452 ? S 19:25 0:00 sleep 1
...
Вот процессы, который нас интересуют. Попробуем убить процесс.
$ sudo kill -9 1290
$ ps -uxa
...
root 2192 0.0 0.0 17664 2616 ? S 19:26 0:00 /bin/bash /root/cmd1.sh
root 2193 0.0 0.0 4112 480 ? S 19:26 0:00 sleep 1
...
Как видим процесс перезапустился и об этом свидетельствует новый PID процесса.
Supervisor реагирует на коды завершения, соответственно, логика перезапуска зависит кодов и настроек, если код равен 0, то перезапуск не будет произведён.
Посмотрим на логи, которые пишет supervisor и как он перехватывает потоки приложения.
Логи по умолчанию расположены тут: /var/log/supervisor/
/var/log/supervisor/supervisord.log
2015-02-23 19:19:25,910 CRIT Supervisor running as root (no user in config file)
2015-02-23 19:19:25,910 WARN Included extra file "/etc/supervisor/conf.d/cmd1.conf" during parsing
2015-02-23 19:19:25,937 INFO RPC interface 'supervisor' initialized
2015-02-23 19:19:25,937 WARN cElementTree not installed, using slower XML parser for XML-RPC
2015-02-23 19:19:25,937 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2015-02-23 19:19:25,937 INFO daemonizing the supervisord process
2015-02-23 19:19:25,937 INFO supervisord started with pid 1289
2015-02-23 19:19:26,940 INFO spawned: 'prg1' with pid 1290
2015-02-23 19:19:27,941 INFO success: prg1 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2015-02-23 19:26:52,797 INFO exited: prg1 (terminated by SIGKILL; not expected)
2015-02-23 19:26:53,800 INFO spawned: 'prg1' with pid 2192
2015-02-23 19:26:54,802 INFO success: prg1 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2015-02-23 19:28:29,507 INFO exited: prg1 (terminated by SIGTERM; not expected)
2015-02-23 19:28:30,509 INFO spawned: 'prg1' with pid 2385
2015-02-23 19:28:31,511 INFO success: prg1 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2015-02-23 19:29:01,036 INFO exited: prg1 (terminated by SIGTERM; not expected)
2015-02-23 19:29:02,039 INFO spawned: 'prg1' with pid 2452
2015-02-23 19:29:03,040 INFO success: prg1 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
Файлы с потоками от приложений расположены там же:
$ sudo ls -lah /var/log/supervisor/prg1-std*
-rw------- 1 root root 0 Feb 23 19:19 /var/log/supervisor/prg1-stderr---supervisor-TA58AK.log
-rw------- 1 root root 23K Feb 23 19:33 /var/log/supervisor/prg1-stdout---supervisor-iKQUvY.log
Мы назвали наше приложение как prg1, соответственно и файлы потоками названы как prg1-stdout...
и prg1-stderr...
.
Можно убедиться, что в файлы содержится вывод приложения:
$ sudo tail /var/log/supervisor/prg1-stdout---supervisor-iKQUvY.log
Mon Feb 23 19:34:32 UTC 2015
Mon Feb 23 19:34:33 UTC 2015
Mon Feb 23 19:34:34 UTC 2015
Mon Feb 23 19:34:35 UTC 2015
Mon Feb 23 19:34:36 UTC 2015
Mon Feb 23 19:34:37 UTC 2015
Mon Feb 23 19:34:38 UTC 2015
Mon Feb 23 19:34:39 UTC 2015
Mon Feb 23 19:34:40 UTC 2015
Mon Feb 23 19:34:41 UTC 2015
На самом деле это не просто интерактивная консоль, а панель управления supervisor. С интерактивным и неинтерактивным режимом.
Запустим консоль и посмотрим команды
$ sudo supervisorctl
prg1 RUNNING pid 2452, uptime 0:08:57
supervisor> help
default commands (type help <topic>):
=====================================
add clear fg open quit remove restart start stop update
avail exit maintail pid reload reread shutdown status tail version
supervisor> help tail
tail [-f] <name> [stdout|stderr] (default stdout)
Ex:
tail -f <name> Continuous tail of named process stdout
Ctrl-C to exit.
tail -100 <name> last 100 *bytes* of process stdout
tail <name> stderr last 1600 *bytes* of process stderr
А вот пример использования консоли в неинтерактивном режиме.
$ sudo supervisorctl tail -100 prg1
:18 UTC 2015
Mon Feb 23 19:41:19 UTC 2015
Mon Feb 23 19:41:20 UTC 2015
Mon Feb 23 19:41:21 UTC 2015
Мы получили последние 100 байт из потока STDOUT приложения prg1.
Изменим файл конфигурации и перезапустим приложение из консоли.
[program:prg1]
command=/root/cmd1.sh
[program:prg2]
command=/root/cmd1.sh
Описание процесса:
$ ps -uxa
...
root 2452 0.0 0.0 17720 2692 ? S 19:29 0:00 /bin/bash /root/cmd1.sh
...
$ sudo supervisorctl
prg1 RUNNING pid 2452, uptime 0:15:33
supervisor> help
default commands (type help <topic>):
=====================================
add clear fg open quit remove restart start stop update
avail exit maintail pid reload reread shutdown status tail version
supervisor> avail
prg1 in use auto 999:999
supervisor> help reread
reread Reload the daemon's configuration files
supervisor> reread
prg2: available
supervisor> avail
prg1 in use auto 999:999
prg2 avail auto 999:999
Мы перечитали конфиграцию, воспользовавшись командой reread
. В списке доступных программ появилась prg2
, а список посмотрели командой avail
.
Запустим наше второе приложение:
supervisor> help add
add <name> [...] Activates any updates in config for process/group
supervisor> add prg2
prg2: added process group
supervisor> avail
prg1 in use auto 999:999
prg2 in use auto 999:999
supervisor> status
prg1 RUNNING pid 2452, uptime 0:18:24
prg2 RUNNING pid 4663, uptime 0:00:13
^D
$ ps -uxa
root 2452 0.0 0.0 17732 2704 ? S 19:29 0:00 /bin/bash /root/cmd1.sh
root 4663 0.0 0.0 17664 2792 ? S 19:47 0:00 /bin/bash /root/cmd1.sh
У нас теперь запущено 2 процесса, а первый процесс не изменил своего PID'а, то есть не был перезапущен.
Попробуем остановить процесс.
$ sudo supervisorctl
prg1 RUNNING pid 2452, uptime 0:19:40
prg2 RUNNING pid 4663, uptime 0:01:29
supervisor> help stop
stop <name> Stop a process
stop <gname>:* Stop all processes in a group
stop <name> <name> Stop multiple processes or groups
stop all Stop all processes
supervisor> stop prg1
prg1: stopped
supervisor> status
prg1 STOPPED Feb 23 07:49 PM
prg2 RUNNING pid 4663, uptime 0:01:55
^D
$ ps -uxa
root 4663 0.0 0.0 17672 2800 ? S 19:47 0:00 /bin/bash /root/cmd1.sh
Запуск остановленного процесса осуществляется командой start
supervisor> start prg1
prg1: started
^D
А можно ещё перезапустить процесс, но уже командой restart
. :)
У supervisord есть и web-интерфейс. Чтобы активировать его, добавим следующие строки в /etc/supervisor/supervisord.conf
[inet_http_server]
port=*:9001
username=root
password=root
То есть, добавим web-интерфейс по адресу и порту 0.0.0.0:9001. Данные для авторизации будут root / root.
Перейдём в браузере по адресу: http://127.0.0.1:9001
и увидим такое окно:
Процесс можно остановить, нажав на
stop
...запустить, нажав на
start
... а нажав на имя приложения можно увидеть лог приложения.
... есть даже возможность видеть лог в реальном времени с обновлением. Для это есть ссылка
tail -f
Создадим простой deb-пакет, который будет добавлять конфиг с приложением и запускать приложение в supervisord.
Я буду создавать пакет в /root/
. После команд вызова редактора vim
располагается содержимое редактируемых файлов для наглядности.
# mkdir package
# cd package
# mkdir -p DEBIAN
# mkdir -p etc/supervisor/conf.d/
# cp /etc/supervisor/conf.d/cmd1.conf etc/supervisor/conf.d/cmd2.conf
# vim etc/supervisor/conf.d/cmd2.conf
[program:prg3]
command=/root/cmd1.sh
# vim DEBIAN/control
Package: tmp
Version: 0.2
Maintainer: Some Person <[email protected]>
Architecture: all
Depends: supervisor
Description: Source simple package
# vim DEBIAN/postinst
#!/bin/bash
supervisorctl reread
supervisorctl add prg3
# cd ..
# chmod +x package/DEBIAN/postinst
# dpkg -b package
dpkg-deb: building package `tmp' in `package.deb'.
А теперь установим пакет, чтобы посмотреть как зарегистрируется и запустится приложение
# dpkg -i package.deb
Selecting previously unselected package tmp.
(Reading database ... 9616 files and directories currently installed.)
Unpacking tmp (from package.deb) ...
Setting up tmp (0.2) ...
prg3: available
prg3: added process group
# supervisorctl status
prg1 RUNNING pid 7475, uptime 0:40:48
prg2 RUNNING pid 6590, uptime 0:44:37
prg3 RUNNING pid 17254, uptime 0:00:08
Как видим приложение запустилось.
- TODO:
- user
- process_name
- autorestart
- autostart
- priority
- directory