Stručné seznámení
Pro Linux i jiné unixy existuje hromada nástrojů na „daemonizování“ procesů, tedy jejich spuštěním tak, aby se odpoutaly od terminálu, kde byly spuštěny, a běžely hezky na pozadí. Jmenovat se dá například daemontools, ale nástroj Supervisor šel v tomto ohledu trochu dále a poskytuje adminům ucelené řešení pro správu téměř jakéhokoli programu či skriptu. Je napsaný v Pythonu a tak je často používán na správu běžících pythoních aplikačních serverů, ale to samozřejmě neznamená, že by jiné jazyky byly z kola venku. Naopak, Supervisor si poradí s čímkoli, co má práva ke spuštění, a ani se to nemusí odtrhávat od mateřského terminálu.
Vývojáři na svých stránkách uvádějí několik hlavních bodů, proč by se admini měli na Supervisor alespoň podívat. Především jde o jednoduchost. Pokud jste někdy psali init skript, tak určitě víte, že to není otázka dvou nebo čtyř řádků, ale je potřeba přesně říct, co se má udělat alespoň při startu, restartu a zastavení, tohle Supervisor překrývá. Tady si možná říkáte, že to svazuje ruce, ale na nějaké komplexní úkoly, kde je potřeba velmi specifické chování při změnách stavu procesu, není Supervisor určen. Zato se třemi řádky v konfiguračním souboru obsloužíte Apache i svůj aplikační server. Supervisor si poradí i s databázemi, OpenLDAPem a s mnoha dalšími službami. Na co není vhodný, je jasné, třeba na skript pro konfiguraci sítě nebo na vypnutí systému.
Na rozdíl od jiných nástrojů je Supervisor centralizovaný. To znamená, že jde o regulérního daemona, který komunikuje přes RPC s ovládací utilitkou nebo přes webové rozhraní. Pro jeho běh tedy nepotřebujete další nástroj, který by správu master procesů sjednocoval. Supervisor pracuje s procesy velmi efektivně, protože je netlačí do pozadí a naslouchá jejich standardnímu vstupu i výstupu. Podle vývojářů díky tomu dokáže odeslat signál rychleji, než kdyby byl process daemonizován. Pokud potřebujete Supervisor do něčeho integrovat, tak jeho architektura a XML-RPC ho umožňuje spravovat téměř z jakéhokoli jazyka.
V současné době je Supervisor v aktivním vývoji a má za sebou už několikaletou historii. Podle vývojářů jede na téměř jakékoli platformě s výjimkou Windows.
Instalace
Jelikož je Supervisor čistý Python kód, není potřeba žádné kompilace a instalace je velmi jednoduchá. Pokud máte k dispozici utilitku pip pro instalaci pythoních balíčků, tak instalace spočívá jen v jejím použití:
# pip install supervisor
Podobně je možné použít easy_install:
# easy_install supervisor
Oba předchozí případy v sobě neschovávají init skript, takže se o spuštění Supervisoru budete muset postarat sami. Proto je lepší použít distribuční balíček, který init skript má, a dokonce i připravenou konfiguraci. V případě Debianu nebo Ubuntu to je:
# apt-get install supervisor
S jinými distribucemi už vám v tomto článku nepomohu.
Použití
To krásné, co se za Supervisorem skrývá je jednoduchá konfigurace. Ta stojí na INI souborech a u Debianu se schovává v adresáři /etc/supervisor. Supervisor má hromadu možností, které by nám pro začátek jen komplikovaly práci. Pokud by vás ale přece jen zajímalo, co všechno umí, podívejte se do dokumentace ke konfiguraci.
Pokud budete chtít používat webové rozhraní, tak do /etc/supervisor/supervisord.conf přidejte tyto čtyři řádky:
[inet_http_server]
port = 127.0.0.1:9001
username = admin
password = abc132
Heslo může být uvedeno i jako sha1 hash, v takovém případě použijte {SHA} jako prefix, takže heslo může vypadat třeba takto {SHA}82ab876d1387bfafe46cc1c8a2ef074eae50cb1d. Hash získáte například přes online službu sha1,cz. Berte na vědomí, že tento způsob není zrovna bezpečný, takže si můžete vypomoci třeba Pythonem, který už v systému určitě máte:
$ echo -n "heslo" | python -c "import hashlib,sys;print hashlib.sha1(sys.stdin.read()).hexdigest()"
A stejně dobře by měla fungovat utilitka sha1sum:
$ echo -n "heslo" | sha1sum
Supervisord jinak funguje jak má a víc pro svou primární funkce nepotřebuje. Přejdeme tedy ke konfiguraci jednotlivých procesů. Ty se dávají do sekcí [program:x], kde x je identifikátor běžícího procesu. Dokumentaci se všemi volbami najdete na webu projektu a já zde uvedu pár voleb, které jsou nejpoužívanější.
Nejdůležitějším a dalo by se říci jediným povinným parametrem je command, kterým říkáte Supervisoru, co má spouštět. Spouštěnému programu můžete předávat parametry, a pokud se sám spouští do pozadí, tak mu v tom zabraňte. Každý proces dřív nebo později vyvolá nějaký exitcode a pokud tento kód nesouhlasí s tím co Supervisor očekává, tak ho restartuje. To znamená, že když proces nějakým způsobem umře, Supervisor ho automaticky nahodí. Jaké kódy jsou v pořádku nastavíte pomocí exitcodes. Ve výchozím stavu to jsou 0 a 2.
Někdy je potřeba, aby některý proces startoval před jiným, v takovém případě oceníte volbu priority. Čím nižší číslo uvedete, tím větší prioritu bude proces mít. Pod jakým uživatelem a skupinou má běžet nastavíte pomocí user a group. Výstup aplikace lze nasměrovat do souboru pomocí stdout_logfile a stderr_logfile. Když aplikace reaguje na proměnné prostředí, tak použijte volbu environment. Jednotlivé proměnné jsou oddělené čárkou takto:
environment=KEY=val,KEY2=val2
Poslední volba, která je důležitá je directory, kterou řeknete Supervisoru, aby před spuštěním procesu změnil aktuální adresář na nastavenou hodnotu.
Když teď známe to nejdůležitější, můžeme tímto způsobem zkusit nastavit nějaký program.
[program:django]
command=python /home/user/djangoproject/manage.py runserver
directory=/home/user/djangoproject
user=cx
groupd=cx
stdout_logfile=/tmp/django.out.log
stderr_logfile=/tmp/django.err.log
Běží-li Supervisor, měli bychom mít možnost se k němu připojit pomocí supervisorctl. Jde o utilitku, která využívá XML-RPC daemona supervisord a s uživatelem umí komunikovat i interaktivně.
# supervisorctl
supervisor> reread
django: changed
supervisor> update
django: stopped
django: updated process group
Když se změní konfigurace, pomocí reread je možné ji znovu načíst a update zkontroluje změny a případně restartuje, co je třeba. Utilitu supervisorctl je možné použít i takto:
# supervisorctl reread
# supervisorctl update
Ovládání
Pokud si nevíte se supervisorctl rady, pomůže příkaz help:
# supervisorctl 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
Některé příkazy se trochu míchají ve významech takže:
- add – aktualizace jednoho procesu
- reload – restart Supervisoru
- reread – znovu načíst konfiguraci
- update – zjistit, co se změnilo v nastavení, a restartovat, co je potřeba
- restart – restart procesu
- shutdown – vypnutí Supervisoru
- start – spuštění procesu
- status – status všech procesů
- stopped – zastavení procesu
Jak se které příkazy používají, zjistíte pomocí:
# supervisorctl help <příkaz>
Shrnutí
Supervisor je hodí tam, kde není úplně vhodné použít init skript, resp. by jeho použití bylo kanónem na vrabce. Na rozdíl od init skriptu, Supervisor si poradí s aplikacemi, které se nerady přesunují do pozadí a dokáže je spravovat přes centrální master proces. S tím je možné komunikovat standardně pomocí utilitky nebo programově díky XML-RPC. Nejvíce ho oceníte při práci s *CGI procesy nebo s různými aplikačními servery, ale poradí si s PostgreSQL, Apachem, Nginxem, Lighttpd a mnoha dalšími. Na rozdíl od klasických init skriptů jsou jednotlivé procesy hlídány a je možné ovlivnit, co se s nimi děje, pokud se objeví nějaký problém.