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:
known_hosts
fichier.Les serveurs sont AIX/ksh (mais je pense que cela n'a pas vraiment d'importance.
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"
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:
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.
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.
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
Je suggère Ansible.cc . C'est un gestionnaire de configuration et un répartiteur de commandes.
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.
Je pense que vous recherchez pssh et les versions parallèles associées des scp, rsync, etc. habituels.
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
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:
Créez la liste des serveurs, pour travailler avec:
# cat hosts.file
server1
server2
server3
server4
server5
Exécutez CollectNode en passant la liste des serveurs:
collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User'
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/
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.
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
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"
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
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.