Containerisierung
Aus HPC@HU
Während im HPC-Bereich Software traditionnel direkt auf den Compute-Nodes ausgeführt wird, hat sich in den letzten Jahren auch die Nutzung eine Containerumgebung für bestimmte Anwendungsfâlle etabliert. Ein bekanntes Problem auf Compute-Clustern ist der Bedarf an einer neuerern glibc-Standardbibliothek welche durch Ihre tiefe Verwurzelung in Linux nicht ohne Weiteres angeboten werden kann. Die Containeriesrung kann es ermöglichen Software auszuführen welche sonst nicht gebaut werden kann oder nicht lauffähig ist.
Docker als bekannteste Conainerisierung ist hierbei im HPC aufgrund der Root-Rechte auf einem von Nutzern geteilten HPC Cluster problematisch. Darum wurde eine Containerisierung am Lawrence Berkeley National Laboratory Entwickelt welche nur im Userspace läuft, heute unter dem Namen Apptainer bekannt ( https://apptainer.org/ ) - diese bieten wir den Nutzern auf unseren Ressourcen an. (Anmerkung: das Projekt startete ursprünglich unter dem Namen Singularity, Apptainer ist mit Singularity. SingularityCE its ein alternativer Fork.)
Container für Apptainer können in Apptainer selbst gebaut werden, oder aber auch in Docker und dann konvertiert werden. Wer sich Container über die Docker-Route selbst bauen möchte, benötigt hierfür seinen eigenen Computer. Alternativ kann Apptainer auch Images direkt vom Docker-Hub herunterladen sofern ein Image zu VerFûgung steht.
Wichtig is hierbei dass die Umgebungsvariable APPTAINER_CACHEDIR
zum Einstellen des Cache-Ordners so gewählt wird, dass sich dieses auf dem Lustre-Dateisystem befindet. Zum Bespiel wie folgt:
export APPTAINER_CACHEDIR=/lustre/department/username/apptainer
Ein Minimales openSUSE 15.6 als glibc Overlay
Bei einem unserer Nutzer befindet sich ein minimales openSUSE 15.6 als Overlay im Testbetrieb um eine neuere glibc anzubieten.
Dazu wird ein Docker-Container mit openSUSE Leap 15.6 aufgesetzt, in welchem zusätlzich noch lua-lmod installiert wird. Letzteres wird benötigt um die Modules-Umgebung zu unterstützen. Wichtige Anmerkung, damit zypper korrekt funktioniert, benötigt es ein "clean" sowie "refresh". Dies ist mit dem folgenden Dockerfile möglich:
# syntax=docker/dockerfile:1 # use Leap as a basis to reduce differences FROM opensuse/leap:15.6 RUN zypper clean --all RUN zypper ref # the container needs to bring its own lmod along RUN zypper -n install lua-lmod RUN bash
Danach kann der Container mit docker build . -t opensuse-15.6
gebaut werden.
Ist der Docker-Container lokal aufgesetzt, kann dieser in eine Apptainer sif-Datei umgewandelt werden, und zwar wie folg: apptainer build opensuse-15.6.sif docker-daemon://opensuse-15.6:latest
Hier ist es wichtig entweder den Tag (fals vorhanden) oder :latest
anzugeben, sonst wird die Datei nicht erstellt.
Die nun erstellte Datei ist der Container welcher sich nun in einer HPC-Umgebung - mit Nutzerrechtne - verwenden lässt. In einer interaktiven Session würde der Container mit apptainer run opensuse-15.6.sif
ausgeführt. Dies ist an sich zuerst nicht besonders nützlich da nur das Home-Verzeichnis benutzbar ist. Allerdings können weitere Verzeichnisse über --bind
eingebunden werden, wodurch sich im Container die gleichen Pfade wie außerhalb nutzen lassen. Das wäre hier:
apptainer run --bind /lustre,/software opensuse-15.6.sif
Allerdings kann der Container dabei im Zweifelsfall nicht auf systemseitig angebotene Software oder Bibliotheken zugreifen. Diese lassen sich über einen Workaround ebenfalls einbinden. Der Pfad wird umgeschrieben und über die Umgebungsvariablen eingespielt. Hierbei ist es wichtig dass der Pfad zu der Systemsoftware ans Ende gehängt wird, denn die Pfade innerhalb des Containers sollen privilegiert werden.
Zum Beispiel liese sich der Container wie folgt starten:
apptainer run --bind /bin:/bin_base,/usr:/usr_base,/lustre,/software opensuse-15.6.sif
Und danach könne die Umgebungsvariablen mit den folgenden Befehelen gesetzt werden:
## add the base software back in via path: export PATH=$PATH:/usr_base/local/bin:/usr_base/bin:/bin_base ## ensure base OS libraries are included export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr_base/lib:/usr_base/lib64
Dies geht so natürlich nur in einer interaktiven Session.
Soll ein Job über SLURM eingereicht werden, so muss dies automatisch geschehen. Dazu kannn apptainer exec
genutzt werden. Es wird ein Bash-Script geschrieben welcher die Umgebungsvariablen exportiert (zum erweitern der Pfade) und benötigte Module lädt und dann eventuellen Code ausführt. Das Script muss hierbei ausführbar sein, woraus sich ein Aufruf wie folgt ergibt: apptainer exec --bind /bin:/bin_base,/usr:/usr_base,/lustre,/software opensuse-15.6.sif executable_script.sh
Ein minimaler Container mit openSUSE 15.6 ist unter /software/containers/opensuse-15.6.sif
verfügbar.
Bereitgestellte Container
Manche Programme werden von den Entwicklern bereits containerisiert angeboten. In diesem Fall sollte zuerst sichergestellt werden dass die Umgebungsvariable APPTAINER_CACHEDIR
gesetzt ist, idealerweise mit einem Verweis auf das Lustre wie folgt:
export APPTAINER_CACHEDIR=/lustre/department/username/apptainer
Viele Container werden als Docker-Image bereitgestellt und können direkt verwendet werden. Als Beispiel wird hier Reaction Mechanism Generator vom MIT genutzt.
Auf der Docker-Hub Seite des Projekts wird folgender Befehl für die Nutzung von Docker bereitgestellt: ( https://hub.docker.com/r/reactionmechanismgenerator/rmg )
docker pull reactionmechanismgenerator/rmg
Da wir Apptainer anbieten ist der Aufruf üb er die Befehlszeile nicht identisch, aber sehr ähnlich: ( https://apptainer.org/docs/user/main/cli/apptainer_pull.html )
apptainer pull docker://reactionmechanismgenerator/rmg