$ wc -l /tmp/ossh.ips
21418 /tmp/ossh.ips
$ time ossh -n -h /tmp/ossh.ips -c uptime -p 1000 >/tmp/ossh.out
real 3m10.310s
user 0m30.970s
sys 0m19.282s
$ grep 'load average' /tmp/ossh.out | sort -n -k5 | tail -n1
10.23.91.97 [1] 13:37:55 up 828 days, 2:34, 0 users, load average: 8.29, 4.45, 3.90
$
In diesem Beispiel enthält die Datei /tmp/ossh.ips 21418 IP-Adressen von Computern. -n bedeutet, dass Sie keine umgekehrten Abfragen durchführen müssen, um den Namen anhand der Adresse zu bestimmen. -c Betriebszeit legt den Befehl fest, den ich ausführen möchte. -p 1000 erlaubt bis zu 1000 Verbindungen gleichzeitig. Wie Sie der Ausgabe entnehmen können, hat der Befehl ziemlich schnell funktioniert.
Was kann ossh noch tun?
$ ossh -?
Usage: ossh [-?AinPv] [-c COMMAND] [-C COMMAND_FILE] [-H HOST_STRING] [-h HOST_FILE] [-I FILTER] [-k PRIVATE_KEY] [-l USER] [-o PORT] [-p PARALLELISM] [-T TIMEOUT] [-t TIMEOUT] [parameters ...]
-?, --help Show help
-A, --askpass Prompt for a password for ssh connects
-c, --command=COMMAND
Command to run
-C, --command-file=COMMAND_FILE
file with commands to run
-H, --host=HOST_STRING
Add the given HOST_STRING to the list of hosts
-h, --hosts=HOST_FILE
Read hosts from file
-i, --ignore-failures
Ignore connection failures in the preconnect mode
-I, --inventory=FILTER
Use FILTER expression to select hosts from inventory
-k, --key=PRIVATE_KEY
Use this private key
-l, --user=USER Username for connections [$LOGNAME]
-n, --showip In the output show ips instead of names
-o, --port=PORT Port to connect to [22]
-p, --par=PARALLELISM
How many hosts to run simultaneously [512]
-P, --preconnect Connect to all hosts before running command
-T, --connect-timeout=TIMEOUT
Connect timeout in seconds [60]
-t, --timeout=TIMEOUT
Run timeout in seconds
-v, --verbose Verbose output
$
Die Liste der Hosts kann entweder direkt in der Befehlszeile mit der Option -H angegeben werden (bei mehreren Hosts müssen sie durch ein Leerzeichen getrennt sein und die gesamte Liste muss wie in den folgenden Beispielen in Anführungszeichen gesetzt werden) oder wird mit der Option -h aus einer Datei geladen. Zeilen, die in der Datei mit # beginnen, werden ignoriert. Die Adresse kann den Port enthalten: my.host:2222. Sie können die Klammererweiterung verwenden: "host {1,3..5} .com" wird zu "host1.com host3.com host4.com host5.com". Sowohl -H als auch -h können mehrfach verwendet werden.
Zur Autorisierung wird verwendet
- das Passwort, nach dem ossh fragt, wenn die Option -A verwendet wird
- SSH-Schalter angegeben durch Option -k
- ssh-agent (in diesem Fall muss die Umgebungsvariable SSH_AUTH_SOCK definiert sein)
In dieser Reihenfolge.
Manchmal müssen Sie sicherstellen, dass Sie sich bei allen Computern anmelden können, bevor Sie einen Befehl ausführen. Hierfür gibt es eine -P-Option. Wenn mindestens ein Computer nicht verfügbar ist, schlägt ossh standardmäßig fehl. Wenn Sie fehlgeschlagene Verbindungen ignorieren möchten, verwenden Sie die Option -i.
Ossh kann Ihr Inventarsystem verwenden. Dazu müssen die Pfade den Befehl ossh-inventar enthalten, an den die Parameter der Option -I übergeben werden. Diese Option kann mehrfach verwendet werden. Der Befehl ossh-inventar sollte Zeilen zur Standardausgabe im folgenden Format drucken:
_ _
Wobei machine_address entweder DNS-Name oder IP-Adresse sein kann.
Auszuführende Befehle werden durch die Optionen -C (aus Datei lesen) oder -c (aus der Befehlszeile übernehmen) angegeben. Diese Optionen können mehrfach verwendet werden. Wenn sowohl -C als auch -c vorhanden sind, werden Befehle aus Dateien zuerst und dann über die Befehlszeile ausgeführt.
Zusätzlich zur einfachen Ausführung von Befehlen mit ossh können Sie Protokolle in Echtzeit streamen:
$ ossh -H "web05 web06" -c "tail -f -c 0 /var/log/nginx/access.log|grep --line-buffered Wget"
web05 192.168.1.23 - - [22/Jun/2016:12:24:02 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)"
web05 192.168.1.49 - - [22/Jun/2016:12:24:07 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)"
web06 192.168.1.117 - - [22/Jun/2016:12:24:23 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)"
web05 192.168.1.29 - - [22/Jun/2016:12:24:30 -0700] "GET / HTTP/1.1" 200 1532 "-" "Wget/1.15 (linux-gnu)"
...
Hier ist eine fortlaufende Bereitstellungssimulation:
$ ossh -p 1 -H "test0{1..3}" -c "sleep 10 && date"
test01 Wed Jun 22 12:38:24 PDT 2016
test02 Wed Jun 22 12:38:34 PDT 2016
test03 Wed Jun 22 12:38:44 PDT 2016
$
Es ist ersichtlich, dass die Befehle nacheinander auf den Maschinen ausgeführt werden. Es ist jeweils nur eine Maschine beteiligt. Für eine echte Bereitstellung sollte "sleep 10 && date" beispielsweise durch "apt-get install -y your_package" ersetzt werden.
Für die Bereitstellung wurde die allererste Version von ossh geschrieben. Jemand wird fragen, warum ich kein allgemein akzeptiertes Konfigurationsmanagementsystem verwendet habe. Tatsache ist, dass es 2013 war und wir Koch verwendet haben. Es war klar, dass der Küchenchef nicht besonders mit der Ungewissheit zu uns passte, wann genau die Änderungen angewendet würden (der Küchenchef-Kunde wurde alle 30 Minuten ausgeführt). Um Änderungen auf vielen Computern konsequent einzuführen, verwendeten einige Entwickler einen Dirty-Hack: Der Chef-Client funktionierte nicht die ganze Zeit, sondern wurde nur einmal (über ssh) gestartet, wenn die Bereitstellung erforderlich war. Bereits zu diesem Zeitpunkt wurde daran gearbeitet, den Koch durch Salz zu ersetzen, aber der Übergang war nicht einfach und seine Fertigstellung erforderte zusätzliche Zeit. Wir haben einen neuen Service entwickelt,Dies erforderte häufige Bereitstellungen und wurde vom einzigen Debian-Paket eingeführt. Zuerst haben wir das Messer-Dienstprogramm des Küchenchefs verwendet. Mit diesem Dienstprogramm konnten Sie über ssh eine Verbindung zu den gewünschten Servern herstellen und Befehle auf diesen ausführen. Irgendwann wurde mir klar, dass der Koch in diesem Fall ein zusätzlicher Link ist, und ich schrieb Ossh.
Es ist wichtig zu beachten, dass ossh ein Werkzeug zur Lösung von großen und nicht standardmäßigen Problemen ist. Wenn die Notwendigkeit, ossh zu verwenden, häufig auftritt, ist dies ein Grund, darüber nachzudenken, ob Sie mit der Infrastruktur- und Serververwaltung gut zurechtkommen. Hier sind einige Situationen, in denen Ossh mir persönlich geholfen hat:
- Einmal habe ich /root/.ssh/authorized_keys auf einer großen Anzahl von Servern aufgeräumt (es gab zu dieser Zeit ungefähr 7000). Die Entwickler haben dort ihre Schlüssel registriert, insbesondere für die Aktualisierung ihrer Dienste. Es war notwendig, eine Liste aller auf allen Computern verwendeten Schlüssel zu erhalten und sicherzustellen, dass das Löschen dieser Schlüssel nicht katastrophal ist.
- Für schmerzlose Schaltsekunden
- Als wir mit TCP SACK PANIC zu kämpfen hatten , wurden die iptables-Regeln vom Konfigurationsmanagementsystem eingeführt. Um sicherzustellen, dass alles in Ordnung ist, habe ich mit ossh nach den richtigen Regeln gesucht. Und es war überhaupt nicht umsonst, es gab Autos, für die die Regeln nicht galten.
- Manchmal muss ich Testumgebungen mit Hunderten (und manchmal Tausenden) von Maschinen erstellen. Oft sind diese Maschinen vom Produktionsnetzwerk isoliert und für das Standardkonfigurationsmanagementsystem nicht verfügbar. In solchen Situationen kann die Maschinenkonfiguration mit ossh durchgeführt werden.
Ich sehe die Frage voraus, warum ich keine fertige Lösung verwendet habe. Wie oben erwähnt, kam mir 2013 erstmals die Notwendigkeit in den Sinn, Befehle auf Tausenden von Computern auszuführen. Zu dieser Zeit konnte ich nur paralleles SSH finden, was mir mit folgenden Punkten nicht zusagte:
- Ich konnte die Parallelität nicht über 150 erhöhen. Beim Herstellen einer Verbindung zu Remote-Servern traten Fehler auf
- parallel ssh hat die gesamte Ausgabe akkumuliert und nach Beendigung des Befehls ausgegeben. Das Streamen von Protokollen war mit seiner Hilfe beispielsweise nicht möglich
- Die parallele SSH-Ausgabe war (für mich persönlich) umständlich zu analysieren
Ursprünglich wurde Ossh in Rubin geschrieben, um die Leistung zu steigern. Ich habe die Event-Maschine und dann die Glasfaser verwendet. Ich habe vor kurzem Ossh umgeschrieben, um zu gehen. Ich wäre dankbar, wenn Go-Experten (ich bin im Moment nicht) einen Blick auf meinen Code werfen und mögliche Verbesserungsmöglichkeiten aufzeigen würden.