Tutoriaux

Docker est un logiciel libre qui automatise le déploiement d'applications dans des conteneurs logiciels s'executant en isolation. Un conteneur Docker, à l'opposé de machines virtuelles traditionnelles, ne requiert aucun système d'exploitation séparé et n'en fournit aucun mais s'appuie plutôt sur les fonctionnalités du noyau et utilise l'isolation de ressources ainsi que des espaces de noms séparés pour isoler le système d'exploitation tel que vu par l'application.


SLURM (Simple Linux Utility for Resource Management) est une solution open source d'ordonnancement de tâches informatiques qui permet de créer des grappes de serveurs sous Linux ayant une tolérance aux pannes, type ip-failover, ferme de calcul, système d'ordonnancement des tâches.

Cette solution peut être utilisée sur des grappes de tailles variées, de deux à plusieurs milliers de serveurs. Il est utilisé sur la majorité des plus puissants supercalculateurs de la planète.

source: https://fr.wikipedia.org/wiki/SLURM

Architecture de la ressource de calcul



Parallèlement à la ressource de calcul, la plate-forme dispose également de 4 serveurs de virtualisation permettant d'héberger des serveurs Web ou des bases de données. Voir le paragraphe Politique de déploiement de services.


Nœuds de calcul

La ressource de calcul est constituée d'une ferme hétérogène de nœuds :

  • Cluster de production :
    • node[0-31] : 12 cpus.
    • node[40-48] : 12 cpus.
    • node[49-56] : 8 cpus.
    • node[60-68] : 8 cpus.
    • node[69-72] : 16 cpus x 2 (hyperthreading).
    • node73 : 16 cpus.
    • node[74-76] : 20 cpus x 2 (hyperthreading).
    • node[77-79] : 28 cpus x 2 (hyperthreading).
    • node[100-109] : 12 cpus.
    • manycores : 60 cpus x 2 (hyperthreading).
  • Cluster de développement :
    • node[40-41] : 12 cpus.
    • node[57-59] : 8 cpus.
  • Cloud Openstack :
    • node[32-39] : 12 cpus.
  • Nœuds GPU :
    • gpu-node1 : Nvidia GeForce GTX980 x 2.
    • gpu-node[2-3] : Nvidia GeForce GTX1070 x 2.
    • gpu-node4 : Nvidia GeForce GTX1080Ti x 2.
    • gpu-node[5-8] : Nvidia GeForce RTX2080Ti x 2.

Espaces de données

Les utilisateurs du cluster de calcul ont accès à deux espaces de stockage :

  • Joule : espace destiné au stockage uniquement.
  • Scratch : espace destiné aux calculs uniquement. Attention, cet espace n'est pas sauvegardé.
Chemin Type Accessible depuis Utilisation Performance Sauvegardé
/home/joule/ NFS nœuds de calcul espace de stockage moyenne oui
/scratch/user/ Lustre nœuds de calcul + conteneurs logiciels espace de travail élevée non

Il existe plusieurs façons de se connecter à la ressource de calcul :

  • en configurant l'adresse du serveur de noms sur sa machine (conseillé),
  • en éditant son fichier hosts,
  • en tapant directement l'adresse de la machine à joindre.

Configurer l'adresse du serveur de noms (conseillé)

Le serveur de noms est hébergé sur la machine Annuaire (172.27.7.52). Pour l'utiliser, il existe plusieurs solutions selon la version de votre système.

Avec Network Manager (le plus simple)

Cliquer sur l'icône de Network Manager dans la barre en haut à droite -> Edit Connections -> Onglet Wired -> Onglet IPv4 Settings et entrer 172.27.7.52 dans le champ DNS servers. Cliquer sur Save...

Éditer directement le fichier /etc/resolv.conf (déprécié)

Éditer le fichier /etc/resolv.conf avec les droits root et y ajouter les lignes suivantes :

nameserver 172.27.7.52
nameserver 194.254.200.25
nameserver 194.254.200.26

