Eseguire il comando in parallelo su più host utilizzando lo strumento PDSH
PDSH è un piccolo strumento molto intelligente che ti consente di eseguire lo stesso comando su più host contemporaneamente e vedere l’output. È un’utilità parallela remota e ad alte prestazioni. Può eseguire più comandi remoti in parallelo e utilizza una “finestra scorrevole” (o fanout) di thread per conservare le risorse sull’host originale consentendo il timeout di determinate connessioni. In questo articolo spieghiamo come installare lo strumento pdsh e mostriamo alcuni esempi.
Come installare PDSH
L’installazione di pdsh è molto semplice, segui passo dopo passo
1) Scaricare l’ultima versione di PDSH dal sito web di Google Code.
2) Estrai e decomprimi un file pdsh
[shaha@oc8535558703 Downloads]$ bzip2 -dc pdsh-2.26.tar.bz2 | tar xvf -
pdsh-2.26/
pdsh-2.26/config.h.in
pdsh-2.26/configure.ac
pdsh-2.26/configure
pdsh-2.26/bootstrap
pdsh-2.26/scripts/
pdsh-2.26/scripts/Makefile.am
3) Ora installa pdsh con i comandi seguenti
[shaha@oc8535558703 Downloads]$ cd pdsh-2.26
[shaha@oc8535558703 pdsh-2.26]$ ./configure --with-ssh --without-rsh
checking metadata... yes
checking build system type... x86_64-redhat-linux-gnu
checking host system type... x86_64-redhat-linux-gnu
checking target system type... x86_64-redhat-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether to enable maintainer-specific portions of Makefiles... no
checking for gcc... gcc
[shaha@oc8535558703 pdsh-2.26]$ make
[shaha@oc8535558703 pdsh-2.26]$ make install
4) Al termine del comando make install, controllare la versione installata di pdsh con il comando seguente
[shaha@oc8535558703 pdsh-2.29]$ pdsh -V
pdsh-2.26
rcmd modules: ssh,exec (default: ssh)
misc modules: (none)
[shaha@oc8535558703 pdsh-2.29]$
Nota :- Mette i binari in /usr/local/ che è utile per scopi di test. Per il lavoro di produzione lo inserirei in /opt o qualcosa del genere – assicurati solo che sia nel tuo percorso.
Potresti notare che ho usato l’opzione –without-rsh nel comando configure. Per impostazione predefinita, pdsh utilizza rsh, che non è realmente sicuro, quindi scelgo di escluderlo dalla configurazione. Per sostituire rsh e rendere ssh il valore predefinito, aggiungi semplicemente la seguente riga al tuo file .bashrc:
[shaha@oc8535558703 ~]$ cat .bashrc
# .bashrc
export PDSH_RCMD_TYPE=ssh
[shaha@oc8535558703 ~]$
Assicurati di “sorgere” il file .bashrc (cioè, il sorgente .bashrc) per impostare la variabile d’ambiente. Puoi anche disconnetterti e accedere di nuovo. Se per qualche motivo vedi quanto segue quando provi a eseguire pdsh,
Requisito per eseguire il comando pdsh su più nodi
a) Chiavi SSH
In questa breve serie di post del blog, darò un’occhiata ad alcuni strumenti molto utili che possono semplificarti la vita come amministratore di sistema di un cluster di macchine Linux. Questo può essere un cluster Hadoop o solo un semplice insieme di macchine “normali” su cui si desidera eseguire gli stessi comandi e monitoraggio.
Per cominciare, useremo le sempre fantastiche chiavi ssh per gestire la sicurezza del cluster. Successivamente, esamineremo l’esecuzione dello stesso comando su più macchine contemporaneamente utilizzando PDSH.
In breve, le chiavi ssh ci consentono di eseguire l’autenticazione senza password in modo sicuro. Lavorare con le chiavi SSH implica prendere la chiave pubblica da un peer e aggiungerla a un’altra macchina per consentire al proprietario della chiave privata del peer di accedere a quella macchina. Quello che faremo qui è generare una coppia di chiavi univoca che verrà utilizzata come identità nel cluster. Quindi ogni nodo avrà una copia della chiave privata, per potersi autenticare a qualsiasi altro nodo, che avrà una copia della chiave pubblica (nonché, a sua volta, la stessa chiave privata).
Abbiamo diversi modi per implementare le chiavi SSH. Poiché si tratta di un cluster sandbox puro, potrei utilizzare la stessa coppia di chiavi SSH che ho generato per il cluster sulla mia macchina, quindi la stessa coppia di chiavi pubblica/privata è distribuita in questo modo:
Innanzitutto, dobbiamo generare la chiave utilizzando ssh-keygen comando
[shaha@oc8535558703 ]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/shaha/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/shaha/.ssh/id_rsa.
Your public key has been saved in /home/shaha/.ssh/id_rsa.pub.
The key fingerprint is:
42:eb:75:b6:67:f3:86:71:e2:30:af:62:24:15:27:1d shaha@oc8535558703.ibm.com
The key's randomart image is:
+--[ RSA 2048]----+
| .E. |
| o o |
| . + |
| . .. |
| o.S o |
| ..o.oo.o . |
| .o .=+= |
| o o+o. |
| . ... .. |
+-----------------+
[shaha@oc8535558703 ]$
Ciò genera due file nella cartella .ssh: le chiavi privata e pubblica (.pub) della coppia:
[shaha@oc8535558703 ~]$ cd .ssh/
[shaha@oc8535558703 .ssh]$ ls -lrt
-rw-------. 1 shaha shaha 1675 Aug 4 01:03 id_rsa
-rw-r--r--. 1 shaha shaha 408 Aug 4 01:03 id_rsa.pub
[shaha@oc8535558703 .ssh]$
b) Preparazione del file authorized_keys
Ora prepareremo il file authorized_keys, che è dove è memorizzata la chiave pubblica SSH di qualsiasi identità autorizzata ad accedere alla macchina. Si noti che ogni utente su una macchina ha il proprio file authorized_keys, in ~/.ssh/. Quindi, ad esempio, l’utente root ha il file in /root/.ssh/authorized_keys e qualsiasi chiave pubblica elencata in quel file sarà in grado di connettersi al server come utente root. Sii consapevole dell’americano [mis-]ortografia di “autorizzato” – scrivilo [correctly] come “autorizzato” e non otterrai errori evidenti, ma neanche l’autenticazione con chiave ssh funzionerà.
Condivisione di artefatti SSH
Ora invieremo questo set di file SSH nella cartella .ssh dell’utente di destinazione su ciascun nodo, che in questo caso è l’utente root. Dal punto di vista della sicurezza, è probabilmente meglio usare un utente non root per il login e poi sudo se necessario, ma stiamo mantenendo le cose semplici (e meno sicure) per cominciare qui. Quindi i file nella nostra cartella sono:
id_rsa – la chiave privata della coppia di chiavi
id_rsa.pub – la chiave pubblica della coppia di chiavi.
A rigor di termini, ciò non richiede la distribuzione a tutti i nodi, ma è comodo e comodo da tenere accanto alla chiave privata.
authorized_keys – questo è il file che il demone sshd su ciascun nodo esaminerà per convalidare la chiave privata fornita da una richiesta di connessione in entrata e quindi deve contenere la chiave pubblica di chiunque sia autorizzato ad accedere alla macchina come questo utente.
[shaha@oc8535558703 ~]$ cat ~/.ssh/id_rsa.pub |ssh ubuntu@ec2-52-58-254-227.eu-central-1.compute.amazonaws.com 'cat >> .ssh/authorized_keys'
ubuntu@ec2-52-58-254-227.eu-central-1.compute.amazonaws.com's password:
[shaha@oc8535558703 ~]$
A questo punto, dovrai inserire la password per l’utente di destinazione, ma divertiti! Questa è l’ultima volta che dovrai inserirlo, poiché gli accessi successivi verranno autenticati utilizzando le chiavi ssh che hai impostato ora.
c) Confermare la connettività senza password
Se ricevi un errore inferiore durante la connettività, meno password
[shaha@oc8535558703 .ssh]$ ssh ec2-user@ec2-52-59-121-138.eu-central-1.compute.amazonaws.com
Agent admitted failure to sign using the key.
ec2-user@ec2-52-59-121-138.eu-central-1.compute.amazonaws.com's password:
Quindi eseguire questo comando
[shaha@oc8535558703 .ssh]$ export SSH_AUTH_SOCK=0
[shaha@oc8535558703 .ssh]$ ssh ec2-user@ec2-52-59-121-138.eu-central-1.compute.amazonaws.com
[shaha@oc8535558703 .ssh]$ ssh ec2-user@ec2-52-59-121-138.eu-central-1.compute.amazonaws.com
Esempio di comando PDSH
Innanzitutto, cercherò di ottenere la versione del kernel di un nodo utilizzando il suo indirizzo IP:
[shaha@oc8535558703 ~]$ pdsh -w ec2-user@ec2-52-59-121-138.eu-central-1.compute.amazonaws.com uname -r
ec2-52-59-121-138: 4.4.11-23.53.amzn1.x86_64
[shaha@oc8535558703 ~]$
L’opzione -w indica che specifichi il nodo o i nodi che eseguiranno il comando. In questo caso, ho specificato l’indirizzo IP del nodo (ec2-52-59-121-138). Dopo l’elenco dei nodi, aggiungo il comando che voglio eseguire, che in questo caso è uname -r. Si noti che pdsh inizia la riga di output identificando il nome del nodo.
1) Esecuzione del comando a nodo singolo
Per combinare i comandi inviati a ciascun host oa un singolo host, è possibile utilizzare il punto e virgola dell’operatore bash standard;
[shaha@oc8535558703 ~]$ pdsh -w ec2-user@ec2-52-28-150-229.eu-central-1.compute.amazonaws.com uname -a;hostname ; who
ec2-52-28-150-229: Linux ip-172-31-16-42.eu-central-1.compute.internal 3.10.0-327.el7.x86_64 #1 SMP Thu Oct 29 17:29:29 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux
LinuxRedhatCluster
shaha tty1 2016-07-31 20:08 (:0)
shaha pts/0 2016-08-02 11:11 (:0.0)
shaha pts/1 2016-08-02 11:13 (:0.0)
shaha pts/2 2016-08-02 12:02 (:0.0)
shaha pts/3 2016-08-02 20:38 (:0.0)
shaha pts/4 2016-08-03 10:52 (:0.0)
shaha pts/5 2016-08-03 15:19 (:0.0)
shaha pts/6 2016-08-03 10:33 (:0.0)
shaha pts/7 2016-08-03 17:09 (:0.0)
shaha pts/8 2016-08-03 18:48 (:0.0)
shaha pts/9 2016-08-03 22:49 (:0.0)
[shaha@oc8535558703 ~]$
2) Esecuzione di comandi multi-nodo
Un modo molto comune per utilizzare pdsh consiste nell’impostare la variabile di ambiente WCOLL in modo che punti al file contenente l’elenco di host che si desidera utilizzare nel comando pdsh. Ad esempio, ho creato una sottodirectory PDSH in cui creo un file hosts che elenca gli host che voglio utilizzare:
[shaha@oc8535558703 ~]$ mkdir PDSH
[shaha@oc8535558703 ~]$ cd PDSH
[shaha@oc8535558703 PDSH]$ vi hosts
Inserisci tutti i nodi nel file host
[shaha@oc8535558703 PDSH]$ more hosts
ubuntu@ec2-52-58-254-227.eu-central-1.compute.amazonaws.com
ec2-user@ec2-52-59-121-138.eu-central-1.compute.amazonaws.com
[shaha@oc8535558703 PDSH]$
Uso solo due nodi: ec2-52-58-254-227.eu-central-1.compute.amazonaws.com e ec2-52-59-121-138.eu-central-1.compute.amazonaws.com . Il primo è il mio sistema di test (come un nodo master del cluster) e il secondo è il mio nodo di calcolo di test. Puoi inserire gli host nel file come faresti sulla riga di comando, separati da virgole. Assicurati di non inserire una riga vuota alla fine del file perché pdsh tenterà di connettersi ad esso. Puoi inserire la variabile d’ambiente WCOLL nel tuo file .bashrc:
export WCOLL=/home/shaha/PDSH/hosts
Come prima, puoi procurarti il tuo file .bashrc o disconnetterti e riconnetterti.
3) Specificare l’esecuzione del comando Hosts
Non elencherò tutti gli altri modi per specificare un elenco di nodi. Il modo più semplice per specificare i nodi sulla riga di comando è utilizzare l’opzione -w:
[shaha@oc8535558703 ~]$ pdsh -w ec2-user@ec2-52-59-121-138.eu-central-1.compute.amazonaws.com,ubuntu@ec2-52-58-254-227.eu-central-1.compute.amazonaws.com uname -r
ec2-52-59-121-138: 4.4.11-23.53.amzn1.x86_64
ec2-52-58-254-227: 3.13.0-92-generic
[shaha@oc8535558703 ~]$
In questo caso, abbiamo specificato i nomi dei nodi separati da virgole. Puoi anche utilizzare una gamma di host come segue:
[shaha@oc8535558703 PDSH]$ pdsh -w ^hosts uptime
ubuntu@ec2-52-58-254-227: 10:00:52 up 2 days, 16:48, 0 users, load average: 0.05, 0.04, 0.05
ec2-user@ec2-52-59-121-138: 10:00:50 up 2 days, 16:51, 0 users, load average: 0.00, 0.01, 0.05
[shaha@oc8535558703 PDSH]$
4) Comandi pdsh più utili
Ora posso passare alla seconda marcia e provare alcuni trucchi pdsh più sofisticati. Innanzitutto, voglio eseguire un comando più complicato su tutti i nodi. Si noti che ho messo l’intero comando tra virgolette. Ciò significa che l’intero comando viene eseguito su ciascun nodo, incluso il primo (cat /proc/cpuinfo) e il secondo (grep bogomips, model, cpu).
[shaha@oc8535558703 PDSH]$ pdsh 'cat /proc/cpuinfo' | egrep 'bogomips|model|cpu'
ubuntu@ec2-52-58-254-227: cpu family : 6
ubuntu@ec2-52-58-254-227: model : 63
ubuntu@ec2-52-58-254-227: model name : Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz
ubuntu@ec2-52-58-254-227: cpu MHz : 2400.070
ubuntu@ec2-52-58-254-227: cpu cores : 1
ubuntu@ec2-52-58-254-227: cpuid level : 13
ubuntu@ec2-52-58-254-227: bogomips : 4800.14
ec2-user@ec2-52-59-121-138: cpu family : 6
ec2-user@ec2-52-59-121-138: model : 62
ec2-user@ec2-52-59-121-138: model name : Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz
ec2-user@ec2-52-59-121-138: cpu MHz : 2500.036
ec2-user@ec2-52-59-121-138: cpu cores : 1
ec2-user@ec2-52-59-121-138: cpuid level : 13
ec2-user@ec2-52-59-121-138: bogomips : 5000.07
[shaha@oc8535558703 PDSH]$
[shaha@oc8535558703 PDSH]$ pdsh vmstat 1 2
ec2-user@ec2-52-59-121-138: procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
ec2-user@ec2-52-59-121-138: r b swpd free buff cache si so bi bo in cs us sy id wa st
ec2-user@ec2-52-59-121-138: 2 0 0 287424 122872 529200 0 0 1 5 10 20 0 0 100 0 0
ubuntu@ec2-52-58-254-227: procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
ubuntu@ec2-52-58-254-227: r b swpd free buff cache si so bi bo in cs us sy id wa st
ubuntu@ec2-52-58-254-227: 1 0 0 262924 153712 505960 0 0 1 5 13 19 0 0 100 0 0
ec2-user@ec2-52-59-121-138: 0 0 0 287504 122872 529232 0 0 0 0 34 74 0 0 100 0 0
ubuntu@ec2-52-58-254-227: 0 0 0 262924 153712 505992 0 0 0 0 18 20 0 0 100 0 0
[shaha@oc8535558703 PDSH]$
[shaha@oc8535558703 ~]$ pdsh -w ubuntu@ec2-52-59-121-138-node0[1-4] "date;sleep 5;date"
ec2-52-59-121-138-node01: Sat Nov 30 20:57:06 GMT 2016
ec2-52-59-121-138-node03: Sat Nov 30 20:57:06 GMT 2016
ec2-52-59-121-138-node04: Sat Nov 30 20:57:06 GMT 2016
ec2-52-59-121-138-node02: Sat Nov 30 20:57:06 GMT 2016
ec2-52-59-121-138-node01: Sat Nov 30 20:57:11 GMT 2016
ec2-52-59-121-138-node03: Sat Nov 30 20:57:11 GMT 2016
ec2-52-59-121-138-node04: Sat Nov 30 20:57:11 GMT 2016
ec2-52-59-121-138-node02: Sat Nov 30 20:57:11 GMT 2016
Si noti che l’utilizzo di virgolette per racchiudere l’intera stringa di comando. Senza di loro, l’interprete bash prenderà il sopravvento ; come delimitatore di comando locale e provare a eseguire i seguenti comandi in locale:
[shaha@oc8535558703 ~]$ pdsh -w ubuntu@ec2-52-59-121-138-node0[1-4] date;sleep 5;date
ec2-52-59-121-138-node03: Sat Aug 30 20:57:53 GMT 2016
ec2-52-59-121-138-node04: Sat Aug 30 20:57:53 GMT 2016
ec2-52-59-121-138-node02: Sat Aug 30 20:57:53 GMT 2016
ec2-52-59-121-138-node01: Sat Aug 30 20:57:53 GMT 2016
Sat 30 Aug 2016 20:58:00 GMT
5) Tubi e reindirizzamenti di file
Simile alla combinazione dei comandi sopra, puoi reindirizzare l’output dei comandi e devi usare le virgolette per racchiudere l’intera stringa di comando.
[shaha@oc8535558703 ~]$ pdsh -w root@ec2-52-59-121-138-node[01-4] "chkconfig|grep collectl"
ec2-52-59-121-138-node03: collectl 0:off 1:off 2:on 3:on 4:on 5:on 6:off
ec2-52-59-121-138-node01: collectl 0:off 1:off 2:on 3:on 4:on 5:on 6:off
ec2-52-59-121-138-node04: collectl 0:off 1:off 2:on 3:on 4:on 5:on 6:off
ec2-52-59-121-138-node02: collectl 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Conclusione
Anche gli amministratori esperti utilizzano strumenti di shell paralleli per comprendere gli stati dei loro sistemi. Questi strumenti sono facili da scrivere in modo da poter archiviare i dati in un file flat o in un database.