web-dev-qa-db-fra.com

Exécuter automatiquement des commandes via SSH sur de nombreux serveurs

Il y a une liste d'adresses IP dans un fichier .txt, ex .:

1.1.1.1
2.2.2.2
3.3.3.3

Derrière chaque adresse IP, il y a un serveur, et sur chaque serveur, il y a un sshd en cours d'exécution sur le port 22. Tous les serveurs ne sont pas dans le known_hosts list (sur mon PC, Ubuntu 10.04 LTS/bash).

Comment puis-je exécuter des commandes sur ces serveurs et collecter la sortie?

Idéalement, j'aimerais exécuter les commandes en parallèle sur tous les serveurs.

J'utiliserai l'authentification par clé publique sur tous les serveurs.

Voici quelques pièges potentiels:

  • Le ssh m'invite à mettre la clé ssh du serveur donné dans mon known_hosts fichier.
  • Les commandes données peuvent renvoyer un code de sortie différent de zéro, indiquant que la sortie est potentiellement invalide. Je dois reconnaître cela.
  • Une connexion peut ne pas être établie avec un serveur donné, par exemple en raison d'une erreur réseau.
  • Il doit y avoir un délai d'attente, au cas où la commande s'exécute plus longtemps que prévu ou si le serveur tombe en panne pendant l'exécution de la commande.

Les serveurs sont AIX/ksh (mais je pense que cela n'a pas vraiment d'importance.

47
LanceBaynes

En supposant que vous ne pouvez pas installer pssh ou d'autres, vous pouvez faire quelque chose de similaire à:

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

Il existe plusieurs outils qui vous permettent de vous connecter et d'exécuter une série de commandes sur plusieurs machines en même temps. En voici deux:

62
Caleb

Si vous aimez les scripts Python plus que les scripts bash, alors Fabric pourrait être l'outil pour vous.

Depuis la page d'accueil de Fabric :

Fabric est une bibliothèque Python (2.5 ou supérieure) et un outil de ligne de commande pour rationaliser l'utilisation de SSH pour le déploiement d'applications ou les tâches d'administration de systèmes.

Il fournit une suite d'opérations de base pour l'exécution de commandes Shell locales ou distantes (normalement ou via Sudo) et le téléchargement/téléchargement de fichiers, ainsi que des fonctionnalités auxiliaires telles que l'invitation de l'utilisateur en cours de saisie ou l'interruption de l'exécution.

L'utilisation typique consiste à créer un module Python contenant une ou plusieurs fonctions, puis à les exécuter via l'outil de ligne de commande fab.

18
Riccardo Murri

J'utilise parallèle GN pour cela, plus précisément vous pouvez utiliser this recette:

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

Avec your.txt étant le fichier avec l'adresse/les noms IP du serveur.

11
Anthon

Configuration très basique:

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

L'authentification avec un nom/mot de passe n'est vraiment pas une bonne idée. Vous devez configurer une clé privée pour cela:

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

Je suggère Ansible.cc . C'est un gestionnaire de configuration et un répartiteur de commandes.

4
Tom

Le projet Hypertable a récemment ajouté un outil ssh multi-hôte. Cet outil est construit avec libssh et établit des connexions et émet des commandes de manière asynchrone et en parallèle pour un parallélisme maximal. Voir Outil SSH multi-hôte pour une documentation complète. Pour exécuter une commande sur un ensemble d'hôtes, vous devez l'exécuter comme suit:

$ ht ssh 1.1.1.1,2.2.2.2,3.3.3.3 uptime

Vous pouvez également spécifier un nom d'hôte ou un modèle IP, par exemple:

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

Il prend également en charge un --random-start-delay <millis> option qui retardera le démarrage de la commande sur chaque hôte d'un intervalle de temps aléatoire entre 0 et <millis> millisecondes. Cette option peut être utilisée pour éviter des problèmes de troupeau tonitruants lorsque la commande en cours d'exécution accède à une ressource centrale.

2
Doug judd

Je pense que vous recherchez pssh et les versions parallèles associées des scp, rsync, etc. habituels.

2
unclejamil

J'ai construit un outil open source appelé Overcast pour rendre ce genre de chose plus facile.

Vous définissez d'abord vos serveurs:

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

Ensuite, vous pouvez exécuter plusieurs commandes et fichiers de script sur eux, de manière séquentielle ou en parallèle, comme suit:

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

J'ai développé collectnode Très simple et efficace pour exécuter des tâches sur plusieurs serveurs (fenêtres incluses)

Comment utiliser CollectNode:

  1. Créez la liste des serveurs, pour travailler avec:

    # cat hosts.file
    server1
    server2
    server3
    server4
    server5
    
  2. Exécutez CollectNode en passant la liste des serveurs:

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User'
    
  3. En option, il est possible de filtrer les résultats, par exemple, cette commande affiche uniquement le serveur sur lequel la condition est remplie.

    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

Juste un headsup pour une question vraiment sympa:

La meilleure solution que j'ai trouvée est, sans surprise, tmux.

Vous pouvez faire Ctrl-B: setw synchronize-panes dans tmux pour une resut incroyable. Vous devez avoir toutes vos connexions ssh ouvertes, dans différents volets de 1 fenêtre de Tmux pour cela.

1
Mikhail Krutov

Je pense que "attendre" est ce dont vous avez besoin.
Beaucoup de gens ne savent même pas qu'il existe. C'est un programme basé sur tcl qui posera des questions et des réponses possibles en votre nom. Jetez un œil à https://wiki.tcl-lang.org/page/Expect

0
Clement

Créez un fichier/etc/sxx/hosts

remplissez comme suit:

[grp_ips]
1.1.1.1
2.2.2.2
3.3.3.3

partager la clé ssh sur toutes les machines.

Installez sxx à partir du package:

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

Exécutez ensuite la commande comme suit:

sxx username@grp_ips "whatever bash command"
0
ericcurtin

Peut-être que quelque chose comme ça fonctionne, pour exécuter la commande sur plusieurs hôtes? supposons que tous les hôtes soient configurés dans .ssh/config pour une connexion sans mot de passe.

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

0
Y0NG

Utilisez Paramiko http://www.paramiko.org/ et le parallélisme basé sur les threads https://docs.python.org/3/library/threading.html .below le code permet d'exécuter plusieurs commandes sur chaque serveur en parallèle!

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()

Remarque: répétez les instructions ci-dessus pour chaque serveur.

0
Sharma