Überblick
Während Container einen bequemen Weg bieten, komplexe Anwendungen fertig verpackt zu nutzen, bergen die Container-Laufzeitumgebungen einige Möglichkeiten für Probleme.
Beispielsweise muss jeder Zugriff auf Dateien unserer clusterweiten Filesysteme pro Container eigens konfiguriert werden (durch Definition sog. „volumes“). Hinzu kommt, dass die meisten Container-Laufzeitumgebungen nicht (bzw. nicht gut) mit Netzwerk-Dateisystemen umgehen können (sowohl NFS als auch GPFS/SpectrumStorage, worauf unser Lichtenberg-Speicher basiert).
Außerdem ist es schwierig bis unmöglich, aus einem Container heraus auf unser Software-Modulsystem zuzugreifen.
„Über“-Containerisierung
In manchen Fällen enthält ein Container nur eine bestimmte Python-Interpreter-Version mit einigen (speziellen) Python-Modulen.
In solchen Fallen ist es einfacher, dafür mit denselben Modulen ein „python virtual environment“ aufzusetzen.
Viel leichter einzurichten und zu pflegen, arbeitet es außerdem perfekt mit den Cluster-Filesystemen und unserem Modulsystem zusammen.
Prüfen Sie daher Ihr gewünschtes Container-Rezept zuerst darauf, ob es wirklich sehr komplexe Abhängigkeiten elegant löst, oder nur solch ein „einfaches“ Setup beinhaltet!
Unterstützte Container-Laufzeitumgebungen
Auf dem Lichtenberg-Cluster unterstützen wir nur folgende CRIs:
Apptainer(früher Singularity)
Teilweise unterstützt und mit viel manuellem Aufwand unsererseits verbunden:
podman– benötigt manuelles Mapping von sub-UIDs und sub-GIDs, und arbeitet nicht gut mit Netzwerk- bzw. geteilten Dateisystemen zusammen
Nicht unterstützt wird
– benötigt erweiterte Rechte („dockerroot“-Zugriff)
Apptainer
Apptainer (früher Singularity) ist eine relativ leichtgewichtige und portable Container-Laufzeitumgebung. Weil mit explizitem Fokus auf HPC-Umgebungen entwickelt, läuft es verhältnismäßig gut auf Linux-Clustern und deren Netzwerk-Dateisystemen.
Aufsetzen
Um fertige Container-Abbilder im docker-Format (hier als Beispiel „lolcow“) in das apptainer-Format zu wandeln:
# Aus der „docker“-Registry:
mkdir -p myCont && cd myCont
singularity build lolcow.sif docker://godlovedc/lolcow
singularity run lolcow.sif
# Vom „docker“-Archive („podman pull“ only works if podman is correctly configured):
mkdir -p myCont && cd myCont
podman pull docker://godlovedc/lolcow
singularity build lolcow_from_archive.sif docker-archive://$(pwd)/lolcow_docker_archive.tar
singularity run lolcow_from_archive.sif
# Aus einem „docker“-File:
mkdir -p myCont && cd myCont
git clone https://github.com/GodloveD/lolcow
source myenv/bin/activate
spython recipe lolcow/Dockerfile ./sing.lolcow
singularity build --fakeroot lolcow_from_dockerfile.sif sing.lolcow
singularity run lolcow_from_dockerfile.sif
deactivate
Verwendung im Batch-Job
Um solche konvertierten apptainer in einem Batch-Job zu benutzen, brauchen Sie jetzt nur noch die zwei Zeilen
cd myCont
singularity run lolcow_from_dockerfile.sifin Ihr Jobscript aufzunehmen.
Beispiel mit NVidia GPUs
Es ist auch möglich, Container mit NVidia-GPUs zu verwenden (AMD und Intel haben derzeit noch Probleme):
# Wir fordern 2 Nvidia Hopper H100 GPUs für eine interaktive Nutzung an:
srun -t 07:00:00 -n16 --mem-per-cpu=4G --gres=gpu:h100:2 --pty /bin/bash
# Wir exportieren zwei Umgebungsvariablen für temporäre Dateien, um sicherzustellen, dass genügend Platz vorhanden ist:
export TMPDIR=${HPC_SCRATCH} APPTAINER_TMPDIR=${HPC_SCRATCH}
# Wir bauen ein Apptainer-Container-Image in die Datei "pytorch_cont.sif":
apptainer build pytorch_cont.sif docker://nvcr.io/nvidia/pytorch:25.03-py3
# Wir führen einen Container mit diesem Image aus:
apptainer shell --nv pytorch_cont.sif
# und testen es:
Apptainer> python
Python 3.12.3 (main, Feb 4 2025, 14:48:35) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> torch.cuda.is_available()
True
>>> torch.cuda.device_count()
2
>>> exit()