La plupart du temps cette solution n'est pas viable car un certain nombre de services écrasent le fichier (NetworkManager, dhcpd ou resolvconf).

Configurer manuellement ses interfaces (le plus fiable)

Désactiver le démon NetworkManager :

sudo systemctl stop NetworkManager
sudo systemctl disable NetworkManager

Encore une fois, plusieurs possibilités selon la nature de votre système :

  • Éditer le fichier /etc/network/interfaces et y ajouter les lignes suivantes (remplacer eth0 par le nom de votre interface) :

    auto eth0
    iface eth0 inet dhcp

    Éditer le fichier /etc/dhcp/dhclient.conf et y ajouter la ligne suivante :

    prepend domain-name-servers 172.27.7.52;
  • OU

  • Éditer le fichier /etc/sysconfig/network-scripts/ifcfg-eth0 (remplacer eth0 par le nom de votre interface) et modifier / ajouter la ligne suivante :

    DNS1=172.27.7.52

Connexion

Pour se connecter au cluster de production :

ssh login@slurmmaster.rpbs.priv

Pour se connecter au cluster de développement :

ssh login@node57.rpbs.priv

Éditer son fichier hosts

Éditer le fichier /etc/hosts avec les droits root et y ajouter les lignes suivantes :

172.27.7.35 slurmmaster #cluster de prod
172.27.7.57 node57 #cluster de dev

Il est bien-sûr possible de remplacer ces alias par d'autres (par exemple cluster et clusterdev respectivement).

Remarque : Pour les personnes souhaitant avoir accès aux registres de conteneurs logiciels depuis leur poste, il sera nécessaire de compléter la ligne suivante :
172.27.7.35 slurmmaster docker-registry.rpbs.univ-paris-diderot.fr dev-registry.rpbs.univ-paris-diderot.fr

Pour se connecter au cluster de production :

ssh login@slurmmaster

Pour se connecter au cluster de développement :

ssh login@node57

Soumettre un job

Pré-requis

Pour des raisons de sécurité, les conteneurs logiciels ne montent que l'espace de travail de l'utilisateur (/scratch/user/). Il faut donc s'assurer d'être dans le bon dossier avant de soumettre toute commande :

cd /scratch/user/[LOGIN]

Exemple :

cd /scratch/user/rey

La liste des partitions disponibles peut être consultée avec la commande suivante :

sinfo --summarize

Exemple qui permet d'obtenir le nombre de cpus et de gpus pour chaque nœud de la partition gpu :

sinfo -p gpu --Node -o "%6t %6z %.4c %16G %6m %N"

Pour plus de paramètres :

man sinfo

Commande de base

La commande de base pour soumettre un job en intéractif est la suivante :

srun [OPTIONS] [COMMANDE À EXÉCUTER]

Pour exécuter un programme dans un conteneur docker :

