Singularity

From CC Doc
Jump to navigation Jump to search
This page is a translated version of the page Singularity and the translation is 84% complete.
Outdated translations are marked like this.
Other languages:
English • ‎français

Généralités

Singularity[1] est un logiciel libre (open source) créé par Berkeley Lab pour

  • utiliser de façon sécuritaire des conteneurs Linux sur des grappes Linux multiutilisateur;
  • donner aux utilisateurs le plein contrôle de leur environnement;
  • créer des paquets de logiciels scientifiques et les déployer sur des grappes différentes de même architecture.

Singularity permet la virtualisation du système d’exploitation sous la forme de conteneurs.

À la différence d’une instance (virtual machine), un conteneur

  • exige possiblement moins de ressources;
  • peut seulement exécuter des programmes conçus pour le même noyau (ici Linux) avec une même architecture matérielle.

Une instance peut exécuter plus d’un système d’exploitation et peut quelquefois servir à exécuter des programmes conçus pour des architectures CPU différentes.

Les conteneurs font usage des fonctionnalités Linux

  • cgroups pour limiter, contrôler et isoler l’utilisation des ressources (par exemple la mémoire vive, les disques I/O, l’accès au CPU);
  • kernel namespaces pour virtualiser et isoler les ressources du système d’exploitation d’un groupe de processus (par exemple les processus et les identifiants d’utilisateurs, les systèmes de fichiers, l’accès au réseau);
  • systèmes de fichiers Overlay pour donner l’apparence d’opérations d’écriture dans des systèmes de fichiers à lecture seule.

Contrairement à d’autres solutions de conteneurs comme Docker[2], Singularity permet d’utiliser les conteneurs de façon sécuritaire, particulièrement avec les grappes de calcul multiutilisateur.[3]

Disponibilité

Singularity est disponible sur les grappes de Calcul Canada.

Si vous voulez utiliser Singularity sur votre propre ordinateur, consultez la documentation d’installation [4]. Vous devriez disposer d’une distribution Linux relativement récente (noyau de v3 10.0 ou plus).

Utilisation sur les grappes de Calcul Canada

Charger un module

Chargez d’abord le module que vous voulez utiliser, par exemple

$ module load singularity/2.5

Voyez les modules disponibles avec

$ module spider singularity

Créer des images

Avant d’utiliser Singularity, vous devez créer une image (un conteneur). Cette image est soit un fichier, soit un répertoire dans lequel Linux est installé. Pour créer une image, utilisez la commande singularity build, soit

  • singularity build WHAT-TO-WRITE SPECIAL-URI-OR-PATH

WHAT-TO-WRITE peut être

  • le nom du fichier de l'image Singularity (*.sif) où l'image construite sera écrite
  • un répertoire si vous construisez un bac à sable avec l'option --sandbox, généralement sur votre propre ordinateur Linux (avec un compte d'accès root)

et SPECIAL-URI-OR-PATH peut être

  • une adresse URI commençant par library:// pour construire à partir d'une bibliothèque de conteneurs,
  • une adresse URI commençant par docker:// pour construire à partir de Docker Hub,
  • une adresse URI commençant par shub:// pour construire à partir de Singularity Hub,
  • un chemin vers un conteneur existant,
  • un chemin vers un répertoire pour construire à partir d'un bac à sable,
  • un chemin vers un fichier de l'image Singularity (qui est une recette pour construire l'image).

Avertissement

Il est fortement recommandé de créer les images Singularity sur un ordinateur ou une instance

  • dont le système d'exploitation est Linux,
  • où Singularity est installé,
  • avec un accès à l'internet,
  • de préférence où vous êtes utilisateur racine (root), soit avec les permissions sudo.

