Tutoriaux

Docker est un logiciel libre qui automatise le déploiement d'applications dans des conteneurs logiciels s'executant en isolation. Un container 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.

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, éditer le fichier /etc/resolv.conf avec les droits root et y ajouter les lignes suivantes :

search rpbs.priv rpbs.univ-paris-diderot.fr mti.univ-paris-diderot.fr
nameserver 172.27.7.52
nameserver 194.254.200.25
nameserver 194.254.200.26

Sur certains systèmes il est nécessaire de désactiver le service NetworkManager pour éviter que le fichier ne soit écrasé :

sudo systemctl stop NetworkManager
sudo systemctl disable NetworkManager

Dans ce cas précis il faudra configurer ses interfaces à la main au risque de perdre sa connexion au réseau.

Pour se connecter au cluster de production :

ssh login@slurmmaster

Pour se connecter au cluster de développement :

ssh login@node57

É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 containers 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

Exécuter un programme

Pour des raisons de sécurité, les conteneurs 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

Pour exécuter un programme :

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

Exemple :

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.

Quelques images de services et chemins vers les programmes :

Image Ligne de commande
faf-drugs /usr/local/FAF-Drugs/bin/FAFDrugs.py
gromacs-2016-1 gmx pdb2gmx
gmx editconf
gmx solvate
gmx genion
gmx grompp
gmx mdrun
opendocking babel
pdb2mol2
pdbqt2pdb
/usr/share/pyshared/AutoDockTools/Utilities24/prepare_ligand4.py
/usr/share/pyshared/AutoDockTools/Utilities24/prepare_receptor4.py
vina
autodock4

Ordonnancement des tâches

Commande de base

La commande de base pour soumettre un job est la suivante :

srun [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]

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 scripts batch

Pour soumettre des jobs en batch :

sbatch [SCRIPT.Q]

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

Les options utilisables avec sbatch sont les mêmes que pour srun.

Utilisation de la bibliothèque python cluster (experts)

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

Autres commandes

Obtenir la liste des nœuds et des partitions :

sinfo

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

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'

Annuler un job :

scancel [ID DU JOB]

Annuler tous les jobs d'un user en particulier :

scancel -u rey

Obtenir des infos sur un job :

scontrol show job [ID DU JOB]

Erreurs fréquentes

  • -bash-4.2$ drun opendocking babel -i protein.pdb -o protein.mol2
    /bin/bash: line 0: cd: /home/joule/rey: No such file or directory

    Pour des raisons de sécurité, les conteneurs ne montent que l'espace de travail de l'utilisateur (/scratch/user/[LOGIN]). Il faut donc s'assurer d'être dans son dossier /scratch/user/[LOGIN].

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.mti.univ-paris-diderot.fr

