Einen SLURM-Cluster mit Terraform erstellen
SLURM ist ein Open-Source-Job-Scheduler für Rechencluster. Sie reichen einen Job ein, der das auszuführende Programm sowie die benötigten CPUs, den Arbeitsspeicher, die Knoten und die Laufzeit beschreibt. SLURM stellt den Job in eine Warteschlange, bis Ressourcen verfügbar sind, startet ihn auf den zugewiesenen Knoten und verfolgt seinen Status.
Verwenden Sie SLURM für Aufgaben mit einem definierten Ende, beispielsweise zum Verarbeiten von Satellitenbildern, zum Ausführen von Simulationen oder für parallele Programme mit MPI (Message Passing Interface). Sie können viele Jobs einreichen und SLURM die Zuweisung der Ressourcen überlassen. So müssen Sie sich nicht auf einzelnen Workern anmelden, um Programme manuell zu starten.
Sowohl SLURM als auch Kubernetes verteilen Arbeitslasten auf die Knoten eines Clusters. Kubernetes verwaltet Anwendungen, die als Container bereitgestellt werden, darunter dauerhaft laufende Dienste und Batch-Jobs. SLURM konzentriert sich auf Rechenjobs in Warteschlangen und kann mehrere Knoten gemeinsam für einen parallelen Lauf zuweisen. In diesem Beispiel laufen die Programme direkt auf den virtuellen Maschinen und greifen über gemeinsam genutzten Speicher auf Dateien zu.
Dieser Artikel führt Sie vom Erstellen der virtuellen Maschinen auf OpenStack bis zum Einreichen Ihres ersten SLURM-Jobs. Terraform erstellt die Infrastruktur. cloud-init installiert und konfiguriert beim ersten Start SLURM, die MUNGE-Authentifizierung, Open MPI und den gemeinsam genutzten Speicher.
Das Beispiel erstellt myslurmcluster mit einem Controller und zwei Workern unter Ubuntu 24.04 LTS. Der Controller stellt auch den SSH-Zugang bereit und gibt sein Verzeichnis /home über NFS für die Worker frei. Die Jobs laufen auf den beiden Workern. SLURM stellt den Jobs auf jedem Worker zwei CPUs und 6 GiB RAM zur Verfügung.
Voraussetzungen
Nr. 1 Cloud-Konto und Projekt
Melden Sie sich bei Horizon unter https://identity.cloudferro.com/auth/realms/CODE-DE3/account/ an und wählen Sie das Projekt und die Region aus, in denen Sie den Cluster erstellen möchten.
Nr. 2 Terraform und OpenStack-Authentifizierung
Folgen Sie Generierung und Autorisierung von Terraform mit Keycloak auf CODE-DE-Lab, um Terraform zu installieren und sich für die OpenStack-CLI zu authentifizieren. Verwenden Sie Terraform 1.6 oder neuer aus der Versionsreihe 1.x. Lassen Sie die RC-Umgebung des Projekts in Ihrem lokalen Linux-Terminal aktiv. openstack flavor list muss die verfügbaren Flavors ausgeben.
Die folgenden Befehle verwenden dasselbe Terminal. Python 3, OpenSSH und unzip müssen ebenfalls lokal installiert sein. Führen Sie Terraform als normaler Benutzer aus.
Nr. 3 SSH-Schlüsselpaar
Bereiten Sie ein Schlüsselpaar vor, wie in Wie erstellt man ein Schlüsselpaar im OpenStack Dashboard? beschrieben. Bewahren Sie die öffentliche und die private Schlüsseldatei auf Ihrem lokalen Computer auf. Terraform importiert den öffentlichen Schlüssel in OpenStack; SSH verwendet den privaten Schlüssel.
Wenn Ihr privater Schlüssel durch eine Passphrase geschützt ist, laden Sie ihn mit ssh-add /path/to/private-key in Ihren SSH-Agenten, bevor Sie die Verbindungsprüfung in Schritt 4 ausführen.
Nr. 4 Image, Netzwerk und Quota
Verwenden Sie ein Cloud-Image von Ubuntu 24.04 LTS x86-64 mit diesen Flavors:
Rolle |
Instanzen |
Flavor |
vCPUs je Instanz |
RAM je Instanz (Horizon) |
|---|---|---|---|---|
Controller |
1 |
eo1a.medium |
2 |
4 GB |
Worker |
2 |
eo2a.large |
2 |
7.45 GB |
Terraform erstellt in Schritt 3 das private Netzwerk, das IPv4-Subnetz und den Router des Clusters. Der Router verbindet die Knoten zur Paketinstallation mit dem Internet. Terraform weist dem Controller außerdem eine Floating IP zu und verbindet sie mit ihm. Das vorhandene externe Netzwerk der Cloud wählen Sie in Schritt 2 aus.
Prüfen Sie die verfügbare Kapazität anhand von Dashboard-Übersicht - Projektkontingente und Flavors. Dieses Beispiel verwendet 3 Instanzen, 6 vCPUs, etwa 19 GB RAM und 3 Boot-Volumes mit insgesamt 90 GiB. Das 50-GiB-Volume des Controllers enthält auch die gemeinsam genutzten Home-Verzeichnisse. Jeder Worker verfügt über ein Boot-Volume mit 20 GiB.
Für das Netzwerk werden 1 privates Netzwerk, 1 Subnetz, 1 Router, 1 Floating IP und 2 Sicherheitsgruppen verwendet.
Nr. 5 EODATA-Netzwerk für den EO-Verarbeitungsworkflow
Suchen Sie für den privaten EODATA-Zugriff das vorhandene EODATA-Netzwerk in Ihrem Projekt. Führen Sie diesen Befehl in Ihrem lokalen Terminal aus, während die OpenStack-Sitzung aus Voraussetzung Nr. 2 aktiv ist:
openstack network list -c ID -c Name
Suchen Sie die Zeile mit dem Namen eodata oder einem Namen, der mit eodata_ beginnt. Kopieren Sie die ID, um sie in Schritt 2 für eodata_network_id zu verwenden. Terraform verbindet dieses Netzwerk beim Erstellen des Clusters mit dem Controller und beiden Workern.
Die ID des eodata-Netzwerks in der OpenStack-Netzwerkliste.
Konfigurieren Sie den EODATA-S3-Endpunkt und die Zugangsdaten später auf dem Controller im begleitenden EO-Verarbeitungsworkflow.
Schritt 1: Cluster-Konfiguration herunterladen
Laden Sie slurm-terraform.zip in Ihr lokales Arbeitsverzeichnis herunter und entpacken Sie das Archiv:
unzip slurm-terraform.zip
cd slurm-terraform
cp terraform.tfvars.example terraform.tfvars
Das Paket enthält die Terraform-Ressourcen, die cloud-init-Vorlage, die SLURM-Konfigurationsvorlage und zwei Einrichtungsskripte. Sie müssen nur terraform.tfvars bearbeiten.
Entpacken der Terraform-Konfigurationsdateien aus slurm-terraform.zip.
Schritt 2: Projektwerte festlegen
Führen Sie die folgenden Befehle auf Ihrem lokalen Computer in dem Terminal aus, in dem die OpenStack-Sitzung aus Voraussetzung Nr. 2 aktiv ist. Ermitteln Sie die Werte und tragen Sie sie anschließend wie unten gezeigt in terraform.tfvars ein.
ID des Ubuntu-Images ermitteln
Listen Sie die verfügbaren aktiven Images auf:
openstack image list --status active -c ID -c Name
Suchen Sie das Image Ubuntu 24.04 LTS x86-64 und kopieren Sie seine ID. Diese UUID ist der Wert für image_id. Ersetzen Sie damit UBUNTU_24_04_IMAGE_UUID in terraform.tfvars und behalten Sie die Anführungszeichen bei.
Namen des externen Netzwerks ermitteln
Listen Sie die externen Netzwerke auf:
openstack network list --external -c ID -c Name
Übernehmen Sie den Wert aus Name in external_network_name. Das Netzwerk in diesem Beispiel heißt external. Die Einstellung lautet daher:
external_network_name = "external"
Öffentliche IPv4-Adresse für SSH ermitteln
Führen Sie diesen Befehl auf Ihrem lokalen Computer über dieselbe Internet- oder VPN-Verbindung aus, die Sie für SSH verwenden werden:
curl -4 -fsS https://api.ipify.org
Der Befehl gibt die öffentliche IPv4-Adresse Ihrer Verbindung aus. Hängen Sie /32 an diese Adresse an und verwenden Sie das Ergebnis für ssh_cidr. Für die Beispieladresse 203.0.113.10 ergibt sich:
ssh_cidr = "203.0.113.10/32"
Ersetzen Sie 203.0.113.10 durch die Adresse, die Ihr Befehl ausgegeben hat. /32 erlaubt SSH-Zugriff von genau dieser einen öffentlichen IPv4-Adresse.
ID des EODATA-Netzwerks ermitteln
Geben Sie die UUID des in Voraussetzung Nr. 5 ermittelten eodata-Netzwerks aus:
openstack network show eodata -f value -c id
Kopieren Sie die ausgegebene UUID in eodata_network_id, zwischen die leeren Anführungszeichen in terraform.tfvars. Wenn der Netzwerkname mit eodata_ beginnt, ersetzen Sie eodata im Befehl durch den vollständigen Namen.
Lassen Sie eodata_network_id leer, wenn Sie einen Endpunkt verwenden, der über den Router des Clusters erreichbar ist.
Variablendatei bearbeiten
Öffnen Sie die Variablendatei im Verzeichnis slurm-terraform:
nano terraform.tfvars
Ersetzen Sie die Platzhalter in Großbuchstaben durch die zuvor ermittelten Werte und tragen Sie die kopierte Netzwerk-UUID in eodata_network_id ein:
# Replace the uppercase placeholders with values from your OpenStack project.
cluster_name = "myslurmcluster"
worker_count = 2
image_id = "UBUNTU_24_04_IMAGE_UUID"
controller_flavor_name = "eo1a.medium"
worker_flavor_name = "eo2a.large"
external_network_name = "EXTERNAL_NETWORK_NAME"
ssh_cidr = "YOUR_PUBLIC_IPV4/32"
ssh_public_key_path = "~/.ssh/id_ed25519.pub"
ssh_private_key_path = "~/.ssh/id_ed25519"
# Terraform creates the private network, subnet, and router.
subnet_cidr = "192.168.50.0/24"
dns_nameservers = ["1.1.1.1", "8.8.8.8"]
# Supply the network UUID when using the project's private EODATA endpoint.
eodata_network_id = ""
controller_disk_gb = 50
worker_disk_gb = 20
Behalten Sie controller_flavor_name = „eo1a.medium“, worker_flavor_name = „eo2a.large“ und worker_count = 2 bei. Setzen Sie die beiden Schlüsselpfade auf Ihre vorhandenen öffentlichen und privaten Schlüsseldateien.
Terraform erstellt ein privates Subnetz anhand von subnet_cidr. Der Standardwert ist 192.168.50.0/24. Verwenden Sie einen Bereich, der sich nicht mit dem EODATA-Netzwerk überschneidet. DHCP stellt den Knoten Adressen, eine Standardroute über den Router und die in dns_nameservers aufgeführten DNS-Server bereit.
Speichern Sie die Datei mit Ctrl+O, drücken Sie Enter und beenden Sie Nano mit Ctrl+X.
Schritt 3: Cluster erstellen
Fordern Sie über Ihre aktive OpenStack-Sitzung einen Token an und initialisieren Sie Terraform:
export OS_TOKEN="$(openstack token issue -f value -c id)"
terraform init
terraform validate
terraform plan -out=cluster.tfplan
Der Plan enthält Hunderte von Textzeilen wie diese:
Terraform-Plan für die Instanz worker001.
Terraform-Plan für das SSH-Schlüsselpaar und die Zuordnung der Floating IP zum Controller.
Terraform-Plan für den EODATA-Port von worker001.
Prüfen Sie den Plan und erstellen Sie anschließend die Ressourcen:
terraform apply cluster.tfplan
Terraform führt den Plan aus. Am Ende sollte diese Meldung erscheinen:
Terraform schließt die Erstellung der Ressourcen ab und zeigt die IP-Adresse des Controllers sowie die SSH-Konfiguration an.
Terraform erstellt myslurmcluster-network, myslurmcluster-subnet und myslurmcluster-router. Es verbindet das Subnetz mit dem Router und aktiviert den ausgehenden Internetzugriff über das ausgewählte externe Netzwerk, bevor die VMs gestartet werden.
Die drei VMs heißen myslurmcluster-controller001, myslurmcluster-worker001 und myslurmcluster-worker002. Der Controller erhält die Floating IP, die dieser Befehl ausgibt:
terraform output -raw controller_ip
Die Sicherheitsgruppen des Clusters erlauben die Kommunikation zwischen den Knoten sowie SSH-Zugriff auf den Controller aus ssh_cidr. Der Zugriff auf die Worker erfolgt über den Controller.
Schritt 4: Einrichtung abwarten und anmelden
Nachdem Terraform beendet ist, setzt cloud-init die Paketinstallation und die Konfiguration des Clusters fort. Führen Sie das mitgelieferte Skript aus, um auf den Abschluss der Einrichtung auf allen drei Knoten zu warten:
bash wait-for-cluster.sh
Das Skript erstellt außerdem ssh_config im Terraform-Verzeichnis. Verwenden Sie diese Datei, um sich als hpc auf dem Controller anzumelden:
ssh -F ./ssh_config myslurmcluster
Der Hostname des Controllers lautet controller001. Ihr Home-Verzeichnis /home/hpc wird gemeinsam mit allen Workern genutzt.
Schritt 5: Worker und gemeinsam genutzten Speicher prüfen
Führen Sie diese Befehle auf dem Controller aus:
sinfo -N -o '%N %P %t'
srun --nodes=2 --ntasks=2 --ntasks-per-node=1 hostname
Die Partition compute muss worker001 bis worker002 vor dem ersten Job mit dem Status idle auflisten. Der Befehl srun gibt die beiden Hostnamen der Worker aus, einen pro Task.
Beide Worker haben den Status idle und geben ihre Hostnamen zurück.
Erstellen Sie eine Datei in Ihrem Home-Verzeichnis und lesen Sie sie von beiden Workern aus:
printf 'Shared home is ready\n' > ~/shared-home-check.txt
srun --nodes=2 --ntasks=2 --ntasks-per-node=1 cat /home/hpc/shared-home-check.txt
Beide Worker lesen die Datei aus dem gemeinsam genutzten Home-Verzeichnis.
Die Meldung erscheint zweimal. Prüfen Sie MPI und boto3 mit mpirun innerhalb einer SLURM-Ressourcenzuweisung:
salloc --nodes=2 --ntasks=2 --ntasks-per-node=1 --time=00:05:00 \
mpirun -np 2 --map-by ppr:1:node \
/usr/bin/python3 -c 'from mpi4py import MPI; import boto3; print("MPI and boto3 are ready")'
Der Befehl gibt MPI and boto3 are ready einmal pro Worker aus. Der Cluster ist einsatzbereit, wenn alle drei Prüfungen erfolgreich sind.
Die Prüfung von MPI und boto3 ist auf beiden Workern erfolgreich.
Fehlerbehebung bei der Einrichtung
Wenn das Warteskript einen cloud-init-Fehler meldet, prüfen Sie den betroffenen Knoten von Ihrem lokalen Terraform-Verzeichnis aus. Für worker001 lautet der Befehl beispielsweise:
ssh -F ./ssh_config worker001 'sudo tail -n 80 /var/log/cloud-init-output.log'
Prüfen Sie bei einem Worker, der nicht den Status idle hat, seinen SLURM-Status auf dem Controller:
sinfo -R
scontrol show node worker001
SLURM-Konfiguration und aktueller Status von worker001.
Neue Instanzen in Horizon anzeigen
Die neuen Ressourcen lassen sich in verschiedenen Ansichten von Horizon anzeigen. Unter Compute -> Instances sehen Sie beispielsweise folgende Ausgabe:
Der laufende SLURM-Controller und die beiden Worker in Horizon.
Unter Volumes -> Volumes sehen Sie auch drei neue Volumes:
Die Boot-Volumes des Controllers und der Worker in Horizon.
In der Netzwerktopologie ist ganz rechts das neue Netzwerk myslurmcluster-network hinzugekommen.
Das Netzwerk, der Router und die EODATA-Verbindungen des SLURM-Clusters in Horizon.
Optional: Cluster entfernen
Kopieren Sie zuerst die Ergebnisse, die Sie behalten möchten, auf Ihren lokalen Computer. Beim Löschen dieses Clusters werden alle drei Instanzen und ihre Boot-Volumes gelöscht, einschließlich des gemeinsam genutzten Verzeichnisses /home auf dem Controller.
Beenden Sie die Sitzung auf dem Controller und führen Sie diese Befehle im lokalen Verzeichnis slurm-terraform aus, während die RC-Umgebung des Projekts aktiv ist:
export OS_TOKEN="$(openstack token issue -f value -c id)"
terraform destroy
Prüfen Sie die vorgeschlagenen Löschungen und geben Sie yes ein, um den Cluster zu entfernen.
Terraform entfernt außerdem das private Netzwerk, das Subnetz, den Router, die Floating IP und die Sicherheitsgruppen des Clusters. Das externe Netzwerk der Cloud und das vorhandene EODATA-Netzwerk bleiben verfügbar.
Hinweise zum Betrieb
Dieses Beispiel verwendet eine feste Anzahl von Workern und einen Controller. Es fügt keine Worker automatisch hinzu und bietet keine Ausfallsicherung für den Controller. Das gemeinsam genutzte Home-Verzeichnis liegt auf dem Boot-Volume des Controllers.
Bewahren Sie das Terraform-Verzeichnis und den darin gespeicherten Zustand auf, bis der Cluster entfernt wurde. Der Zustand enthält den MUNGE-Schlüssel des Clusters. Speichern Sie Zustandsdateien und gespeicherte Pläne geschützt und nehmen Sie sie nicht in die Versionsverwaltung auf. OpenStack-Token laufen ab. Fordern Sie vor einer späteren Terraform-Operation einen neuen Token an.
Nächste Schritte
Fahren Sie mit Beispiel-Workflow: MPI-Jobs zur EO-Verarbeitung auf einem SLURM-Cluster in der CODE-DE-Lab Cloud ausführen fort, um die Sentinel-2-Verarbeitung auf die beiden Worker zu verteilen.