sviluppo-web-qa.it

Esegui automaticamente comandi su SSH su molti server

C'è un elenco di indirizzi IP in un file .txt, ad es .:

1.1.1.1
2.2.2.2
3.3.3.3

Dietro ogni indirizzo IP c'è un server e su ogni server c'è un SSH in esecuzione sulla porta 22. Non tutti i server si trovano nel known_hosts list (sul mio PC, Ubuntu 10.04 LTS/bash).

Come posso eseguire comandi su questi server e raccogliere l'output?

Idealmente, vorrei eseguire i comandi in parallelo su tutti i server.

Userò l'autenticazione con chiave pubblica su tutti i server.

Ecco alcune potenziali insidie:

  • Lo ssh mi chiede di mettere la chiave ssh del server dato al mio known_hosts file.
  • I comandi forniti potrebbero restituire un codice di uscita diverso da zero, indicando che l'output è potenzialmente non valido. Devo riconoscerlo.
  • Potrebbe non essere possibile stabilire una connessione a un determinato server, ad esempio a causa di un errore di rete.
  • Dovrebbe esserci un timeout, nel caso in cui il comando venga eseguito più a lungo del previsto o il server si arresti durante l'esecuzione del comando.

I server sono AIX/ksh (ma penso che non contano davvero.

47
LanceBaynes

Supponendo che non sei in grado di installare pssh o altri, potresti fare qualcosa di simile a:

tmpdir=${TMPDIR:-/tmp}/pssh.$$
mkdir -p $tmpdir
count=0
while IFS= read -r userhost; do
    ssh -n -o BatchMode=yes ${userhost} 'uname -a' > ${tmpdir}/${userhost} 2>&1 &
    count=`expr $count + 1`
done < userhost.lst
while [ $count -gt 0 ]; do
    wait $pids
    count=`expr $count - 1`
done
echo "Output for hosts are in $tmpdir"
15
Arcege

Esistono diversi strumenti che consentono di accedere ed eseguire serie di comandi su più macchine contemporaneamente. Eccone un paio:

62
Caleb

Se sei interessato a Python scripting più di bash scripting, allora Fabric potrebbe essere lo strumento per te.

Dalla home page di Fabric :

Fabric è una libreria Python (2.5 o successiva) e uno strumento da riga di comando per semplificare l'uso di SSH per le attività di distribuzione dell'applicazione o di amministrazione dei sistemi.

Fornisce una suite di operazioni di base per l'esecuzione di comandi Shell locali o remoti (normalmente o tramite Sudo) e il caricamento/download di file, nonché funzionalità ausiliarie come la richiesta di input all'utente o l'interruzione dell'esecuzione.

L'uso tipico prevede la creazione di un Python contenente una o più funzioni, quindi eseguirle tramite lo strumento da riga di comando fab.

18
Riccardo Murri

Uso GNU parallel per questo, in particolare puoi usare this ricetta:

parallel --tag --nonall --slf your.txt command

Con your.txt è il file con l'indirizzo/i nomi IP del server.

11
Anthon

Configurazione molto semplice:

for Host in $(cat hosts.txt); do ssh "$Host" "$command" >"output.$Host"; done

L'autenticazione con nome/password non è davvero una buona idea. È necessario impostare una chiave privata per questo:

ssh-keygen && for Host in $(cat hosts.txt); do ssh-copy-id $Host; done
8
michas

Suggerisco Ansible.cc . È un gestore di configurazione e dispatcher di comandi.

4
Tom

Il progetto Hypertable ha recentemente aggiunto uno strumento ssh multi-host. Questo strumento è costruito con libssh e stabilisce connessioni e invia comandi in modo asincrono e in parallelo per il massimo parallelismo. Vedere Strumento SSH multi-host per la documentazione completa. Per eseguire un comando su un set di host, eseguirlo come segue:

$ ht ssh 1.1.1.1,2.2.2.2,3.3.3.3 uptime

È inoltre possibile specificare un nome host o un modello IP, ad esempio:

$ ht ssh 1.1.1.[1-99] uptime
$ ht ssh Host[00-99] uptime

Supporta anche un --random-start-delay <millis> opzione che ritarderà l'avvio del comando su ciascun host di un intervallo di tempo casuale compreso tra 0 e <millis> millisecondi. Questa opzione può essere utilizzata per evitare tuoni fragorosi quando il comando in esecuzione accede a una risorsa centrale.

2
Doug judd

Penso che tu stia cercando pssh e le relative versioni parallele del solito scp, rsync, ecc.

2
unclejamil

Ho creato uno strumento open source chiamato Overcast per rendere più facile questo genere di cose.

Per prima cosa definisci i tuoi server:

overcast import vm.01 --ip 1.1.1.1 --ssh-key /path/to/key
overcast import vm.02 --ip 2.2.2.2 --ssh-key /path/to/key

Quindi è possibile eseguire più comandi e file di script su di essi, in sequenza o in parallelo, in questo modo:

overcast run vm.* uptime "free -m" /path/to/script --parallel
2
Andrew Childs

Ho sviluppato collectnode Molto semplice ed efficace per eseguire le attività in diversi server (finestre incluse)

Come usare CollectNode:

  1. Crea l'elenco di server, per lavorare con:

    # cat hosts.file
    server1
    server2
    server3
    server4
    server5
    
  2. Esegui CollectNode passando l'elenco dei servizi:

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User'
    
  3. Opzionalmente, è possibile filtrare i risultati, ad esempio questo comando visualizza solo il server in cui viene soddisfatta la condizione.

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User' --where="command contain User"
    

https://collectnode.com/5-tasks-collectnode-can-help-managing-servers/

2
fvidalmolina

Solo un avvertimento per una domanda davvero piacevole:

La migliore soluzione che ho trovato è, non così sorprendentemente, tmux.

Puoi fare Ctrl-B: setwynize-panes in tmux per un incredibile resut. Per questo è necessario avere tutte le connessioni ssh aperte, in diversi riquadri di 1 finestra di Tmux.

1
Mikhail Krutov

Penso che "aspettarsi" sia ciò di cui hai bisogno.
Molte persone non sanno nemmeno che esiste. È un programma basato su tcl che farà domande e possibili risposte per tuo conto. Dai un'occhiata a https://wiki.tcl-lang.org/page/Expect

0
Clement

Crea un file/etc/sxx/hosts

popolare così:

[grp_ips]
1.1.1.1
2.2.2.2
3.3.3.3

condividi chiave ssh su tutte le macchine.

Installa sxx dal pacchetto:

https://github.com/ericcurtin/sxx/releases

Quindi eseguire il comando in questo modo:

sxx [email protected]_ips "whatever bash command"
0
ericcurtin

Forse qualcosa del genere funziona, per eseguire il comando su più host? supponiamo che tutti gli host siano configurati in .ssh/config per l'accesso senza password.

$ < hosts.txt xargs -I {} ssh {} command

0
Y0NG

Usa Paramiko http://www.paramiko.org/ e parallelismo basato su thread https://docs.python.org/3/library/threading.html .below codice consente di eseguire più comandi su ciascun server in parallelo!

ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.load_system_Host_keys()
ssh.connect(hostname, port, username, password)
t = threading.Thread(target=tasks[index], args=(ssh, box_ip,))
t.start()

Nota: ripetere le istruzioni precedenti per ciascun server.

0
Sharma