web-dev-qa-db-de.com

Wie führe ich viele SSH-Remote-Befehle auf mehreren Computern im Stapel aus?

Ich verwende SSH, um einige Befehle auf mehreren Remote-Computern in einer for-Schleife auszuführen. Es führt die gleichen Befehle für eine Liste von IP-Adressen aus. Einige der IP-Adressen sind möglicherweise nicht erreichbar, daher habe ich die Option ConnectTimeout verwendet.

Mein Skript funktionierte jedoch nicht so, wie ich es wollte. Tatsächlich blieb es bei der ersten nicht erreichbaren IP-Adresse hängen, anstatt aufzugeben und die nächste IP-Adresse auf meiner Liste auszuprobieren.

Hier ist der relevante Teil meines Skripts:

for ip in ${IP} ; do
    ssh  -o BatchMode=yes \
         -o StrictHostKeyChecking=no \
         -o ConnectTimeout=10 \
         -l ${USERNAME} \
         ${SCRIPT_Host} \
         "${COMMAND} -i $ip || echo timeout" \
         >> ./myscript.out
done

Es funktioniert einwandfrei für erreichbare IPs, aber wenn eine bestimmte IP nicht verfügbar ist, wartet sie eine Weile (viel mehr als 10 Sekunden, vielleicht 35 bis 40 Sekunden) und zeigt eine Fehlermeldung an mein Terminal an:

ERROR connecting : Connection timed out

Ich frage mich also, welche Option ich nicht richtig verwendet habe.

13
JavaRed

Ihre Verwendung von ConnectTimeout ist korrekt, daher ist es nicht offensichtlich, warum sie erst nach 30 oder mehr Sekunden abläuft.

So würde ich Ihr Skript ändern, um das Timeout-Problem vollständig zu vermeiden:

  • Verwenden Sie GNU parallel, um gleichzeitig mit mehreren Zielhosts zu verbinden.
  • Verwenden Sie die Option -f für SSH, um sie im Hintergrund zu verarbeiten.

Hier ist eine Lösung mit GNU parallel , die maximal 50 Verbindungen gleichzeitig ausführt:

parallel --gnu --bg --jobs 50 \
ssh -o BatchMode=yes \
    -o StrictHostKeyChecking=no \
    -o ConnectTimeout=10 \
    -l ${USERNAME} \
    {} \
    "${COMMAND} -i {} || echo timeout" \
::: ${IP}

parallel <command> ::: <arguments> führt <command> <argument> viele Male parallel aus, indem die <arguments>-Liste aufgeteilt wird. Der Platzhalter für <argument> ist {}.

Verwenden Sie parallel --jobs n, um die Anzahl der parallelen Verbindungen zu begrenzen.

15
Sigi

Das Zeitlimit für die Verbindung gilt, wenn Sie bereits eine Verbindung hergestellt haben und wenn die Verbindung für diese Zeitspanne in Sekunden inaktiv bleibt, dann wird die Verbindung getrennt. Dies bedeutet, wenn Sie den Parameter KEEP_ALIVE ssh nicht aktiviert haben, der eine Verbindung überhaupt verhindert im Leerlauf).

Der Grund, warum es mehr als 30 Sekunden dauert, bevor Sie eine Zeitüberschreitung erhalten, ist der interne Timer des Protokolls TCP, der versucht, für diese Zeit eine Verbindung herzustellen und die Fehlermeldung zurückzusenden, dass er keine Verbindung zum Sftp-Server herstellen kann. Es kommt nicht von ssh.

1
tsezane