Containerisierung

Aus HPC@HU

Wechseln zu: Navigation, Suche

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.

Beim bauen des Container, wird /tmp im RAM gemounted. Sollte der Container etwas größer sein, ist es möglich dass der vorhanden Platz nicht ausreicht, und das Bauen eines Apptainer-Containers dadurch fehlschlägt. In diesem Fall kann ein expliziter Pfad für /tmp über eine Umgebungsvariable gesetzt werden. Danach ist man nicht auf den verfügbaren oder zugewiesenen RAM beschränkt.

Dies sähe dann wie folgt aus:

APPTAINER_TMPDIR="/tmp" apptainer build opensuse-15.6.sif docker-daemon://opensuse-15.6:latest

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