drun [NOM DE L'IMAGE] [COMMANDE À EXÉCUTER]

Pour soumettre un job avec un exécutable contenu dans une image, on doit donc combiner les deux commandes :

srun drun [NOM DE L'IMAGE] [COMMANDE À EXÉCUTER]

Exemple :

srun drun faf-drugs python /usr/local/FAF-Drugs/bin/FAFDrugs.py -D 103_c.sdf -f drug -p xlogp3 -g --painsa --painsb --painsc --regular
Attention : Les conteneurs sont des espaces virtualisés dont le contenu est supprimé après son exécution. Toute donnée non écrite dans le dossier /scratch/user/ de l'utilisateur sera perdue.
Remarque : Il est possible d'utiliser le dossier /tmp/ d'un conteneur pour y stocker des fichiers temporaires qui seront supprimés automatiquement à la fin de l'exécution.

Pour spécifier la partition à utiliser (par défaut, production) :

srun -p bigmemory drun [NOM DE L'IMAGE] [COMMANDE À EXÉCUTER]

Allouer un nombre de cpu(s) pour le job :

srun -c 8 drun [NOM DE L'IMAGE] [COMMANDE À EXÉCUTER]

Utilisation de processeurs GPU

Il faut obligatoirement soumettre les jobs sur une partition gpu et indiquer le nombre de GPUs à utiliser avec l'option --gres :

srun -p newgpu --gres=gpu:1 drun [NOM DE L'IMAGE] [COMMANDE À EXÉCUTER]

La commande nvidia-smi permet de vérifier la correcte allocation des GPUs :

rey@SlurmMaster:~$ srun -p newgpu --gres=gpu:2 drun gromacs-plumed nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.33.01    Driver Version: 440.33.01    CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce RTX 208...  On   | 00000000:03:00.0 Off |                  N/A |
| 24%   31C    P8    19W / 257W |      0MiB / 11019MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  GeForce RTX 208...  On   | 00000000:05:00.0 Off |                  N/A |
| 25%   26C    P8    16W / 257W |      0MiB / 11019MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

Exemple de dynamique moléculaire avec gromacs utilisant un GPU :

srun -p newgpu --gres=gpu:1 drun gromacs-plumed gmx mdrun -nsteps 2000 -deffnm 1f3_AE

Utilisation de scripts batch

Pour soumettre des jobs en batch en mode non-intéractif :

sbatch [SCRIPT.Q]

Les mêmes options que la commande srun s'appliquent : ils doivent être précédés par l'instruction #SBATCH dans le script ou bien utilisés en ligne de commande de la même façon que la commande srun.

Exemple de script batch :

#!/bin/bash
#SBATCH --output=test.out
#SBATCH --array=1-5
#SBATCH -p production
case "$SLURM_ARRAY_TASK_ID" in 
   1) fichier='/scratch/user/rey/protein_1';;
   2) fichier='/scratch/user/rey/protein_2';;
   3) fichier='/scratch/user/rey/protein_3';;
   4) fichier='/scratch/user/rey/protein_4';;
   5) fichier='/scratch/user/rey/protein_5';;
esac
drun opendocking babel -i ${fichier}.pdb -o ${fichier}.mol2

Utilisation de la bibliothèque python cluster

Les développeurs disposent également d'une bibliothèque permettant la soumission de jobs directement depuis un script python. Pour l'instant la bibliothèque ne comporte qu'une seule fonction utilisable, mais ceci peut être amené à évoluer. La plupart des fonctions font usage de la bibliothèque python-drmaa pour soumettre des jobs via Slurm.

  • runTasks(command, args, tasks, tasks_from, docker_img, log_prefix, map_list, job_name, job_opts, joinFiles, progress, partition, account, qos)

    • command : chemin vers l'exécutable à l'intérieur du conteneur.
    • args : tableau contenant les arguments à passer à la commande.
    • tasks : nombre de tâches à accomplir (job array). Chaque itération incrémente d'une unité la variable d'environnement TASK_ID accessible depuis les conteneurs. Défaut = 1.
    • tasks_from : valeur initiale pour la variable d'environnement TASK_ID. Défaut = 1.
    • docker_img : nom de l'image Docker à invoquer ou None pour envoyer une commande sans passer par Docker.
    • log_prefix : préfix du fichier de logs retourné par le conteneur. Défaut = nom de l'image invoquée.
    • map_list : surcharge le paramètre tasks. Tableau contenant une liste de fichiers sur laquelle la fonction va boucler. Chaque fichier est accessible depuis un conteneur grâce à la variable d'environnement $(mapped_file ${TASK_ID}). Nécessite l'installation d'un interpréteur python dans l'image invoquée.
    • job_name : nom attribué au job. Défaut = docker_img + command.
    • job_opts : ajouter des options de paramétrage pour Slurm.
    • joinFiles : fusionner tous les fichiers de logs en un seul. Si paramétré sur False, un fichier de log sera créé par tâche. Défaut = True.
    • progress : affichage de la progression (Mobyle). Défaut = True.
    • partition : partition Slurm sur laquelle envoyer le job. Défaut = partition du job principal.
    • account : compte Slurm sur lequel envoyer le job. Défaut = compte du job principal.
    • qos : spécification du QoS (Quality of Service) du job. Défaut = QoS du job principal.

