Wie kann ich automatisieren Befehle remote über SSH auf mehreren Servern parallel laufen?
Frage
Ich habe um ein bisschen für ähnliche Fragen gesucht, aber andere als einen Befehl ausgeführt wird oder vielleicht ein paar Befehl mit Gegenständen wie:
ssh user@host -t sudo su -
Was aber, wenn ich brauche, um im Wesentlichen ein Skript laufen auf (sagen wir mal) 15 Servern gleichzeitig. Ist das machbar in bash? In einer perfekten Welt muß ich die Installation von Anwendungen zu vermeiden, wenn überhaupt möglich, diese weg zu ziehen. Zum Argument willen, lasst uns einfach sagen, dass ich die folgenden über 10 Hosts tun müssen:
- Bereitstellen eines neuen Tomcat-Container
- Stellen Sie eine Anwendung in dem Behälter und konfigurieren
- Konfigurieren eines Apache vhost
- Neu laden Apache
Ich habe ein Skript, das all das tut, aber es verlässt sich auf mich alle in den Servern anmelden, ein Skript nach unten aus einem Repo ziehen, und dann läuft es. Wenn dies nicht machbar in bash ist, welche Alternativen schlagen Sie vor? Muss ich einen größeren Hammer, wie Perl (Python bevorzugt werden könnte, da ich garantieren kann auf alle Boxen in einem RHEL-Umgebung dank yum / up2date Python ist)? Wenn jemand zu mir alle notwendigen Informationen zeigen kann es sehr zu schätzen würde, vor allem, wenn es in der Bash machbar ist. Ich werde für Perl oder Python begleichen, aber ich weiß einfach nicht, diese ebenfalls (arbeiten daran). Dank!
Lösung
Oft werde ich nur die ursprüngliche Version Tcl verwenden von Expect. Sie müssen nur, dass auf der lokalen Maschine haben. Wenn ich in einem Programm mit Perl bin, tue ich dies mit Net :: SSH :: erwarten Sie . Andere Sprachen haben ähnliche "erwarten" Tools.
Andere Tipps
Sie können eine lokale Skript ausführen, wie durch che und Yang gezeigt, und / oder Sie können ein Hier-Dokument verwenden:
ssh root@server /bin/sh <<\EOF
wget http://server/warfile # Could use NFS here
cp app.war /location
command 1
command 2
/etc/init.d/httpd restart
EOF
Die Frage, wie Befehle auf vielen Servern laufen sofort auf den anderen Tag Mailingliste Perl kam und ich die gleiche Empfehlung gab ich dort , die gsh
zu verwenden ist:
http://outflux.net/unix/software/gsh
GSH ist ähnlich der „for box in box1_name box2_name box3_name
“ Lösung bereits gegeben aber ich finde gsh bequemer zu sein. Sie legen ein / etc / Gespenster-Datei mit Ihren Servern in Gruppen wie Web, db, RHEL4, x86_64, oder was auch immer (Mann Geister), dann verwenden Sie diese Gruppe, wenn Sie gsh nennen.
[pdurbin@beamish ~]$ gsh web "cat /etc/redhat-release; uname -r"
www-2.foo.com: Red Hat Enterprise Linux AS release 4 (Nahant Update 7)
www-2.foo.com: 2.6.9-78.0.1.ELsmp
www-3.foo.com: Red Hat Enterprise Linux AS release 4 (Nahant Update 7)
www-3.foo.com: 2.6.9-78.0.1.ELsmp
www-4.foo.com: Red Hat Enterprise Linux Server release 5.2 (Tikanga)
www-4.foo.com: 2.6.18-92.1.13.el5
www-5.foo.com: Red Hat Enterprise Linux Server release 5.2 (Tikanga)
www-5.foo.com: 2.6.18-92.1.13.el5
[pdurbin@beamish ~]$
Sie können auch Split-Geistergruppen, mit Web + db oder Web-RHEL4 zum Beispiel kombinieren oder.
Ich werde auch erwähnen, dass, während ich noch nie verwendet shmux, ihre Website eine Liste enthält von Software (einschließlich GSH), die Sie auf einmal ausführen Befehle auf vielen Servern können. Capistrano wurde bereits erwähnt und (von dem, was ich verstehe) auf dieser Liste als auch sein könnte.
Hier finden Sie aktuelle Expect (man expect
)
Ich habe in der Vergangenheit ähnliche Aufgaben durchgeführt unter Verwendung von Expect.
Sie können über die Pipeline das lokale Skript auf dem Remote-Server und führen Sie es mit einem Befehl:
ssh -t user@host 'sh' < path_to_script
Dies kann durch die Verwendung der öffentlichen Key-Authentifizierung automatisiert werden und Umwickeln mit Skripten parallele Ausführung auszuführen.
Sie können versuchen, paramiko . Es ist ein pures-Python SSH-Client. Sie können Ihre SSH-Sitzungen programmieren. Nichts auf Remote-Rechner zu installieren.
Sehen Sie diesen großer Artikel rel="nofollow auf, wie es zu benutzen.
Um Ihnen die Struktur, ohne eigentliche Code.
- Verwenden Sie scp Ihre Installation / Setup-Skript auf das Zielfeld zu kopieren.
- Verwenden Sie ssh Ihr Skript auf dem Remote-Box aufzurufen.
pssh kann interessant sein, da, anders als die meisten Lösungen, die hier erwähnt, werden die Befehle parallel laufen .
(Für meinen eigenen Gebrauch, ich ein einfacheres kleines Skript sehr ähnlich GavinCattell ist ein schrieb, es ist hier dokumentiert -. in französisch )
Für diejenigen, die sich über diese Frage stolpern, werde ich eine Antwort enthalten, die Stoff verwendet , die genau löst das Problem beschrieben . oben: Ausführen beliebiger Befehle auf mehreren Hosts über ssh
Sobald Stoff installiert ist, können Sie eine fabfile.py
schaffen würde, und implementieren Aufgaben , die auf dem Remote-Rechner ausgeführt werden können. Zum Beispiel kann eine Aufgabe Reload Apache könnte wie folgt aussehen:
from fabric.api import env, run
env.hosts = ['host1@example.com', 'host2@example.com']
def reload():
""" Reload Apache """
run("sudo /etc/init.d/apache2 reload")
Dann auf dem lokalen Computer, laufen fab reload
und der sudo /etc/init.d/apache2 reload
Befehl würde auf alle Hosts in env.hosts
angegeben fahren werden.
Sie können es auf die gleiche Weise tun Sie vorher, nur Skript es anstatt es manuell zu tun. Der folgende Code Fernbedienungen Maschine ‚loca‘ genannt und läuft dort zwei Befehle. Was Sie tun müssen, ist einfach einfügen Befehle, die Sie dort ausgeführt werden soll.
che@ovecka ~ $ ssh loca 'uname -a; echo something_else' Linux loca 2.6.25.9 #1 (blahblahblah) something_else
Dann iteriert durch alle Maschinen, so etwas wie:
for box in box1_name box2_name box3_name do ssh $box 'commmands_to_run_everywhere' done
Um diese ssh Sache Arbeit zu machen, ohne Passwörter ganze Zeit eingeben, müssen Sie Key-Authentifizierung einzurichten. Sie können darüber lesen IBM developer .
Sie können auf einmal den gleichen Befehl auf mehreren Servern laufen mit einem Tool wie Cluster SSH . Die Verbindung ist zu einer Diskussion über Cluster ssh auf dem Debian-Paket des Tages Blog.
Nun, für den Schritt 1 und 2 ist nicht ein Kater-Manager Web-Interface; Sie könnten Skript, das mit curl oder zsh mit dem libwww Stecker in.
Für SSH Sie suchen nach:
1) nicht nach einem Passwort gefragt bekommen (mit den Tasten)
2) übergeben Sie den Befehl (e) auf SSH der Kommandozeile, das ist ähnlich in einem vertrauenswürdigen Netzwerk rsh
.
Andere Beiträge haben gezeigt, was zu tun, und ich würde wahrscheinlich sh
verwenden, aber ich würde versucht sein perl
wie ssh tomcatuser@server perl -e 'do-everything-on-one-line;'
zu verwenden, oder Sie können dies tun:
entweder scp the_package.tbz tomcatuser@server:the_place/.
ssh tomcatuser@server /bin/sh <<\EOF
definieren Sachen wie TOMCAT_WEBAPPS=/usr/local/share/tomcat/webapps
tar xj the_package.tbz
oder rsync rsync://repository/the_package_place
mv $TOMCAT_WEBAPPS/old_war $TOMCAT_WEBAPPS/old_war.old
mv $THE_PLACE/new_war $TOMCAT_WEBAPPS/new_war
touch $TOMCAT_WEBAPPS/new_war
[Sie normalerweise nicht haben tomcat neu starten]
mv $THE_PLACE/vhost_file $APACHE_VHOST_DIR/vhost_file
$APACHECTL restart
[Möglicherweise müssen als Apache-Benutzer anmelden, die Datei zu bewegen und neu starten]
EOF
Sie möchten DSH oder verteilte Schale, die in Clustern viel verwendet wird. Hier ist der Link: dsh
Sie haben grundsätzlich Knotengruppen (eine Datei mit Listen von Knoten in ihnen) und Sie angeben, welche Knotengruppe Sie möchten Befehle auszuführen auf dann würden Sie dsh verwenden, wie Sie Befehle auf ihnen laufen würde ssh.
dsh -a /path/to/some/command/or/script
Es wird den Befehl auf allen Rechnern gleichzeitig laufen und die Ausgabe mit dem Hostnamen als Präfix zurück. Der Befehl oder ein Skript hat auf dem System vorhanden sein, so dass ein gemeinsames NFS-Verzeichnis kann für diese Art von Dingen nützlich sein.
Erstellt Hostnamen ssh Befehl aller zugegriffen Maschinen. von Quierati http://pastebin.com/pddEQWq2
#Use in .bashrc
#Use "HashKnownHosts no" in ~/.ssh/config or /etc/ssh/ssh_config
# If known_hosts is encrypted and delete known_hosts
[ ! -d ~/bin ] && mkdir ~/bin
for host in `cut -d, -f1 ~/.ssh/known_hosts|cut -f1 -d " "`;
do
[ ! -s ~/bin/$host ] && echo ssh $host '$*' > ~/bin/$host
done
[ -d ~/bin ] && chmod -R 700 ~/bin
export PATH=$PATH:~/bin
Ex Ausführen:
$for i in hostname{1..10}; do $i who;done
Es gibt ein Tool FLATT (Flexible Automation und Fehlerbehebung Tool) genannt dass können Sie Skripts auf mehreren Unix / Linux auszuführen ein Klick auf eine Schaltfläche Hosts mit. Es ist eine Desktop-GUI-Anwendung, die auf Mac und Windows läuft, aber es gibt auch ein Kommandozeilen-Java-Client.
Sie können Batch-Jobs und Wiederverwendung auf mehrere Hosts erstellen.
Benötigt Java 1.6 oder höher.
Obwohl es ein komplexes Thema ist, kann ich sehr empfehlen Capistrano .
Ich bin nicht sicher, ob diese Methode für alles funktioniert, die Sie wollen, aber Sie können so etwas wie dies versuchen:
$ cat your_script.sh | ssh your_host bash
Welche wird das Skript ausführen (die lokal befindet) auf dem Remote-Server.
Multixterm ist cool, dies zu tun, und ermöglicht es Ihnen, bequem die 1 aus n setzen Maschine zurück in Abfolge.
Lesen Sie einfach ein neues Blog Verwendung setsid ohne weitere Installation / Konfiguration neben dem Mainstream-Kernel. Geprüft / Bestätigte unter Ubuntu14.04.
Während der Autor auch einen sehr klare Erklärung und Beispielcode hat, ist hier der Zauber Teil für einen schnellen Überblick:
#----------------------------------------------------------------------
# Create a temp script to echo the SSH password, used by SSH_ASKPASS
#----------------------------------------------------------------------
SSH_ASKPASS_SCRIPT=/tmp/ssh-askpass-script
cat > ${SSH_ASKPASS_SCRIPT} <<EOL
#!/bin/bash
echo "${PASS}"
EOL
chmod u+x ${SSH_ASKPASS_SCRIPT}
# Tell SSH to read in the output of the provided script as the password.
# We still have to use setsid to eliminate access to a terminal and thus avoid
# it ignoring this and asking for a password.
export SSH_ASKPASS=${SSH_ASKPASS_SCRIPT}
......
......
# Log in to the remote server and run the above command.
# The use of setsid is a part of the machinations to stop ssh
# prompting for a password.
setsid ssh ${SSH_OPTIONS} ${USER}@${SERVER} "ls -rlt"
Hier ist ein Skript einen SSH-Befehl auf mehreren Maschinen zu tun, kann es helfen:
#!/bin/bash
MACHINES="machine1 machine2 machine3 machine4 machine5 machine6"
for m in $MACHINES
do
cmd="ssh $m '$*'"
eval $cmd
done
Sie könnten auch diese setzen, so ist es in Ihrem Weg, nennen Sie es so etwas wie sshAll, dann geben Sie einfach sshAll Befehl.