Singularity¶
Description¶
Un conteneur Linux est une image qui contient votre propre environnement logiciel et qui partage le noyau Linux avec l'hôte.
Singularity est une solution de conteneur conçue pour le HPC qui permet la portabilité entre environnements Linux, la reproductibilité des résultats et la mobilité entre clusters.
Les utilisateurs font alors tourner un autre système d'exploitation dont ils peuvent contrôler la pile logiciels sans avoir besoin des privilèges root sur la machine hôte.
Singularity est installé sur Curta (module load singularity/latest
), ce qui permet de lancer à l'intérieur d'un job, un conteneur à l'environnement logiciel contrôlé.
Faire tourner des conteneurs sur des serveurs auxquels ont accès d'autres utilisateurs pose des problèmes de sécurité que les développeurs de Singularity ont pris soin de résoudre. Ainsi, il est interdit d'obtenir des privilèges administratifs dans un conteneur Singularity si on n'est pas root sur l'hôte. Ceci oblige l'utilisateur qui veut personnaliser son image de conteneur à le faire sur une machine Linux où il dispose de tels privilèges.
La procédure qui suit détaille les étapes pour configurer une image et utiliser des conteneurs dans vos jobs Curta.
Procédure¶
Documentation Singularity: https://www.sylabs.io/guides/3.0/user-guide/index.html
- Pour créer un conteneur il faut une image (.sif) et un fichier de définition (.def) ainsi qu'un ordinateur où vous avez les droits root pour pouvoir exécuter la commande build. Une fois configurée, il faut la copier sur Curta pour l'utiliser dans un job.
- Installation de Singularity sur votre ordinateur dans la même version que sur Curta (actuellement: 3.8.0-rc.2)
Documentation: https://www.sylabs.io/guides/3.0/user-guide/installation.html
NOTE: Pour des raisons de sécurité, ce logiciel est maintenu à jour.
- Pour définir vos besoins dans le conteneur, il faut écrire un fichier de recette (
container.def
). Voici un exemple d'installation minimale d'un conteneur ubuntu:BootStrap: debootstrap OSVersion: trusty MirrorURL: http://us.archive.ubuntu.com/ubuntu/ %runscript echo "This is what happens when you run the container..." %post echo "Hello from inside the container" sed -i 's/$/ universe/' /etc/apt/sources.list apt-get update apt-get -y install vim apt-get clean mkdir /scratch
Ensuite, on crée l'image<container.sif>
comme suit (cette opération peut prendre un certain temps):sudo singularity build <container.sif> <container.def>
D'autres méthodes sont possibles pour construire son conteneur. Vous avez le détail ici: https://www.sylabs.io/guides/3.0/user-guide/build_a_container.html
- Transférez votre image dans /scratch/<username> sur Curta. Attention cet espace est nettoyé au bout de 90 jours donc il faut garder une copie de votre image ailleurs.
- Maintenant l'utilisation du conteneur dans un job est possible.
Pour exécuter vos scripts dans le conteneur, il faudra utiliser la commande exec:singularity exec <container.sif> <CMD> (args)
Si vous avez lancé un job interactif, vous avez la possibilité d'ouvrir un shell dans le conteneur:singularity shell <container.sif>
- S'il vous manque un paquet dans votre conteneur, il faudra modifier votre conteneur sur votre ordinateur où vous avez les droits root, modifier le conteneur comme suit et retransférer l'image sur le scratch de Curta:
sudo singularity shell -w <container.sif> Singularity centos7.sif:~> yum install <package>
Singularity + GPU¶
Pour utiliser des GPU depuis un conteneur Singularity, il faut utiliser l'option --nv de Singularity.
Exemples d'utilisation¶
OpenMPI¶
Pour que vos jobs s'exécutent correctement, il faut installer dans le conteneur une version de openmpi qui soit également installée en module sur Curta (et charger ce module-ci dans votre job).
- Fichier de définition openmpi.def
Bootstrap: yum OSVersion: 7 MirrorURL: http://mirror.centos.org/centos-%{OSVERSION}/%{OSVERSION}/os/$basearch/ Include: yum %post echo "Hello from inside the container" echo "Installing Development Tools YUM group" yum -y groupinstall "Development Tools" yum -y install wget which less nano emacs mkdir /scratch mkdir /tmp/mpi cd /tmp/mpi echo "Installing OpenMPI into container..." wget https://download.open-mpi.org/release/open-mpi/v3.1/openmpi-3.1.3.tar.gz tar xvzf openmpi-3.1.3.tar.gz cd openmpi-3.1.3 ./configure --prefix=/usr/local make make install /usr/local/bin/mpicc examples/ring_c.c -o /usr/bin/mpi_ring cd / rm -rf /tmp/mpi exit 0
- Job SLURM
Pour un bon fonctionnement de openmpi:- Il faut charger la même version openmpi que celle installée dans le conteneur.
- Une façon de procéder est de compiler le programme dans le conteneur avant de l'exécuter (mpirun/mpiexec).
#!/bin/bash # #SBATCH -J singularity_openmpi #SBATCH -o /scratch/aldarrie/singularity/%x-%j.out #SBATCH -N 3 #SBATCH --ntasks-per-node=4 #SBATCH -t 10:00 echo "#############################" echo "User:" $USER echo "Date:" `date` echo "Host:" `hostname` echo "Directory:" `pwd` echo "SLURM_JOB_NAME:" $SLURM_JOB_NAME echo "SLURM_JOB_ID:" $SLURM_JOB_ID echo "SLURM_NODELIST: " $SLURM_NODELIST echo "SLURM_NTASKS: " $SLURM_NTASKS echo "#############################" echo IMG=/scratch/aldarrie/singularity/openmpi.sif module load singularity/latest module load mpi/openmpi/3.1.3 echo "OpenMPI" NP=$SLURM_NTASKS echo "Running on $NP processors" mpiexec -pernode singularity exec $IMG mpicc mpitest.c -o mpitest mpirun -np $NP singularity exec $IMG ./mpitest echo "Job finished"
R¶
- Fichier de définition
BootStrap: debootstrap OSVersion: trusty MirrorURL: http://us.archive.ubuntu.com/ubuntu/ %runscript echo "This is what happens when you run the container..." %post echo "Hello from inside the container" sed -i 's/$/ universe/' /etc/apt/sources.list apt-get update apt-get -y install vim apt-get install -y r-base r-base-core r-base-dev wget vim git nano git cmake curl wget python autoconf bzip2 libtool python-pip python-dev glpk-utils libglpk-dev glpk-doc python-glpk apt-get clean mkdir /scratch %test #!/bin/sh exec R --slave -e 'print("Hello Worl!")' %runscript glpsol -m sudoku.mod
- Job SLURM
#!/bin/bash # #SBATCH -J singularity_R #SBATCH -o /scratch/aldarrie/singularity/%x-%j.out #SBATCH -N 1 #SBATCH --ntasks-per-node=1 #SBATCH -t 10:00 echo "#############################" echo "User:" $USER echo "Date:" `date` echo "Host:" `hostname` echo "Directory:" `pwd` echo "SLURM_JOB_NAME:" $SLURM_JOB_NAME echo "SLURM_JOB_ID:" $SLURM_JOB_ID echo "SLURM_NODELIST: " $SLURM_NODELIST echo "SLURM_NTASKS: " $SLURM_NTASKS echo "#############################" echo IMG=/scratch/aldarrie/singularity/r.sif module load singularity/latest ###module load R/3.5.0 cp $IMG $TMPDIR cp sudoku.mod $TMPDIR echo "R sudoku program" singularity test $TMPDIR/r.sif singularity run $TMPDIR/r.sif echo "Job finished"