Exemple simple de script python utilisant la bibliothèque cluster :

#!/usr/bin/env python

import sys                                     # import de la bibliothèque
sys.path.append("/service/env")
import cluster

cmd = "PyPPPExec"                              # chemin vers l'executable

args = ["-s %s" % self.options.pepseq,         # liste d'arguments de type str
        "-l %s" % self.options.label,
        "--2012",
        "-v"]
                    
cluster.runTasks(cmd, args, docker_img = "pep-sitefinder")
Attention : Les arguments doivent être obligatoirement de type str. L'utilisation de variables de type int ou float déclenchera une erreur lors de la soumission.

Exemple de script python qui va itérer sur une liste contenue dans un fichier :

#!/usr/bin/env python

import sys
sys.path.append("/service/env")
import cluster


cmd = "echo"

args = [ '$(sed -n "${TASK_ID}p" liste.txt)',
       ]

cluster.runTasks(cmd, args, tasks = 5, docker_img = "opendocking")

Il n'y a plus qu'à executer le script en le soumettant sur le cluster :

srun python example.py

Suivre l'exécution du job

Afficher les jobs en cours d'execution ou en attente :

squeue

Suivre l'exécution des jobs à chaque seconde :

watch -n 1 squeue

Afficher les jobs d'un utilisateur en particulier :

squeue -u rey

Afficher plus de colonnes :

squeue -o '%.18i %.9P %.30j %.8u %.8T %.10M %.9l %.6D %R %q %a'

Obtenir des infos sur un job :

scontrol show job -dd [ID DU JOB]

Annuler un job

Annuler un job :

scancel [ID DU JOB]

Annuler tous les jobs d'un utilisateur en particulier :

scancel -u rey

Annuler tous les jobs en attente pour un utilisateur :

scancel -t PENDING -u rey

Il existe plusieurs méthodes pour transférer des données sur l'espace de stockage sauvegardé (Joule) depuis sa machine.

En montant son répertoire sur sa machine via NFS

Les utilisateurs de l'espace de stockage sauvegardé doivent me faire une demande avec l'ip de la machine qui va monter le répertoire.

Pour monter le répertoire ponctuellement :

mkdir -p /home/joule/rey
sudo mount -o nfsvers=3 -t nfs 172.27.7.56:/home/joule/rey /home/joule/rey

Pour monter le répertoire au démarrage il faut modifier le fichier /etc/fstab et y ajouter la ligne suivante :

172.27.7.56:/home/joule/rey   /home/joule/rey   nfs   defaults,nfsvers=3   0   0

Pour prendre les changements en compte immédiatement :

sudo mount -a

En utilisant SSH

Pour faire une simple copie, on doit passer par la machine SlurmMaster :

scp /home/rey/mon_fichier rey@slurmmaster:/home/joule/rey

Alternativement il est possible de monter son répertoire via sftp ou sshfs. Il faudra alors copier sa clé publique sur SlurmMaster en utilisant la commande ssh-copy-id.

mkdir -p /home/joule/rey
ssh-copy-id rey@slurmmaster
sshfs rey@slurmmaster:/home/joule/rey /home/joule/rey

Connexion simple

Il est possible d'accéder au réseau du laboratoire via ssh depuis une connexion distante. Pour cela, dans un terminal, taper :

ssh [login]@epervier.rpbs.univ-paris-diderot.fr

À partir de cette machine il est possible d'accéder à l'ensemble des machines des réseaux bfa-cmpli (172.27.6.x) et rpbs (172.27.7.x).

Remarque : La machine epervier n'a pas vocation à stocker de gros volumes de données de façon pérenne. En aucun cas la persistance des données déposées sur ce serveur ne saura être assurée.

Tunneliser sa connexion

Pour tunneliser sa connexion, ouvrir un terminal, taper la ligne suivante :

ssh -L[port_local]:[machine_du_laboratoire]:22 [login]@epervier.rpbs.univ-paris-diderot.fr

Puis laisser le terminal ouvert. Pour se connecter à la machine, ouvrir un nouveau terminal puis entrer :

