1. Singularity utilisation

Singularity va nous permettre de faire tourner des logiciels sur le cluster à partir de conteneurs. Ces conteneurs peuvent être importés depuis docker ou fabriqués directement avec singularity. Un conteneur est une sorte de machine virtuelle très allégée qui aurait un isolement plus faible.

Alt text

L'aspect construction doit se faire sur votre machine personnelle ou dans une machine virtuelle dans laquelle vous avez des droits sudo/root. En effet, l'étape de build nécessite des droits élevés. Il faut donc au préalable installer singularity (ou en v2.6 pour meso@lr par exemple) sur votre machine ou VM.

Le build va ensuite se faire à partir d'une recette. Il est également possible de faire des pull (sorte de téléchargement) directement et d'utiliser directement ces conteneurs (hébergés sur des registres d'image comme le singularity-hub ou DockerHub...).

Les recettes Singularity sont composés d'un en-tête puis de sections : Les contenu des sections s'exprime en bash.

Exemple (depuis la documentation Singularity) :

Bootstrap: docker
From: ubuntu:16.04


%post
    apt-get -y update
    apt-get -y install fortune cowsay lolcat


%environment
    export LC_ALL=C
    export PATH=/usr/games:$PATH


%runscript
    fortune | cowsay | lolcat

Construction de l'image depuis la recette :

$ sudo singularity build lolcow.simg Singularity

Plus d'informations sur les sections, recettes.

Pour lancer ce conteneur, il suffira de faire :

singularity run lolcow.simg

Mais il est possible, depuis l'hôte, de lancer n'importe quel programme présent dans le conteneur :

# ici le programme "cat"
singularity exec lolcow.img cat /etc/os-release

Lorsque vous avez fini la construction de votre image, copiez la sur le cluster puis essayez de l'exécuter ou de faire un singularity shell dedans.

Si vous avez besoin d'accéder à un dossier de l'hôte, en dehors de votre $HOME et du /tmp, vous pouvez monter ce dossier (on parle de bind mount) dans votre conteneur, avec l'option -B :

cd /tmp
singularity shell -B /opt/gridengine:/opt/gridengine ubuntu_16.04.sif
> Singularity ubuntu_16.04.sif:/tmp> ls -l /opt/gridengine
> ...

L'équipe MBB met à votre disposition 2 applications pour générer des recettes :

Certaines images sont déjà disponibles dans /share/apps/sing-images/$SINGULARITY_VERSION. Si vous pensez que votre image peut être utile à d'autres personnes et que vous souhaitez la partager, n'hésitez pas à nous en faire part et nous la rajouterons !

L'exécution sur le cluster est aisée, le $HOME et le TMP sont montés par défaut dans votre conteneur et l'utilisateur dans le conteneur est le même que sur l'hôte. Un modulefiles vous permet de charger singularity (voir utilisation de module).

Un petit exemple basique d'un fichier de soumission SGE/singularity serait (après avoir chargé le module singularity) :

#$ -S /bin/bash
#$ -N Singularity_Job
#$ -q cemeb.q
#$ -l h_rt=10:00:00
#$ -cwd
#$ -V

singularity exec myfirstimage.simg myprog --myargs > myoutputfile.out

2. TP singularity avance

Voici un TP assez avancé que j'avais fait dans le cadre de l'ANF UST4HPC, en version 2.4.6 : https://mbb.univ-montp2.fr/ust4hpc/tpSingu.html

3. bugs connus

Si vous avez le message suivant :

FATAL: kernel too old

Essayez de changer l'image de départ de votre conteneur pour un noyau linux plus ancien.

Par exemple, si vous faites, dans votre recette, un From: ubuntu:18.04, essayez de le remplacer par From: ubuntu:16.04.

4. Rajouts classiques spécifiques au Cluster MBB et au Cluster ISEM

De manière générale, je vous conseille de rajouter le contenu suivant à votre section %post :

  # Specific Cluster config
  mkdir -p /share/apps/bin
  mkdir /share/apps/lib
  mkdir /share/apps/gridengine
  mkdir /share/bio
  mkdir -p /opt/gridengine
  mkdir -p /export/scrach
  mkdir -p /usr/lib64
  /usr/sbin/groupadd --system --gid 400 sge
  /usr/sbin/useradd --system --uid 400 --gid 400 -c GridEngine --shell /bin/true --home /opt/gridengine sge
  ln -s /bin/bash /bin/mbb_bash
  ln -s /bin/bash /bin/isem_bash

En effet, par défaut, je rajoute automatiquement (dans la configuration générale de singularity.conf), les bind mount suivant (en plus du /tmp et du $HOME):

bind path = /share/apps/bin
bind path = /share/apps/lib
bind path = /export/scrach
bind path = /opt/gridengine

4.1. OpenMPI

Par ailleurs, si vous souhaitez utiliser MPI, il faudra utiliser la même version que celle sur le cluster (toujours en %post) :

  cd /usr/local
  ## MPI stuffs (installing the same OpenMPI version that the one on the nodes)
  wget -O /tmp/openmpi-1.6.2.tar.gz https://www.open-mpi.org/software/ompi/v1.6/downloads/openmpi-1.6.2.tar.bz2
  tar -xf /tmp/openmpi-1.6.2.tar.gz
  cd openmpi-1.6.2
  ./configure --prefix=/usr/local --enable-static
  make -j4
  make install

5. Utilisation sur le cluster meso@lr

Merci à Rémi Allio pour ses tests et ses notes

Comme dans beaucoup de cluster, vous ne disposez pas de droit élevés sur le cluster Meso@LR. Sous ces conditions, la création d’une image singularity peut s’avérer cruciale.

Comme expliqué précédemment, pour créer cette image vous nécessitez des droits administrateur et vous devez donc la construire depuis votre machine.

Quelques petits conseils pour le cluster Meso@LR :

Le cluster monte de nombreux dossiers par nfs et ainsi, lorsque vous soumettez un job sur un nœud (via un fichier (s)batch par example), le chemin d’accès à vos fichiers est changé. Ainsi, au lieu d’être /home/$USER/, le vrai chemin sera /nfs/home/$USER/.

Ainsi, lors de la création de votre recette (spécifiquement pour Meso@LR) il sera utile d’ajouter la ligne suivante dans la section %post :

# remplacer $USER par votre username sur le cluster
mkdir -p /nfs/home/$USER/

Cette commande vous permet de créer un chemin dans votre container qui est équivalent à celui du cluster. Ensuite, lors du chargement de singularity sur votre nœud de calcul, il faudra lier le chemin du nœud au chemin du container. Pour cela il faudra effectuer la commande suivante :

singularity exec -B /nfs/home/$USER/:/nfs/home/$USER/ mon_image.img

De cette manière, les fichiers dans le container auront les mêmes chemins que dans le nœud de calcul (i.e. même chemin que dans votre home avec /nfs/ en plus).

Pour finir, par défaut les dossiers $HOME, /tmp, /proc, /sys, /dev sont montés lors du chargement de singularity. Cependant, lorsque singularity est chargé depuis un nœud de calcul, le $HOME considéré est /home/$USER/. Malheureusement, depuis le nœud de calcul, vous ne disposez pas des droits sur ce HOME depuis le nœud de calcul. L’erreur suivante va donc stopper votre job :

ERROR  : Home directory is not owned by calling user: /home/$USER

Pour pallier cette erreur, lors du chargement de singularity dans le nœud de calcul, il faut préciser le chemin du HOME à considerer comme ceci :

singularity exec --home /nfs/home/$USER:/home/$USER  -B /nfs/home/$USER/:/nfs/home/$USER/  mon_image.img

En effet, /home/$USER sur le noeud est un lien symbolique et nécessite l'existence du dossier cible /nfs/home/$USER, contenant vos fichiers, à créer et à monter dans le conteneur.

6. Ressources