Sans permissions sudo, sachez que toutes les permissions (de l'utilisateur et du groupe) pour l'image que vous créez deviendront celles définies pour le compte à partir duquel l'image a été créée. De façon générale, il est difficile de revenir aux permissions qu'il faut et donc, dépendant du contenu de l'image, il pourrait être impossible de la mettre à jour par la suite.

Par exemple, les commandes pour les images Debian et Ubuntu dpkg, apt-get et apt exigent les permissions root pour installer et mettre à jour des paquets. Si vous prévoyez devoir éventuellement installer ou mettre à jour des logiciels, créez votre image dans un système Linux où vous avez les permissions root.

Remarque : les images créées sur votre ordinateur personnel doivent être téléchargées sur la grappe pour que vous puissiez les utiliser.

Erreur de build avec une distribution Linux

Avec certaines distributions, vous pourriez recevoir cette erreur même si la mémoire est suffisante.

$ WARNING: 'nodev' mount option set on /tmp, it could be a source of failure during build process
$FATAL: no memory left on device

Many modern Linux distributions, use an in-memory tmpfs filesystem, which may limit the size of the container you can build. The Singularity Documentation gives a more detailed explanation.

If that is the case, you can solve the problem by setting SINGULARITY_TMPDIR to a disk location.

$ SINGULARITY_TMPDIR="disk/location" singularity build IMAGE_NAME.sif docker://DOCKER-IMAGE-NAME

Créer une image sur une grappe de Calcul Canada

Puisqu'il vous est impossible d'avoir les permissions sudo sur nos grappes, prenez connaissance de l'avertissement au paragraphe précédent. Les images peuvent être créées sur toutes les grappes de Calcul Canada et sur les ordinateurs pour la visualisation (gra-vdi.computecanada.ca en date de février 2020). Veuillez tenir compte des particularités suivantes :

  • sur beluga.computecanada.ca, connectez-vous avec SSH et utilisez un nœud de connexion pour créer vos images;
  • sur cedar.computecanada.ca, connectez-vous avec SSH et créez vos images avec une tâche interactive; n'utilisez pas un nœud de connexion;
  • sur graham.computecanada.ca, connectez-vous avec SSH et utilisez un nœud de connexion pour créer vos images;
  • sur gra-vdi.computecanada.ca, connectez-vous avec VNC et utilisez une fenêtre de terminal pour créer vos images;
  • sur niagara.computecanada.ca, connectez-vous avec SSH et utilisez un nœud de connexion pour créer vos images;
    • IMPORTANT : Ne créez pas de lien avec /localscratch qui n'existe pas sur Niagara.

L'option à privilégier est d'utiliser gra-vdi.computecanada.ca. Dans les autres cas, nous observons les difficultés suivantes :

  • beluga, graham et niagara
    • il y a un maximum de mémoire RAM pouvant être utilisé avec les nœuds de connexion et
    • pas d'accès à l'internet avec les nœuds de calcul.
  • cedar:
    • les nœuds de connexion ne peuvent pas être utilisés et
    • comme il est très difficile de prévoir combien de mémoire RAM est nécessaire avec les nœuds de calcul, une erreur pourrait survenir; si c'est le cas, quittez la tâche interactive et essayez de nouveau avec plus de mémoire.

Créer une image avec DockerHub et Dockerfile

Le site Docker offre une interface de recherche pour identifier des images.

Si par exemple l’URL du conteneur est docker://ubuntu, téléchargez le conteneur avec

$ singularity build myubuntuimage.sif docker://ubuntu

This command will work on a Cedar compute node but not on Béluga or Graham, where compute nodes can not access the internet. We don't recommend building large Singularity images on login nodes because this process will affect other users and likely fail due to the high CPU and RAM usage. The following two-step process can solve the problem.

  1. Download a Docker image without converting it to Singularity. The download-frozen-image tool from the Moby Project can be used to do this. This step is not computationally intensive and can be done on any data transfer or login node.
  2. Convert the downloaded Docker image to Singularity image. This step is computationally intensive and so should be done on a compute node with a suitable allocation of memory and CPU.

As an example, let's download and build a Singularity image for the package GQCP.

On a data transfer node or a login node download the Docker image:

$ cd ~/scratch
$ wget https://raw.githubusercontent.com/moby/moby/master/contrib/download-frozen-image-v2.sh
$ sh download-frozen-image-v2.sh gqcp gqcg/gqcp:latest
$ cd gqcp && tar cf ../gqcp.tar * && cd ..

Start an interactive job:

$ cd ~/scratch
$ salloc --mem-per-cpu=2000 --cpus-per-task=4 --time=2:0:0

On the allocated compute node, build the Singularity image:

$ module load singularity
$ singularity build gqcp.sif docker-archive://gqcp.tar

One can also use a Dockerfile to create Singularity images, but this is a two step process.

  • The first step is to create a Docker image with the Dockerfile. This step should be executed on your VM or Linux machine, where you have sudo access. Go to the directory which contains the Dockerfile and run the command sudo docker build -t CC:latest .. By passing '.' as a parameter we are asking Docker to search for the Dockerfile in the current directory. This command will create a Docker image with the name CC and assign the image a tag with the value latest. Remember that latest is the default tag that Docker assigns to an image, so if you don't provide a tag, the image will use the default tag value latest.
  • The second step is to use the Docker image created above as the source for Singularity. The following command will create a Singularity image cc_image_latest.sif from the Docker image CC:latest,
sudo singularity build cc_image_latest.sif docker-daemon://CC:latest

You don't need to provide a path to the Docker image as the Docker daemon will automatically pick the image specified though the Docker registry, but we have to ensure that we use the correct image name and tag value.

Creating a custom image with sandbox

The --sandbox flag allows you to create a container within a writable directory. this allows for easy modifications of existing containers.

$ singularity build --sandbox IMAGE_NAME/ docker://DOCKER-IMAGE-NAME

Changes can be made within the container with the --writable flag.

$ singularity shell --writable IMAGE_NAME/

A sandbox directory can be converted into a sif file with the build command.

$ singularity build production.sif IMAGE_NAME/

Utilisation de la commande sudo

Dans la documentation de Singularity sur comment construire un conteneur, on utilise la commande sudo parce que la commande build requiert souvent les permissions root de l’utilisateur racine (superutilisateur). Comme les utilisateurs de Calcul Canada n’ont pas ce niveau de permissions, la commande sudo ne peut pas être utilisée. Vous n’avez généralement pas besoin d’un accès sudo si vous construisez une image préconstruite à partir de Singularity ou de Docker Hub. Si vous avez besoin des privilèges root pour construire une image, vous pouvez demander l’intervention du soutien technique ou encore installer Linux et Singularity sur votre propre ordinateur.

Il est fort possible que vous n’ayez pas besoin d’utiliser la commande sudo avec votre image. Voici ce qui se produira si elle n’est pas utilisée :

  • Singularity émettra un avertissement indiquant que l’image créée ne fonctionnera pas; il ne s’agit toutefois que d’un avertissement et l’image sera quand même créée.
  • Toutes les permissions pour le système de fichiers seront réduites aux permissions de l’utilisateur et du groupe Linux qui exécute singularity build, habituellement l’utilisateur et le groupe qui ont servi à la connexion.

Habituellement, vous n’avez pas à vous soucier de conserver les permissions à moins que

  • vous ayez à régulièrement mettre à jour et reconfigurer le contenu de l’image et
  • que les outils pour mettre à jour et reconfigurer le contenu de l’image exigent que les permissions ne soient pas modifiées.

Il est facile de mettre à jour ou d’installer de nouveaux logiciels avec plusieurs distributions Linux à l’aide de commandes comme

  • apt-get update && apt-get upgrade
  • apt-get install some-software-package
  • yum install some-software-package
  • dnf install some-software-package
  • etc.

Il est possible que ces commandes et d’autres ne s’exécutent correctement que si les permissions des systèmes de fichiers sont conservées.

La création d’une image pourrait ne pas se faire en raison de certaines restrictions du nœud avec lequel vous travaillez; en particulier, c’est le cas des nœuds de connexion. Si vous avez besoin d’assistance pour créer une image Singularity, contactez le soutien technique.

Utilisation

NOTE : Nous abordons ici l’utilisation de Singularity sans tenir compte de Slurm qui fait l’ordonnancement des tâches interactives ou en lots; pour des renseignements à ce sujet, consultez Exécuter des tâches.

Vous n’utiliserez jamais la commande sudo pour exécuter des applications sur une grappe de Calcul Canada. Il y a différentes façons d’exécuter ces applications :

  1. exécuter les commandes interactivement dans une session Singularity;
  2. exécuter une commande unique qui s’arrête lorsqu’elle est complétée;
  3. exécuter une instance conteneur pour exécuter des daemons.

Exécuter les commandes interactivement

Pour des renseignements sur l’utilisation de la commande pour l’interpréteur Singularity, utilisez

$ singularity shell --help

Dans l’exemple suivant avec le conteneur myimage.simg,

$ singularity shell -B /home -B /project -B /scratch -B /localscratch myimage.simg

le résultat serait de

  • faire un bind mount de /home pour que tous les répertoires home soient accessibles (dépendant des permissions associées à votre compte);
  • faire un bind mount de /project pour que tous les répertoires project soient accessibles (dépendant des permissions associées à votre compte);
  • faire un bind mount de /scratch pour que le répertoire scratch soit accessible (dépendant des permissions associées à votre compte);
  • faire un bind mount de /localscratch pour que le répertoire localscratch soit accessible (dépendant des permissions associées à votre compte);
  • exécuter un interpréteur (par exemple /bin/bash)

Si cette commande réussit, vous pourrez exécuter des commandes interactivement à partir de votre conteneur en ayant accès à vos fichiers dans home, project, scratch et localscratch.

NOTE : Lorsque vous avez terminé, entrez exit.

Dans certains cas, vous ne voudrez pas que les variables de l’interpréteur de Calcul Canada polluent l’environnement de l’interpréteur; ajoutez donc l’option -e comme suit

$ singularity shell -e -B /home -B /project -B /scratch -B /localscratch myimage.simg

Sachez toutefois que vous devrez peut-être définir certaines variables de l’environnement de l’interpréteur, par exemple $USER.

Enfin, si vous utilisez Singularity interactivement sur votre propre ordinateur, vous devez vous assurer de satisfaire les conditions suivantes pour que les modifications apportées à l’image soient enregistrées sur le disque :

  • utiliser une image sandbox Singularity (c’est-à-dire utiliser un répertoire et non le fichier en lecture seule .simg)
  • utiliser l'option -w et
  • utiliser sudo.

Par exemple, créez d’abord votre image sandbox avec

$ sudo singularity build -s myimage-dir myimage.simg

puis communiquez interactivement avec Singularity.

$ sudo singularity shell -w myimage-dir

Lorsque vous avez terminé, créez ou mettez à jour le fichier simg avec

$ sudo singularity build myimage-new.simg myimage-dir/

et téléversez myimage-new.simg sur une grappe pour pouvoir l’utiliser.

Exécuter une commande unique

Pour soumettre une tâche qui fait appel à des commandes dans un conteneur Singularity, il faut utiliser les commandes Singularity exec ou run.

  • la commande exec ne nécessite aucune configuration
  • avec la commande run, il faut configurer une application à l’intérieur d’un fichier de recette Singularity; ce sujet n’est pas abordé ici.

Les options pour la commande exec sont presque identiques à celles de la commande shell, par exemple

$ singularity exec --help

Lorsqu’il ne s’agit pas d’une demande d’assistance, exec exécute la commande spécifiée dans le conteneur et quitte ensuite le conteneur, par exemple

$ singularity exec -B /home -B /project -B /scratch -B /localscratch myimage.simg ls /

qui retourne le contenu du répertoire racine dans le conteneur. Notez que la version de ls est celle qui est installée dans le conteneur; si par exemple gcc de GCC était installé dans le conteneur myimage.simg, la commande suivante

$ singularity exec -B /home -B /project -B /scratch -B /localscratch myimage.simg gcc -v

retournerait les renseignements sur la version de ce qui est installé dans le conteneur, alors qu’à l’invite de l’interpréteur usuel de Calcul Canada,

$ gcc -v

retournerait la version de GCC chargée à ce moment sur les grappes de Calcul Canada.


Pour exécuter une commande unique de l’intérieur de votre conteneur Singularity, la commande exec est suffisante. N’oubliez pas de faire un bind mount des répertoires dont vous aurez besoin pour que votre tâche soit bien exécutée.

Singularity can also accept user defined environment variables. This can be achieved via --env-file flag. We pass path of the file that define all the variables which we want to use inside the singularity context as an argument to the --env-file flag. The --env-file flag is especially useful for the scenarios when we want to use the -e flag with singularity exec which forces a "clean environment".

For example, if we want to use the PYSPARK_SUBMIT_ARGS environment variable inside the singularity context, we will create a file, for example envfile, and define the variable PYSPARK_SUBMIT_ARGS in it. We can define more than one variable inside the file.

PYSPARK_SUBMIT_ARGS='--driver-memory 96g  --driver-java-options "-verbose:gc  -XX:+UseSerialGC  -XX:-UseGCOverheadLimit" pyspark-shell'

And then we pass the path of file to the singularity command via --env-file flag.

$ singularity exec --env-file envfile  myimage.simg gcc -v

In the above example we assume that envfile is present at the same location from where we execute the singularity command and thus we passed just the filename rather than the path to the file.


Exécuter des instances de conteneurs

Pour exécuter des daemons et des processus en arrière-plan dans un conteneur, n’utilisez pas la commande exec, mais plutôt les commandes Singularity instance.start et instance.stop pour créer et supprimer les sessions (les instances de conteneurs). En utilisant des sessions, Singularity s’assure que vos applications exécutées dans l’instance sont terminées quand la tâche se termine, peu importe la raison.

Pour démarrer une instance de session, lancez la commande instance.start suivie du nom de l’image (ici myimage.simg) et du nom de la session (ici quadrat5run).

$ singularity instance.start myimage.simg quadrat5run

La commande instance.stop met fin à la session et à toutes les applications qui y sont associées.

$ singularity instance.stop myimage.simg quadrat5run

En tout temps, vous pouvez voir la liste des sessions en cours avec

$ singularity instance.list

qui fournit le nom du daemon, son PID et le chemin pour l’image du conteneur.

Lorsqu’une session est en cours, les applications peuvent être exécutées avec les commandes Singularity shell, exec ou run en indiquant le nom de l’image suivi du préfixe instance:// accolé au nom de la session.

$ singularity instance.start mysessionname
$ singularity exec myimage.simg instance://mysessionname ps -eaf
$ singularity shell myimage.simg instance://mysessionname 
nohup find / -type d >dump.txt
exit
$ singularity exec myimage.simg instance://mysessionname ps -eaf
$ singularity instance.stop mysessionname

Bind mount

Par défaut, une application exécutée dans un conteneur Singularity ne voit que les fichiers dans l’image du conteneur et ceux dans le répertoire courant. Les tâches Singularity doivent donc faire le bind mount des systèmes de fichiers dans lesquels se trouvent les fichiers avec l’option -B aux commandes shell, exec ou run.

$ singularity shell -B /home -B /project -B /scratch -B /localscratch myimage.simg
$ singularity exec -B /home -B /project -B /scratch -B /localscratch myimage.simg ls /
$ singularity run -B /home -B /project -B /scratch -B /localscratch:/temp myimage.simg some-program

Ces commandes font un bind mount des systèmes de fichiers de l’image de conteneur myimage.simg :

  • /home pour que tous les répertoires home soient accessibles (dépendant des permissions associées à votre compte);
  • /project pour que tous les répertoires project soient accessibles (dépendant des permissions associées à votre compte);
  • /scratch pour que le répertoire scratch soit accessible (dépendant des permissions associées à votre compte);
  • /localscratch pour que le répertoire localscratch soit accessible (dépendant des permissions associées à votre compte).

Dans la plupart des cas, il n’est pas recommandé de monter directement chacun des répertoires pour éviter des problèmes d’accès; montez plutôt le répertoire racine du système de fichiers, tel que montré plus haut.

Problèmes connus pour le CHP

Applications MPI dans un conteneur

Si vous utilisez des applications MPI, rien de particulier ne doit être fait pour les tâches utilisant un seul nœud.

Pour utiliser plusieurs nœuds, vous devez :

  • vous assurer que votre application MPI est compilée avec la version OpenMPI qui est installée dans votre conteneur Singularity;
    • idéalement, cette version OpenMPI est 3 ou 4; la version 2 pourrait ou non fonctionner; la version 1 ne fonctionnera pas;
  • vous assurer que le script de votre tâche Slurm utilise srun pour exécuter l'application MPI; n'utilisez pas mpirun ou mpiexec, par exemple
srun singularity exec /path/to/your/singularity/image.sif /path/to/your-program
  • vous assurer que le script de votre tâche ne contient aucune commande pour charger un module;
  • installer dans votre conteneur le paquet slurm-client de votre distribution pour pouvoir interagir avec l'ordonnanceur Slurm;
  • avant de soumettre la tâche avec sbatch, dans l'interpréteur (shell) CC, chargez les modules suivants :
    • singularity
    • openmpi (il n'est pas nécessaire que la version corresponde à la version de OpenMPI dans le conteneur; idéalement, utilisez les versions 3 ou 4; la version 2 pourrait ou non fonctionner; la version 1 ne fonctionnera pas).

Enfin, assurez-vous qu'un paquet de réseautique haute performance soit installé dans votre image :

  • installez libpsm2 si le superordinateur utilise OmniPath,
  • installez UCX si le superordinateur utilise Infiniband.

Using CUDA on Compute Canada clusters

If you are running programs which use the CUDA library, you must make sure that your Singularity container has CUDA installed.

The --nv flag needs to be added to make CUDA work.

$ srun singularity run --nv container-name.sif [job to do]

Changer les répertoires Singularity par défaut

Vous pouvez changer le répertoire temporaire et le répertoire de mise en cache en définissant ces variables d'environnement avant de lancer Singularity :

  • SINGULARITY_CACHEDIR : répertoire pour l’écriture des fichiers temporaires, incluant ceux créés à la construction de fichiers image SquashFS,
  • SINGULARITY_TMPDIR : répertoire pour le téléchargement et la mise en cache des fichiers.

Dans cet exemple, on demande à Singularity d’utiliser l’espace /scratch pour les fichiers temporaires et la mise en cache.

$ mkdir -p /scratch/$USER/singularity/{cache,tmp}
$ export SINGULARITY_CACHEDIR="/scratch/$USER/singularity/cache"
$ export SINGULARITY_TMPDIR="/scratch/$USER/singularity/tmp"

Ces commandes doivent être exécutées avant de lancer Singularity.

Voir aussi

Présentation faite par Paul Preney le 14 février 2018 ː

Références

  1. Site web Singularity, https://www.sylabs.io/docs/
  2. Site web Docker, https://www.docker.com/
  3. Documentation de sécurité Singularity, https://www.sylabs.io/guides/2.5.1/admin-guide/security.html
  4. Documentation d'installation Singularity, https://www.sylabs.io/docs/