Pokud máte na starosti větší skupinu serverů se stejnou či podobnou konfigurací, musíte zajistit, aby na nich byla stejná data, konfigurace i služby. Velmi často je na takových serverech potřeba provádět identické akce, jako je změna konfigurace, doinstalace nových balíčků, aktualizace a podobně. V dnešní době clusterů a virtualizačních prostředí je navíc takový stav čím dál běžnější.
Pokud byste měli takové věci dělat ručně, už u desítky serverů byste mohli narazit na problémy. Jednak je taková věc časově náročná a otravná a především při ní může docházet k chybám. Tu zadáte příkaz špatně, tady zapomenete některý z kroků a problémy jsou na světě.
Samozřejmě si pro to můžete napsat skript, který akce provede postupně stejně na všech počítačích. Takové řešení už ale existuje a navíc má tu výhodu, že pracuje paralelně. Časově náročnější akce se tedy provádějí na všech strojích najednou a není třeba čekat na jejich postupné dokončování.
Paralelní SSH
Zmíněné řešení se jmenuje parallel-ssh a už název částečně vysvětluje, oč se jedná. Jde o sadu programů, které umožňují používat SSH paralelně na velkém množství vzdálených serverů. Nejde zdaleka jen o spouštění příkazů, ale i o kopírování souborů nebo zabíjení procesů.
Instalace balíčku je triviální, určitě jej najdete ve své distribuci. Balíček má po rozbalení asi 200 KB a k běhu potřebuje Python. Upozornit vás ale musím na rozdíly v pojmenování jednotlivých utilit, které se vám objeví v systému. Debian pro ně totiž používá jiné pojmenování než upstream a jiné distribuce. Samozřejmě Ubuntu přebírá názvy z Debianu.
Názvy a popis příkazů shrnuje následující tabulka:
Název programu | Příkaz v Debianu | Příkaz ostatní distribuce | popis |
Parallel ssh | parallel-ssh | pssh | Spouštění příkazu na vzdálených serverech |
Parallel scp | parallel-scp | pscp | Kopírování souborů na vzdálené servery |
Parallel rsync | parallel-rsync | prsync | Synchronizace souborů směrem na vzdálené servery |
Parallel nuke | parallel-nuke | pnuke | Zabíjení procesů na vzdálených serverech |
Parallel slurp | parallel-slurp | pslurp | Kopírování souborů ze vzdálených serverů |
Podle své distribuce tedy musíte použít patřičnou podobu příkazů buďto jen s písmenem p
nebo s kompletním parallel-
. Dále budu v příkladech používat delší podobu z Debianu, ale syntaxe zůstává pochopitelně stejná i na ostatních distribucích.
Začínáme ovládat
Abyste mohli začít přímo servery paralelně ovládat, budete potřebovat dvě věci: nastavit přihlašování pomocí klíčů a vytvořit si seznam serverů do textového souboru. První krok je důležitý k tomu, abyste nemuseli stále dokola zadávat hesla k serverům a aby přihlášení proběhlo automaticky. Seznam serverů si vytvoříte do samostatného textového souboru s libovolným názvem, do kterého na každý řádek napíšete informaci o jednom serveru se syntaxí:
host[:port] [uživatel]
Pokud vám všude běží SSH na standardním portu 22 a používáte stejné uživatele jako na počítači, na kterém pracujete, bude stačit v souboru vyplnit jen IP adresy či doménová jména serverů. Uživatele můžete také jednotně změnit při zadávání příkazu pomocí parametru -l
, ale předpokládá to, že je tento uživatel na všech serverech k dispozici.
Tento konfigurační soubor si můžete samozřejmě vytvořit vícekrát a ovládat tak celé skupiny serverů například podle jejich určení, hardware či konfigurace. Pokud máte například část serverů s Debianem a část s RHEL, můžete vytvořit soubory debian.txt
a rhel.txt
a v budoucnu se nebudete muset o další rozdělení starat.
Příklady použití
Nejjednodušším použitím je zavolání konkrétního příkazu. Zkusíme nejprve něco opravdu jednoduchého:
$ parallel-ssh -A -h servery.txt -o /tmp/vystup "uname -a" [1] 14:34:26 [SUCCESS] 192.168.1.101 [2] 14:34:26 [SUCCESS] 192.168.1.102 [3] 14:34:26 [SUCCESS] 192.168.1.103 [4] 14:34:26 [SUCCESS] 192.168.1.104
První parametr zapíná dotaz na heslo (viz poznámky na konci článku), následuje volba souborů se seznamem serverů, adresář s výstupy a pak samotný příkaz. Adresář s výstupy je lokální a bude obsahovat výstupy jednotlivých serverů rozházené po souborech se jménem (nebo IP adresou) serveru v názvu. To je velmi užitečné u komplikovaných akcí, kdy chcete mít k dispozici záznam a vyhledat v něm případné problémy.
Pokud nechcete výstup psát do souboru, ale rovnou vidět na obrazovce (a třeba přímo filtrovat grepem), použijte místo -o
parametr -i
. Výstupy se budou objevovat přímo nad hlášením o úspěšném provedení příkazu, takže je bez problému přiřadíte ke konkrétním strojům:
$ parallel-ssh -A -h servery.txt -i "uname" Linux [1] 14:53:05 [SUCCESS] 192.168.1.101 Linux [2] 14:53:05 [SUCCESS] 192.168.1.102 Linux [3] 14:53:05 [SUCCESS] 192.168.1.103 Linux [4] 14:53:05 [SUCCESS] 192.168.1.104
Ostatní příkazy se používají velmi podobně, jen mají jiný smysl. Pokud potřebujete na servery nakopírovat nový skript, použijete parallel-scp
:
$ parallel-scp -A -h servery.txt skript /tmp/skript
Tento příklad bude fungovat jen pro jeden jediný soubor. Pokud budete potřebovat zkopírovat celý adresář, použijte parametr -r
. Podobně je možné použít paralelizovaný rsync, pokud budete chtít synchronizovat celý adresář. Dejme tomu, že máte svůj adresář se skripty, který chcete udržovat na serverech stejný.
$ parallel-rsync -h servery.txt -A -r moje-skripty /home/petr/skripty
Dva předchozí příkazy umožňují přesunout soubory směrem na server. Pokud naopak potřebujeme třeba stáhnout logy ze serveru směrem k nám, musíme použít parallel-slurp
(čili „paralelní srk“). V příkladu si stáhneme soubory se seznamem uživatelů na jednotlivých serverech.
$ parallel-slurp -A -h servery.txt -L /tmp/vystup /etc/passwd uzivatele.txt
Výstup se objeví v adresáři /tmp/vystup
a v podadresářích pojmenovaných podle serverů. V každém z nich bude soubor uzivatele.txt
, který bude obsahovat výstup z patřičného passwd
.
Poslední příkaz z balíku pssh
umí zabíjet vzdálené procesy. Jeho použití je velmi jednoduché a je analogické tomu, co už jsme používali dřív.
$ parallel-nuke -A -h servery.txt java
Několik důležitých poznámek
Standardně používají programy z balíku pssh maximálně 32 vláken. Více spojení program neotevře a další servery pak budou čekat ve frontě. Pokud budete obsluhovat větší množství serverů a chcete to udělat najednou, můžete počet vláken zvýšit parametrem -p
.
Zároveň mají některé příkazy také časové omezení, které je standardně nastaveno na jednu minutu. Po této lhůtě program automaticky běžící příkaz ukončí, odpojí se a nahlásí chybu.
Týká se to variant ssh a nuke, naopak scp a rsync standardní timeout nemají. V každém případě je ale možné ho při delších akcích nastavit parametrem -t
. V opačném případě byste se po uplynutí času dozvěděli:
[1] 14:50:21 [FAILURE] 192.168.1.103 Timed out, Killed by signal 9
Pokud máte u sebe privátní klíč chráněný heslem, skončí pokusy chybou 255. Musíte utilitě sdělit, že se má na heslo zeptat. V takovém případě použijte navíc parametr -A
.
Program se na heslo zeptá jednou a předá jej přímo SSH. Nemělo by se tedy objevit nikde v komunikaci ani ve výpisech programu. Mám tento postup s veřejným klíčem vyzkoušený a funguje bez problémů.
Pokud byste chtěli používat pssh
ve skriptech, můžete použít proměnné PSSH_HOSTS
a PSSH_USER
k uložení seznamu serverů, respektive k zapsání jména vzdáleného uživatele.