ssh [login]@localhost -p [port_local]

On peut également se connecter à la machine avec Nautilus (Gnome-shell, Ubuntu, Fedora, etc...) et monter un dossier distant comme si il s'agissait d'un dossier local. Pour cela, faire Ctrl + L puis taper dans la barre d'adresse ssh://[login]@localhost:[port_local]. Cela permet surtout de travailler sur ses fichiers distants avec des programmes qui tournent en local, ce qui est bien moins lourd que d'exporter l'affichage de la machine distante.

Quelques exemples :

  • Dans un terminal : ssh -L1234:172.27.6.198:22 rey@epervier.rpbs.univ-paris-diderot.fr
  • Dans un autre terminal : ssh rey@localhost -p 1234
  • Dans Nautilus (Fichiers) : Ctrl + L puis ssh://rey@localhost:1234

Bien entendu il est possible de mapper un port local avec un port autre que 22 sur la machine distante. Par exemple, si l'on souhaite accéder à un serveur Web présent sur une machine du réseau rpbs :

ssh -L9876:172.27.7.111:80 rey@epervier.rpbs.univ-paris-diderot.fr

Puis, dans un navigateur Web, taper dans la barre d'adresse : http://localhost:9876

Accès

La forge Gitlab est située à l'adresse https://gitlab.rpbs.univ-paris-diderot.fr.


Configuration

L'authentification sur les dépôts de la forge peut s'effectuer par https en tapant ses identifiants à chaque fois ou par ssh par un système de clé publique / clé privée si vous vous connectez à partir du réseau bfa-cmpli. Dans le second cas il est nécessaire de copier sa clé publique sur son espace personnel :

cat ~/.ssh/id_rsa.pub

Puis aller dans Profile Settings -> SSH Keys -> ADD SSH KEY et copier / coller le contenu de la clé dans la fenêtre Key. Valider en cliquant sur ADD KEY.


Utilisation

Clôner un dépôt

Par HTTPS :

Dans un terminal, taper :

git clone https://gitlab.rpbs.univ-paris-diderot.fr/rey/mon_depot.git

Par SSH :

Depuis le réseau bfa-cmpli, dans un terminal, taper :

git clone git@172.27.7.118:rey/mon_depot.git
Attention : Contrairement à ce qui est indiqué sur la page Command line instructions d'un projet, on doit renseigner l'adresse locale du Gitlab (172.27.7.118) et non l'adresse publique (gitlab.rpbs.univ-paris-diderot.fr).

Créer un nouveau projet

Sur la page d'accueil, cliquer sur + NEW PROJECT, renseigner les champs, puis cliquer sur CREATE PROJECT. Puis, dans un terminal :

Par HTTPS :

Dans un terminal, taper :

cd dossier_du_projet
git init
git remote add origin https://gitlab.rpbs.univ-paris-diderot.fr/rey/mon_depot.git
git add .
git commit
git push -u origin master

Par SSH :

Depuis le réseau bfa-cmpli, dans un terminal, taper :

cd dossier_du_projet
git init
git remote add origin git@172.27.7.118:rey/mon_depot.git
git add .
git commit
git push -u origin master
Remarque : l'argument -u est important lors du premier push afin d'associer la branche locale à la branche distante. Il n'est plus nécessaire par la suite.

Accès

Interface Web

Une plate-forme de stockage et de partage de fichiers Owncloud est située à l'adresse https://owncloud.rpbs.univ-paris-diderot.fr.

La page d'accueil est on ne peut plus simple et permet un accès direct aux fichiers personnels et partagés. Il est possible de partager un fichier personnel avec d'autres personnes en cliquant sur l'icône Partager : on peut alors soit entrer le nom d'un autre utilisateur ou d'un groupe de la plate-forme (cmpli, équipe 1, équipe 2, équipe 3, système, etc...), soit partager sous forme de lien à transmettre à n'importe qui. Dans ce cas il est possible de protéger le lien à l'aide d'un mot de passe.

