Kommandos im Cluster ausführen

Kategorien: Linux

Nachdem der Cluster aus den ODROID-HC1 läuft (Docker-Cluster mit ODROID-HC1 aufbauen), geht es jetzt daran Kommandos auf den einzelnen Knoten auszuführen.

Nach dem Klonen und Anpassen der Rechnernamen ist der Cluster prinzipiell einsatzbereit. Allerdings nervt zum Beispiel das Herunterfahren des Clusters. Auf jedem Konten einloggen und mit sudo halt -p den Knoten herunterzufahren. Nicht gut.

SSH

Bei der Ausführung der Kommandos auf den Knoten nervt es ungemein, wenn man immer das Passwort eingeben muss. Außerdem ist die Anmeldung mit Passwort unsicherer. Kopieren wird also unseren öffentlichen SSH-Schlüssel auf die Knoten.

Das kann allerdings schon etwas nerven, weil man immer wieder ein sehr ähnliches Kommando (ssh-copy-id -i .ssh/id_rsa.pub admin@node-01) eingeben muss. Das kann man doch in der Shell automatisieren. Dazu kommen erst einmal die Benutzer und Knotennamen in die Datei cluster.txt.

cat <<EOF >~/cluster.txt
admin@node-01
admin@node-02
admin@node-03
admin@node-04
EOF

Mit for i in $( cat cluster.txt ); do ssh-copy-id -i ~/.ssh/id_rsa.pub $i; done kommen jetzt die Identitäten auf die einzelnen Knoten. Man muss einfach nur entsprechnd oft das Passwort des Benutzers admin auf den Knoten eingeben.

Parallele Ausführung von Kommandos auf den Knoten

Mit der Datei cluster.txt und der for-Schleife von oben, kann man bequem nacheinander Kommandos auf den Knoten nacheinander ausführen. Wenn jedes Kommando aber lange läuft, ist das auch nicht so toll. Ich will, dass die Kommandos nebenläufig auf allen Knoten ausgeführt wird. Dazu gibt es mehrere Möglichkeiten:

GNU Parallel

GNU Parallel gibt es als Paket für wahrscheinlich jede Linux-Distribution und kann deshalb schnell über den Paketmanager installiert werden. Seine Stärken liegen in der nebenläufigen Ausführung von Kommandos mit verschiedenen Argumenten und Kombinationen von Argumenten. Es kann aber auch das gleiche Kommando mit ssh auf verschiedenen Rechnern nebenläufig ausführen.

Da wir oben schon die Datei cluster.txt angelegt haben, können wir sie wiederverwenden und mit parallel --tag --sshloginfile cluster.txt --nonall uname -a testen, ob alle Knoten uname -a ausführen. Allerdings funktioniert das Ausführen von Kommandos mit sudo nicht. Dazu gibt es keine richtig saubere Lösung. Da es nur mein heimischer Cluster für Experimente ist, reicht es mit sudo visudo auf jedem Knoten die Option NOPASSWD bei der Gruppe sudo hinzuzufügen.

Jetzt noch ein kleines Skript anlegen, damit man nicht immer die ganzen Argumente angeben muss.

cat <<EOF >~/.local/bin/cluster
#!/bin/bash

parallel --tag --sshloginfile ~/cluster.txt --nonall \$*
EOF
chmod 755 ~/.local/bin/cluster

Jetzt kann ich mit cluster sudo halt -p bequem alle Knoten herunterfahren.

PSSH

Die Entwicklung von PSSH sieht eingeschlafen aus. Die originale Seite oben verweist auf eine Google Code Seite, die aber auch schon wieder eingeschlafen zu sein scheint. Nach der Installation mit pip vermisst pssh ein Modul version. Das ist ein Zeichen, dass es nicht unter Python 3 läuft. Also noch einmal deinstallieren und mit pip2 installieren und pssh startet.

Die Datei cluster.txt funktioniert auch mit pssh. Den Test von oben kann man mit pssh -h cluster.txt -P uname -a ausführen.

ParallelSSH

ParallelSSH läßt sich auch einfach mit pip installieren und scheint noch zu leben. Es ist allerdings “nur” ein Python-Modul. Die Kommandos muss man dabei Python-Skripten implementieren. Dafür ist es aber super flexibel und meiner Meinung nach leichter verständlich als Bash-Skripte.

Mit dem folgenden Skript als cluster.py gespeichert, kann man ebenfalls Kommandos auf allen Rechnern des Clusters ausführen.

from pssh.clients import ParallelSSHClient
import sys
import shlex

hostsfile = open("cluster.txt", "r")

hosts = [s.strip().split("@") for s in hostsfile.readlines()]
host_config = dict([(t[1], {'user': t[0]}) for t in hosts])
client = ParallelSSHClient(host_config.keys(), host_config=host_config)

command = " ".join([shlex.quote(i) for i in sys.argv[1:]])
output = client.run_command(command)

for host, host_output in output.items():
    for line in host_output.stdout:
        print("Host [%s] - %s" % (host, line))

Damit kann man die nebenläufige Ausführung mit python cluster.py uname -a testen. Das Skript verwendet wieder die Datei cluster.txt. Das macht das Skript etwas aufwendiger.

DSH

DSH ist uralt, könnte aber interessant im Vergleich sein. Ich werde es hier aber nicht ausprobieren.

Ansible

Ansible bietet deutlich mehr als ich hier haben wollte, aber man kann damit auch viele Rechner nebenläufig beauftragen. Hier will ich nur kurz zeigen, wie ich nebenläufig Kommandos auf meinem Cluster ablaufen lassen kann.

Die Datei mit den Rechnernamen muss anders aufgebaut sein als unsere gute alte cluster.txt. Diese Datei nennt Ansible “Inventory”. Normalerweise erwartet sie es in /etc/ansible/hosts. Ich lege es aber in ~.ansible/hosts an.

cat <<EOF >~/.ansible/hosts
node-01
node-02
node-03
node-04
EOF

Damit kann man schon ein Kommando auf allen Knoten ausführen lassen. Zum Beispiel:

ansible -i ~/.ansible/hosts all -u admin -a "uname -a"

Ansible kann noch viel mehr. Dazu muss man sogenannte Playbooks schreiben. Darauf will ich hier aber nicht eingehen.

Fazit

Es gibt noch Unmengen an Alternativen, die man (und auch ich) sich noch ansehen kann. Fabric ist ein weiteres Python-Modul, das ich mir nicht angesehen habe.

Vorerst bin ich mit GNU Parallel sehr zufrieden. Es ist zwar manchmal etwas spröde, wenn man etwas Bestimmtes erreichen möchte. Zum Beispiel habe ich aufgegeben, die SSD damit mit bonnie zu messen. Mit der for-Schleife in der Shell lassen sich nicht zu lange dauernde Kommandos auf allen Knoten nacheinander ausführen. Damit habe ich auch meinen Benchmark durchgeführt. Hat zwar etwas gedauert, war aber einfach zu implementieren.

PSSH funktioniert ordentlich. Ich werde aber keine Arbeit hineinstecken, da es schon lange nicht mehr gepflegt wird. DSH habe ich mir deshalb erst gar nicht genauer angesehen.

Ansible ist ein etabliertes, modernes Werkzeug zur Automatisierung von Administrationsaufgaben. Ich denke, es lohnt sich hier einiges an Lernaufwand zu investieren.

ParallelSSH finde ich sehr interessant. Mein kleines Skript muss noch erweitert werden, aber dann bietet es die besten Möglichkeiten ohne zu viel in ein neues Werkzeug zu investieren.

Das könnte Sie auch interessieren