Parallel SSH: jeden příkaz vládne všem

31. 8. 2011
Doba čtení: 5 minut

Sdílet

Pokud spravujete desítky serverů, jistě jste zjistili, že to není nic jednoduchého. Často je na řadě z nich potřeba udělat sadu stejných úkonů, což je otravné a trvá to nepříjemně dlouho. Existují ale nástroje, které vám mohou tuto rutinní činnost výrazně usnadnit. Najdete je v balíku pssh.

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.

ict ve školství 24

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.

Autor článku

Petr Krčmář pracuje jako šéfredaktor serveru Root.cz. Studoval počítače a média, takže je rozpolcen mezi dva obory. Snaží se dělat obojí, jak nejlépe umí.