En cliquant sur le menu déroulant en haut à gauche, on a également accès à d'autres fonctions comme un calendrier qui permet de noter ses congés ou des réunions et qui ne pourra être visible que par les personnes de son choix.

Attention : Sur certains navigateurs l'icône de partage de fichier ou de calendrier n'apparaît pas. Il faut désactiver adblock ou bien ajouter le site à la liste des exceptions.

Montage via Nautilus (Gnome-shell, Ubuntu, Fedora, etc...)

Dans l'interface Web, cliquer sur Paramètres, puis copier l'adresse située sous WebDAV.

Dans Nautilus (Fichiers) : Ctrl + L puis coller l'adresse en substituant https par davs. Par exemple :

davs://owncloud.rpbs.univ-paris-diderot.fr:443/owncloud/remote.php/dav/files/rey/

Puis rentrer son login et mot de passe. On peut ensuite effectuer des glisser / déposer de fichiers comme dans un répertoire local.

Remarque : Le volume est monté dans /run/user/1000/gvfs (Debian / Ubuntu).

Montage en ligne de commande

Installer le package davfs2 :

Pour les distributions Debian/Ubuntu :

sudo apt-get install davfs2

Monter le dossier :

Il s'agit d'une commande mount classique :

sudo mount.davfs https://owncloud.rpbs.univ-paris-diderot.fr/owncloud/remote.php/dav/files/rey /mnt/

Synchronisation via le client (Linux, OS X)

Installer le client owncloud :

Pour les distributions Debian/Ubuntu :

sudo apt-get install owncloud-client

Pour la distribution Fedora :

sudo dnf install owncloud-client

Pour OS X : voir https://owncloud.com/client/

Configuration du client :

  1. Cliquer sur le bouton "Account" et choisir "Add new".
  2. Entrer "https://owncloud.rpbs.univ-paris-diderot.fr/owncloud/" comme nom du serveur.
  3. Entrer vos identifiants.
  4. Selectionner les options souhaitées, ainsi que le répertoire qui contiendra la copie locale des fichiers.

Selon la distribution et la configuration, le client peut ne pas lancer la synchronisation des fichiers de façon automatique. Dans ce cas, il est possible de forcer la synchronisation manuellement :

  1. Cliquer sur l'icone du client pour ouvrir le dialogue.
  2. Cliquer sur le signe "..." pour dérouler le menu.
  3. Choisir "Force sync now" pour synchroniser les fichiers locaux et distants.

Manipulation d'images

Une image est un template à partir duquel on va exécuter des conteneurs.

Lister les images présentes sur sa machine :

docker images

Chercher des images hébergées sur le registre officiel Docker :

docker search centos      # exemple d'une recherche d'une distribution centos
docker search gitlab      # exemple d'une recherche d'un serveur gitlab
Remarque : Si aucune adresse n'est précisée, Docker cherchera sur le registre officiel Docker. Pour chercher une image présente sur les registres du laboratoire il faut donc préciser l'adresse comme expliqué ci-dessous.

Lister les images hébergées sur le registre de développement du laboratoire :

docker search dev-registry.rpbs.univ-paris-diderot.fr/library

Lister les images hébergées sur le registre de production du laboratoire :

docker search docker-registry.rpbs.univ-paris-diderot.fr/library

Télécharger une image sur sa machine depuis le registre officiel Docker :

docker pull debian:stable

Télécharger une image sur sa machine depuis le registre de production du laboratoire :

docker pull docker-registry.rpbs.univ-paris-diderot.fr/opendocking
Remarque : Télécharger une image écrasera celle présente sur la machine locale.

Pour renommer une image locale :

docker tag [ID DE L'IMAGE] [NOUVEAU NOM DE L'IMAGE]

Pour effacer une image locale :