À partir de cette machine il est possible d'accéder à l'ensemble des machines des réseaux mti (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.mti.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 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.mti.univ-paris-diderot.fr
  • Dans un autre terminal : ssh rey@localhost -p 1234
  • Dans Nautilus : 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.mti.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 s'effectue par un système de clé publique / clé privée. Pour pouvoir pousser et tirer depuis le Gitlab 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

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 :

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 (mti, é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

Dans Nautilus, cliquer sur Connexion à un serveur, puis entrer l'adresse suivante :

davs://owncloud.rpbs.univ-paris-diderot.fr/owncloud/remote.php/webdav

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

Debian / Ubuntu

Debian 7 / Ubuntu 14.04

Docker est disponible dans les dépôts à partir de la version 14.04 d'Ubuntu et à partir de la version 7.7 de Debian :

sudo apt-get install docker.io

Afin de pouvoir utiliser les registres, les clients doivent pouvoir résoudre le nom DNS de la machine :

sudo echo "172.27.7.35  dev-registry.rpbs.univ-paris-diderot.fr docker-registry.rpbs.univ-paris-diderot.fr" >> /etc/hosts

Éditer le fichier /etc/default/docker et modifier la ligne suivante de cette façon :

DOCKER_OPTS="--dns 194.254.200.25 --insecure-registry dev-registry.rpbs.univ-paris-diderot.fr --insecure-registry docker-registry.rpbs.univ-paris-diderot.fr"

Pour utiliser Docker il faut soit posséder les droits administrateur (par exemple en utilisant la commande sudo), soit être présent dans le groupe docker. Pour éviter de devoir taper sudo devant chaque commande, il faut ajouter l'utilisateur au groupe docker :

adduser [ LOGIN ] docker

Exemple :

adduser rey docker

Debian 8

Le paquet docker.io a été retiré des dépôts officiels. Il faut donc ajouter le dépôt suivant :

sudo echo "deb https://apt.dockerproject.org/repo debian-jessie main" > /etc/apt/sources.list.d/docker.list

Télécharger la clé gpg :

apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

Mettre à jour la liste des paquets :

sudo apt-get update

Installer le paquet docker-engine :

sudo apt-get install docker-engine

Éditer le fichier /etc/default/docker et modifier la ligne suivante de cette façon :

DOCKER_OPTS="--dns 194.254.200.25 --insecure-registry dev-registry.rpbs.univ-paris-diderot.fr --insecure-registry docker-registry.rpbs.univ-paris-diderot.fr"

Éditer le fichier /lib/systemd/system/docker.service et modifier la section [Service] de façon à ce que les deux lignes suivantes y figurent :

[Service]
EnvironmentFile=-/etc/default/docker
ExecStart=/usr/bin/docker daemon -H fd:// $DOCKER_OPTS

Démarrer le démon docker :

sudo service docker start

Pour utiliser Docker il faut soit posséder les droits administrateur (par exemple en utilisant la commande sudo), soit être présent dans le groupe docker. Pour éviter de devoir taper sudo devant chaque commande, il faut ajouter l'utilisateur au groupe docker :

adduser [ LOGIN ] docker

Exemple :

adduser rey docker

Fedora

Fedora est disponible pour les versions suivantes de Fedora :

  • Fedora 20
  • Fedora 21
  • Fedora 22

Télécharger le paquet correspondant à sa version :

Version Nom du paquet
Fedora 20 docker-engine-1.7.1-1.fc20.x86_64.rpm
Fedora 21 docker-engine-1.7.1-1.fc21.x86_64.rpm
Fedora 22 docker-engine-1.7.1-1.fc22.x86_64.rpm

Installer le paquet :

sudo yum localinstall --nogpgcheck docker-engine-1.7.1-0.1.fc21.x86_64.rpm

Démarrer le démon Docker

sudo service docker start

Afin de pouvoir utiliser les registres, les clients doivent pouvoir résoudre le nom DNS de la machine :

sudo echo "172.27.7.35  dev-registry.rpbs.univ-paris-diderot.fr docker-registry.rpbs.univ-paris-diderot.fr" >> /etc/hosts

Éditer le fichier /etc/sysconfig/docker et modifier la ligne suivante de cette façon :

other_args="--dns 194.254.200.25 --insecure-registry dev-registry.rpbs.univ-paris-diderot.fr --insecure-registry docker-registry.rpbs.univ-paris-diderot.fr"

Pour utiliser Docker il faut soit posséder les droits administrateur (par exemple en utilisant la commande sudo), soit être présent dans le groupe docker. Pour éviter de devoir taper sudo devant chaque commande, il faut créer le groupe docker et ajouter l'utilisateur à ce groupe :

sudo usermod -aG docker [ LOGIN ]

Exemple :

sudo usermod -aG docker rey

Pour que Docker démarre automatiquement au boot du système :

sudo chkconfig docker on

Mac OS (Obsolète)

Docker ne fonctionne pas nativement sous OS X. Il est nécessaire d'installer l'application Boot2Docker qui inclut une machine virtuelle (VM) VirtualBox, le logiciel Docker et l'outil de gestion Boot2Docker :

  1. Se rendre sur la page suivante.
  2. Télécharger Boot2Docker en cliquant sur Boot2Docker-x.x.x.pkg dans la section Download.
  3. Installer Boot2Docker en double-cliquant sur le paquet.

Afin de rendre le client Docker utilisable, il faut le personnaliser. D'abord vérifier que l'application Boot2Docker est lancée en tapant dans un terminal :

docker ps

Si un message d'erreur apparaît :

boot2docker up

Se connecter à la VM Boot2Docker :

boot2docker ssh

Puis éditer le script de démarrage :

touch /var/lib/boot2docker/bootlocal.sh
chmod +x /var/lib/boot2docker/bootlocal.sh
sudo vi /var/lib/boot2docker/bootlocal.sh

Et y copier/coller le contenu suivant :

#!/bin/sh
#Hostname setup
echo "172.27.7.35 dev-registry.rpbs.univ-paris-diderot.fr docker-registry.rpbs.univ-paris-diderot.fr" >> /etc/hosts

Éditer le fichier de configuration du démon Docker

sudo vi /var/lib/boot2docker/profile

Et modifier la ligne suivante :

EXTRA_ARGS="--dns 194.254.200.25 --insecure-registry dev-registry.rpbs.univ-paris-diderot.fr --insecure-registry docker-registry.rpbs.univ-paris-diderot.fr"

Stopper et relancer la VM

exit
boot2docker down
boot2docker up

Vérifier que tout fonctionne en réalisant une recherche sur le registre de développement :

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

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 container en mode intéractif avec les bons uid et gid, en montant le dossier courant et en se plaçant dedans, et supprimer le container à 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

Méthode 1 : mode intéractif

Pour copier des fichiers dans l'image il est nécessaire de monter un dossier. Démarrer un conteneur en mode intéractif à partir d'une image de base (système d'exploitation debian stable), en montant un dossier de la machine hôte (ex : /home/rey/Travail) dans un dossier du conteneur (ex : /opt/Travail) :

docker run -it -v /home/rey/Travail:/opt/Travail debian:stable /bin/bash

Ensuite, réaliser toutes les installations et paramétrages nécessaires :

root@29d4663f7b11:~# _
root@29d4663f7b11:~# apt-get update
root@29d4663f7b11:~# apt-get install gcc make python vim
root@29d4663f7b11:~# cp -r /opt/Travail /usr/local/.

Quitter le conteneur, puis faire un commit pour créer une image à partir du conteneur (utiliser la commande docker ps -a pour avoir la liste des containers fermés ou en cours d'exécution).

docker commit -a [AUTEUR] [ID DU CONTENEUR] [NOM DE L'IMAGE]

Exemple :

docker commit -a "Julien Rey <julien.rey@univ-paris-diderot.fr>" 29d4663f7b11 dev-registry.rpbs.univ-paris-diderot.fr/monimage
Remarque : Il faut tout de suite préciser l'adresse du registre de développement dans le nom de l'image. En cas d'oubli on peut renommer l'image à l'aide la commande docker tag.
Attention : Les dossiers montés lors du lancement du conteneur ne seront pas inclus dans le commit.

Méthode 2 (recommandée) : automatisation à l'aide d'un Dockerfile

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

Écriture du Dockerfile

Voici les différentes instructions à fournir :

FROM debian:wheezy
  • FROM : image de base (ubuntu, debian, etc...).
MAINTAINER Julien Rey <julien.rey@univ-paris-diderot.fr>
  • MAINTAINER : nom et mail du mainteneur de l'image.
ENV CHEMAXON_LICENSE_URL /var/www/.chemaxon/license.cxl
  • ENV : déclaration des variables d'environnement.
COPY src/programs /tmp
COPY src/FAF_PROD /usr/local/FAF-Drugs
COPY src/licence /var/www
  • COPY : copie d'un dossier de la machine locale vers l'image.
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 \
  • RUN : commande à exécuter lors de la construction de l'image.

Quelques autres commandes utiles :

  • ADD : copie d'un fichier de la machine locale vers l'image.
  • 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"]
  • EXPOSE : port(s) à exposer à l'extérieur.

Exemple d'un fichier Dockerfile assez complexe qui permet l'automatisation de l'installation de paquets debian, de bibliothèques python et R, et de code source C à compiler :

FROM debian:wheezy
MAINTAINER Julien Rey 

# Création d'un repertoire pour l'utilisateur www-data (nécessaire pour Mobyle) 
RUN mkdir /var/www && \
chown 33:33 /var/www

# Copie des scripts et des fichiers d'installation
COPY src/programs /tmp
COPY src/FAF_PROD /usr/local/FAF-Drugs
COPY src/licence /var/www

# Déclaration d'une variable d'environnement
ENV CHEMAXON_LICENSE_URL /var/www/.chemaxon/license.cxl

# Don't use dash for compatibility 
RUN ln -sfn /bin/bash /bin/sh

# Installation de paquets debian
RUN sed 's/main$/main contrib/' -i /etc/apt/sources.list && \
apt-get -q -y update && \
apt-get install -q -y \ 
  expect \
  fontconfig \
  g++-4.4 \
  java-package \
  libfontconfig1-dev \
  libpng12-dev \
  pkg-config \
  python-pip \
  python-dev \
  r-base

...

# Extraction, compilation et installation d'un programme
RUN cd /tmp && \
tar xzf openbabel-2.2.3.tar.gz && \
cd openbabel-2.2.3 && \
./configure && \
make && \
make install

...

# Installation d'une bibliothèque R
RUN cd /tmp && \
R CMD INSTALL Cairo_1.5-6.tar.gz

...

# Extraction, construction et installation d'une bibliothèque python
RUN cd /tmp && \
tar xzf matplotlib-1.0.1.tar.gz && \
cd matplotlib-1.0.1 && \
python setup.py build && \
python setup.py install

...

# Installation de bibliothèques python avec pip
RUN pip install "cheetah == 2.4.4" && \
pip install odict && \
pip install PIL && \
pip install "rpy2 == 2.1.2" && \
pip install Pillow

...

# Installation de java
RUN cd /tmp && \
yes "" | su -c 'make-jpkg jre-7u75-linux-x64.tar.gz' nobody && \
dpkg --install oracle-j2re1.7_1.7.0+update75_amd64.deb

...

# Nettoyage des fichiers et des paquets non utiles au fonctionnement du conteneur
RUN apt-get autoremove -q -y g++-4.4 make python-pip && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

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 dev-registry.rpbs.univ-paris-diderot.fr/fpocket .
Remarque : Il faut tout de suite préciser l'adresse du registre de développement dans le nom de l'image. En cas d'oubli on peut renommer l'image à l'aide la commande docker tag.

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.

Usage du réseau

Pour des raisons de surcharge du traffic les conteneurs lancés avec la commande drun sur le cluster n'ont pas accès au réseau. Merci de prendre cet aspect en compte lors des développements.

Remarque : On peut simuler l'absence de réseau sur sa machine en ajoutant l'option --net=none à la commande docker run.

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

Sur le registre de développement

Rien de plus simple, taper la commande :

docker push [NOM DE L'IMAGE]

Exemple :

docker push dev-registry.rpbs.univ-paris-diderot.fr/fpocket
Remarque : L'adresse du registre de développement (dev-registry.rpbs.univ-paris-diderot.fr) doit être contenue dans le nom de l'image.
Attention : Le registre de développement est complètement ouvert en écriture et n'a pour objectif que de réaliser des tests. Un usage raisonné de la ressource est donc demandé. Merci de ne pas multiplier les images identiques en leur donnant des noms différents.

L'image sera alors visible depuis tous les nœuds du cluster de développement.

Remarque : La commande drun vérifie à chaque fois qu'elle est lancée que la version de l'image Docker présente sur le nœud est la plus récente. Il est donc normal de voir s'afficher des messages de Docker avant l'exécution d'un programme : le nœud télécharge la dernière version de l'image avant de démarrer le conteneur :

-bash-4.2$ drun opendocking babel -i protein.pdb -o protein.mol2
Pulling repository dev-registry.rpbs.univ-paris-diderot.fr/opendocking
72b3ea59f87e: Download complete 
511136ea3c5a: Download complete 
30d39e59ffe2: Download complete 
c90d655b99b2: Download complete 
a3c2a3aac44b: Download complete 
1c09cc21a2a4: Download complete 
5bb0dbdb9447: Download complete 
f6ca52397cb1: Download complete 
3271ceeb9fdd: Download complete 
b62621a5c2e4: Download complete 
36e76bea3570: Download complete
Status: Image is up to date for dev-registry.rpbs.univ-paris-diderot.fr/fpocket:latest

De ce fait il n'est pas nécessaire de mettre à jour soi-même les images sur les nœuds du cluster de développement.


Sur le registre de production

Une fois les tests effectués sur le cluster de développement et l'image validée, prendre contact avec un administrateur pour transférer l'image sur le cluster de production.