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:

Flavors des Clusters

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.

OpenStack-Netzwerkliste mit hervorgehobener ID des eodata-Netzwerks.

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.

Terminalausgabe mit den aus slurm-terraform.zip entpackten Dateien.

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 mit der Instanz worker001 und dem Flavor eo2a.large.

Terraform-Plan für die Instanz 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:

Ausgabe einer erfolgreichen Terraform-Ausführung mit der IP-Adresse des Controllers und der SSH-Konfiguration.

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.

SLURM listet worker001 und worker002 als idle auf, und srun gibt beide Hostnamen der Worker aus.

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 geben Shared home is ready aus, nachdem sie die Datei aus dem gemeinsam genutzten Home-Verzeichnis gelesen haben.

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.

Eine SLURM-Ressourcenzuweisung mit zwei Knoten führt mpirun aus und gibt MPI and boto3 are ready zweimal aus.

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-Details für worker001 mit dem Status IDLE, zwei CPUs und 6144 MiB konfiguriertem Arbeitsspeicher.

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:

Horizon-Seite Instances mit dem SLURM-Controller und zwei Workern im Status Active und Running.

Der laufende SLURM-Controller und die beiden Worker in Horizon.

Unter Volumes -> Volumes sehen Sie auch drei neue Volumes:

Horizon-Seite Volumes mit einem 50-GiB-Boot-Volume für den Controller und zwei 20-GiB-Boot-Volumes für die Worker.

Die Boot-Volumes des Controllers und der Worker in Horizon.

In der Netzwerktopologie ist ganz rechts das neue Netzwerk myslurmcluster-network hinzugekommen.

Horizon-Netzwerktopologie mit den SLURM-Knoten am Clusternetzwerk und an EODATA sowie dem mit dem externen Netzwerk verbundenen Clusterrouter.

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.

Still need help?
If this article does not answer all of your questions, the support team will help you.
Contact support