docker rmi [ID DE L'IMAGE]
Remarque : Si une instance de cette image (conteneur) existe, Docker affichera une erreur. Il faut alors soit utiliser l'option -f, soit effacer les conteneurs avant.

Manipulation des conteneurs

Un conteneur est une instance d'exécution créée à partir d'un template (image).

Démarrer un conteneur en mode intéractif à partir d'une image :

docker run -it debian:stable /bin/bash
Remarque : Docker privilégiera toujours les images présentes sur la machine locale. Si l'image n'est pas présente localement, cette dernière sera téléchargée automatiquement. Pour mettre à jour l'image locale il faut donc d'abord soit effacer l'image locale, soit la retélécharger manuellement avec la commande docker pull.

En mode intéractif, le prompt du shell est modifié et affiche désormais l'identifiant du conteneur en cours d'exécution.

root@29d4663f7b11:~# _
Remarque : L'utilisateur par défaut est root. Pour utiliser ses uid et gid il faut utiliser l'option -u.

Le conteneur se comporte de la même façon qu'une machine virtuelle. L'utilisateur est administrateur de cette machine (compte root), il est alors possible de réaliser des installations ou de modifier des fichiers sytème sans aucune incidence sur la machine hôte.

Pour sortir / couper le conteneur :

exit

ou encore :

Ctrl + D
Remarque : Par défault, le conteneur arrêté n'est pas effacé. Pour effacer le conteneur automatiquement après son arrêt il faut utiliser l'option --rm avec la commande docker run.

Pour lister les conteneurs (y compris ceux qui ont été stoppés) :

docker ps -a

Pour redémarrer un conteneur qui a été stoppé :

docker start -a -i [ID DU CONTENEUR]

Pour effacer un conteneur stoppé :

docker rm [ID DU CONTENEUR]

Commandes avancées

Démarrer un conteneur en mode intéractif avec les bons uid et gid, en montant le dossier courant et en se plaçant dedans, et supprimer le conteneur à la sortie :

docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) -w $(pwd) debian /bin/bash

Effacer les conteneurs arrêtés :

docker ps -qa -f "status=exited" | xargs docker rm

Effacer les images untagged (<none>) :

docker images --filter "dangling=true" -q --no-trunc | xargs docker rmi -f

Écriture du Dockerfile

Le Dockerfile est un fichier texte qui inclut une liste d'actions à exécuter pour construire une image.

Voici les différentes instructions à fournir :

FROM debian:jessie
  • FROM : image de base (centos, debian, etc...). Préciser la version, ne pas mettre latest !
LABEL maintainer="jean.dupont@u-paris.fr"
LABEL principal.investigator="sophie.lemarchand@inserm.fr"
LABEL contributors="marie.boulanger@u-paris.fr; francois.martin@inserm.fr; leila.belkacem@cea.fr"
  • LABEL : ajoute des métadonnées à l'image qui seront affichées lorsqu'un utilisateur soumettra la commande docker inspect image:version --format={{json .Config.Labels}} ou module whatis image:version
ENV PATH /usr/local/some_program/bin:$PATH
  • ENV : déclaration des variables d'environnement. Le chemin vers les exécutables qui ne sont pas situés dans le PATH standard (/usr/local/bin) devrait être déclaré ici.
COPY src /tmp/
COPY test /test
  • COPY : copie des fichiers ou des répertoires depuis le dossier du dépôt local et les ajoute au système de fichiers du container. Le dossier /test doit obligatoirement exister et comporter un fichier .command comprenant une ligne de commande lançant un test fonctionnel.
Attention : L'instruction COPY copie le contenu du dossier et non le dossier lui-même.
RUN apt-get -q -y update && \
apt-get install -q -y \ 
  python-pip \
  python-dev \
  r-base && \  
apt-get autoremove -q -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
  • RUN : commande à exécuter lors de la construction de l'image. Le nombre d'instructions RUN doit être réduit au minimum afin de limiter la taille de l'image.

Quelques autres commandes utiles :

  • ENTRYPOINT : commande qui s'exécute au démarrage du conteneur.
  • CMD : commande par défaut qui s'exécute au démarrage du conteneur. La commande est écrasée si une autre est spécifiée lors du lancement du conteneur.
  • Remarque : La commande donnée par l'instruction CMD peut être utilisée comme argument de la commande donnée avec l'instruction ENTRYPOINT. Exemple:

    ENTRYPOINT ["/usr/bin/babel"]
    CMD ["--help"]

