J’ai chez moi un cluster de Raspberry Pi qui font tourner Docker Swarm. Pour garder le contrôle sur tout ça, ils utilisent tous la même configuration : utilisateurs, versions de Docker, etc.
Parfois, certaines mises à jour demandent d’exécuter la même chose sur tous les nœuds du cluster – par exemple – créer un nouveau réseau Docker macvlan.
Pour ça, il faut soit lancer les mêmes commandes à la main sur tous les nœuds, en se connectant en ssh sur chacun d’eux, en exécutant les commandes puis en passant au suivant.
Comme j’essaie de me faciliter la vie sur le long terme et de garder les choses aussi organisées que possible, je me suis mis à chercher des moyens d’exécuter des commandes sur tous les nœuds en même temps.
Itération 1 : un script Python maison
La première itération a consisté à écrire un script Python maison. D’un côté, ça me permettait d’apprendre un peu mieux Python ; de l’autre, je ne trouvais pas de moyen correct d’exécuter des commandes de façon plus native.
Comme on peut s’y attendre (eh, j’ai encore peu d’expérience dans ce langage 🙂 ), c’est devenu un gros bazar assez vite, et ça cassait très facilement.
Il me fallait trouver une autre solution, sans avoir à réapprendre ce que j’avais fait il y a 3 semaines et ce qui avait planté la dernière fois.
Itération 2 : pssh
En fouillant sur Google, je suis tombé sur [pssh](https://linux.die.net/man/1/pssh), qui permet d’exécuter des commandes en parallèle via SSH.
Tout bien considéré, c’était plutôt facile à mettre en place.
Le problème, c’est que pour exécuter certaines choses, j’avais besoin de passer par sudo. Faire circuler des mots de passe n’était pas l’idéal, alors j’ai dû chercher à nouveau comment envoyer le mot de passe sudo quand le serveur distant le demandait.
Il s’avère que c’est assez simple si on tombe sur le bon commentaire StackOverflow.
La version TL;DR; :
stty -echo; printf "Password: "; read PASS; stty echo; echo "${PASS}" | \
pssh -h <HOSTFILE> -o /tmp/output -t 0 -I "`cat ./commands.sh`"Le -I "`cat ./commands.sh`" doit obligatoirement être écrit comme ça (entouré de guillemets et d’accents graves), sinon les commandes ne s’exécutent pas correctement. Le mot de passe sera envoyé comme une commande à part et non récupéré comme une entrée de sudo.
L’autre subtilité : vu la façon dont tout ça est configuré, il faut lancer sudo avec le paramètre -S pour qu’il lise correctement le mot de passe.