Inclusion de sous-modules git

Les sous-modules permettent de gérer un dépôt Git comme un sous-répertoire d'un autre dépôt Git. Cela permet de cloner des dépôts dans le projet et de garder isolés les commits de ce dépôt.

Bien évidemment, le dépôt principal doit être initialisé.

git init

Pour ajouter un sous-module :

git submodule add git@172.27.7.118:src/PyPDB.git src/PyPDB

ou :

git submodule add ../src/PyPDB.git src/PyPDB
Attention : Attention, il faut que le dépôt inclu comme sous-module soit accessible par le pipeline d'intégration du Gitlab.

Ne pas oublier de tracker le fichier .gitmodules nouvellement créé :

git add .gitmodules

Pour tirer la dernière version du sous-module :

git submodule update --remote

Ne pas oublier de refaire un commit du dépôt Git principal pour que Git mette à jour les pointeurs vers les sous-modules.


Construction de l'image

Taper la commande suivante :

docker build -t [NOM DE L'IMAGE] [CHEMIN VERS LE DOSSIER CONTENANT LE DOCKERFILE]

Exemple :

docker build -t mon_image .
Remarque : On peut renommer l'image à l'aide la commande docker tag.

C'est le moment de tester que tout fonctionne bien :

docker run -w /test --rm mon_image /bin/bash -c "source /test/.command"

Autres recommandations

Écriture des fichiers de résultats

Le dossier /scratch/user de l'utilisateur est automatiquement monté lorsqu'un conteneur est appelé avec la commande drun. L'écriture des fichiers de résultats doit donc se faire obligatoirement dans un sous-dossier du dossier courant. Tout fichier écrit en dehors de ce dossier sera effacé à la fin de l'exécution du conteneur (voir ci-dessous). Il est déconseillé d'utiliser des chemins absolus.

Écriture des fichiers temporaires

Il est conseillé d'écrire les fichiers temporaires directement dans le dossier /tmp du conteneur plutôt que dans le dossier courant. Chaque conteneur est automatiquement effacé après chaque exécution avec la commande drun.

Intégration avec Mobyle

Les conteneurs appelés par l'intermédiaire du portail Mobyle sont lancés en tant qu'utilisateur www-data. Certains logiciels écrivent dans le dossier home de l'utilisateur qu'il l'a lancé (pour www-data il s'agit de /var/www). Par défaut, les images de systèmes de base telles que debian ne comporte pas de dossier /var/www, ce qui risque d'entraîner des erreurs lors du lancement de ces programmes. Pour pallier à ce problème il est nécessaire de créer le dossier /var/www et de lui donner les bons droits :

RUN mkdir /var/www && chown 33:33 /var/www

Intégration continue

Le déploiement d'une image docker se fait dorénavant à travers un mécanisme d'intégration continue via le gitlab RPBS. Chaque image docker possède un projet correspondant dans le groupe docker. Pour ajouter une nouvelle image :

  1. Prendre contact avec le responsable technique de l'infrastructure julien.rey@u-paris.fr pour créer un projet.
  2. Configurer le dépôt git :
    git remote add origin https://gitlab.rpbs.univ-paris-diderot.fr/docker/mon-outil.git

    ou :

    git remote add origin git@172.27.7.118:docker/mon-outil.git

    Et créer une branche de développement :

    git checkout -b 1.0-dev
    git add .
    git commit -m "Initial commit."
    git push -u origin 1.0-dev
  3. La construction, le test, et le déploiement de l'image sont automatiques. Pour consulter l'avancement du pipeline, se rendre dans CI/CD > Pipelines.
  4. L'image docker résultante aura pour dénomination : nom_du_projet:nom_de_la_branche, par exemple : mon-outil:1.0-dev. Les images avec un tag se terminant par -dev sont tirées depuis le registre avant chaque exécution. Pour les autres, la mise à jour est quotidienne.