n°32
Novembre
2015
Docker & HENP

Le développement logiciel en physique des hautes énergies – en particulier pour les expériences LHC – met en jeu l’assemblage et l’intégration d’un grand nombre de biblio-thèques (externes ou internes, scientifiques ou générales), qui doivent être ensuite compilées, testées et installées sur les machines de production.

De plus, et à cause des ressources limitées disponibles, les logiciels des expériences ne sont testés et déployés que sur un jeu très limité de plateformes, architectures, chaînes de compilation et systèmes d’exploitation. Mécaniquement, l’installation d’un environnement de travail sur une machine de développement avec un système légèrement différent (Debian/CentOS/...), ou bien sur une machine de production exploitant une nouvelle architecture, est généralement un processus itératif chronophage, surtout lorsque les performances natives (sans machine virtuelle) sont requises.

En effet, les machines virtuelles (VM) ont grandement facilité le développement et le déploiement d’applications d’une part, ainsi que la gestion et l’optimisation de l’utilisation de clusters de calcul d’autre part. Cependant, la virtualisation de l’environnement de travail s’est effectuée au prix de performances diminuées par rapport aux performances natives.

Si les VMs offrent une virtualisation au niveau d’une machine entière, les conteneurs offrent quant à eux une virtualisation de l’environnement au niveau du système d’exploitation. Les conteneurs semblent donc mieux répondre aux besoins de la physique nucléaire et des hautes énergies (HENP), l’environnement de production étant essentiellement basé sur des clusters Linux. LXC [1] et OpenVZ [2] ont été les premiers à introduire les conteneurs dans l’écosystème Linux, mais Docker [3] est le projet qui les a réellement popularisés et démocratisés.

Cet article explore les possibles applications des conteneurs Docker aux environnements de travail typiques dans HENP.

Technologies utilisées

Docker est un projet open source écrit en Go [4] pour empaqueter, distribuer et lancer n’importe quelle application à l’intérieur d’un conteneur.

Docker utilise les espaces de nommage (namespaces) Linux, les cgroups [5] et un système de fichiers permettant la fusion de points de montage (unioning) pour isoler les processus. Les images de conteneurs sont similaires aux images de machines virtuelles, mais partagent le noyau Linux avec la machine hôte. Cette configuration met à disposition un système plus léger et permet de provisionner des images de conteneurs en quelques secondes – à comparer aux plusieurs minutes pour les VMs – mais permet également de lancer plusieurs centaines de conteneurs sur une machine de bureau typique.

Grâce aux cgroups, les conteneurs peuvent avoir leurs propres interfaces réseau et sont familièrement vus comme un super-chroot [6], sans avoir recours à une quelconque émulation de matériel – permettant ainsi d’atteindre les performances optimales de la machine physique. Docker utilise également un système de fichiers à plusieurs couches via un système de fichiers d’unioning (UnionFS [7], AUFS [8]) ou via device mapper [9] pour les noyaux Linux sans cette fonctionnalité. Chaque couche du système de fichiers est montée au-dessus des précédentes. La première couche est appelée image de base et contient la collection initiale de fichiers et répertoires mise à disposition par une distribution Linux donnée (Ubuntu, RHEL, Fedora, etc.), distribution qui n’est pas nécessairement la même que celle de la machine hôte. Chaque couche est en lecture seule (seule la dernière couche est modifiable) et seules les différences avec la couche précédente sont stockées sur disque. Les différentes couches sont indexées via un hash à la git (somme de contrôle) et peuvent être partagées et réutilisées par différentes images : cette stratégie permet d’optimiser les ressources de stockage et les performances de provisionnement de disques.

Images Docker

Les images Docker sont créées à partir d’une image de base. Docker met à disposition un nombre important d’images de base officielles (ubuntu, centos, etc.). Ces images peuvent être téléchargées via la commande docker pull comme illustré dans la figure 2.

La liste des images locales peut être consultée en lançant la sous-commande docker images, comme montré dans la figure 3.

Il est également possible de lancer des conteneurs en tâche de fond, le cas typique étant les (micro)services, daemons et serveurs web. La syntaxe est donnée dans la figure 4.

Comme la commande est lancée en tâche de fond, il faut attacher les E/S du terminal au conteneur (0ac942723c25) pour voir les messages s’afficher. La gestion d’un conteneur peut également être effectuée via les sous-commandes start/stop/restart.

Les images Docker peuvent être consultées, publiées et téléchargées depuis le Docker Hub [10] : un registre global d’images officielles et d’images créées par la communauté. Cet index d’images peut être consulté depuis la ligne de commande, comme dans la figure 5, ou bien depuis le web : https://hub.docker.com.

Création d’images personnalisées

Un utilisateur peut créer de nouvelles images de manière interactive. Pour cela, il lui suffit de :

  • lancer un conteneur à partir d’une image de base,
  • lancer des commandes de manière interactive à l’intérieur du conteneur,
  • et sauvegarder l’état actuel du conteneur dans une nouvelle image, comme montré dans la figure 6.

La création d’images en interactif est très utile pendant le développement ou le débogage du processus de création. Cependant, une interface de scriptage est nécessaire pour la reproductibilité du processus de création ainsi que pour son passage à l’échelle. Le projet Docker a donc introduit le concept du fichier Dockerfile et défini ses spécificités. Les fichiers Dockerfile sont ainsi l’équivalent des Makefile [11] pour la création de nouvelles images. La syntaxe de ces fichiers ressemble à celle des scripts shell, avec quelques mots clefs listés et décrits par Dockerfile syntax reference [12].

Le fichier Dockerfile équivalent aux commandes de la figure 6 est reporté dans la figure 7. La nouvelle image correspondant à la recette décrite par le fichier Dockerfile est créée en lançant la commande docker build depuis le répertoire contenant le fichier Dockerfile.

Cas d’usages

Docker est très utile pour un certain nombre de workflows typiques dans HENP. Docker permet en effet :

  • l’encapsulation de la construction de l’entièreté de la pile logicielle d’une expérience, en s’assurant qu’il n’y a aucune dépendance externe implicite cachée,
  • l’installation et le déploiement d’une pile logicielle déjà compilée sur un nombre arbitraire de nœuds et de sites, ainsi qu’une rapide mise en production de cette pile logicielle,
  • la distribution simple et rapide d’environnements de développement.

Docker permet également une répartition plus souple des responsabilités entre les équipes de développement et de production, en adéquation avec la mouvance DevOps [13].

L’équipe de développement peut ainsi choisir la distribution Linux adéquate, le portefeuille de dépendances externes (ainsi que leur version), son cadriciel, etc. sans impact pour l’équipe de production (autre que l’adoption des conteneurs comme outil de mise en production). De son côté, l’équipe de production peut se focaliser sur la gestion des machines, la gestion des logs, la politique de sauvegarde des données, le monitoring, etc. sans interférer avec le processus de développement.

Dans cette optique, un certain nombre d’images de base ont été créées spécifiquement pour la communauté HENP et ont été collectées dans le dépôt gi-thub.com/hepsw/docks. Entre autres :

  • Scientific Linux CERN 5 (hepsw/slc5-base),
  • Scientific Linux CERN 6 (hepsw/slc-base) et,
  • CERN CentOS 7 (hepsw/cc7-base).

Dans ce dépôt se trouvent également les fichiers Dockerfile nécessaires pour la création d’images contenant l’installation binaire du cadriciel Gaudi [14] (hepsw/lhcb-gaudi) et la suite logicielle d’analyse de l’expérience LHCb, Da Vinci (hepsw/lhcb-davinci). Ces images n’ont cependant pas été publiées sur le Docker Hub à cause de leur taille (O(10GB)). Il serait sans doute intéressant d’avoir un hub dédié à la communauté HENP, gérant de façon transparente les certificats grille.

Ce dépôt sert également des images contenant le démon CVMFs correctement installé, configuré et prêt à distribuer la pile logicielle de différentes expériences (ATLAS, CMS, LHCb et LSST).

Conclusions et perspectives

Cet article a présenté Docker et quelques-unes des applications possibles dans la communauté HENP. La ”conteneurisation” de piles logicielles HENP est faisable, et devrait se généraliser et s’accélérer dans le futur. Les conteneurs ne présentent pas de performances dégradées par rapport aux performances natives, et ce, même pour des applications gourmandes en CPU et E/S [15] [16]. De plus, Docker (ou toute autre technologie de virtualisation légère) peut potentiellement faciliter l’optimisation de l’utilisation des clusters de calcul Linux, sans avoir recours aux machines virtuelles.

Un autre usage intéressant de conteneurs est l’empaquetage d’application (et ce sans couplage avec le gestionnaire de paquets de la distribution Linux sous-jacente) ainsi que la préservation des données et de la pile logicielle d’une expérience, permettant la réanalyse ou la réinterprétation des résultats plusieurs années après la fin de cette expérience.

Le paysage de la virtualisation légère est encore en pleine évolution et maturation. Des initiatives telles qu’appc [17], une standardisation du format de conteneurs pour une meilleure interopérabilité, lancée par un concurrent de Docker, rkt [18], ou bien oci [19], l’Open Container Initiative, sont à surveiller. En effet, rkt semble en bonne voie de concurrencer fortement Docker sur le front de la sécurité, ayant un code moins monolithique (et plus facilement auditable, avec des privilèges plus restreints) que ce dernier.

Une saine compétition semble s’engager entre les différents acteurs de la virtualisation légère et devrait profiter à la communauté.

Sébastien BINET (LPC Clermont)

[1] LXC, https://linuxcontainers.org

[2] OpenVZ, https://openvz.org

[3] Docker, http://docker.io

[4] Go, https://golang.org

[5] Linux control groups, http://en.wikipedia.org/wiki/Cgroups

[6] https://wiki.archlinux.fr/Chroot

[7] UnionFS, A Stackable Unification File System, http://unionfs.filesystems.org/

[8] AuFS, advanced multi layered unification filesystem, http://aufs.sourceforge.net/

[9] carte des périphériques

[10] Docker Hub, https://hub.docker.com

[11] http://gl.developpez.com/tutoriel/o...

[12] Dockerfile syntax reference, https://docs.docker.com/reference/b...

[13] DevOps, http://en.wikipedia.org/wiki/DevOps

[14] Barrand G. et al., ”GAUDI – A software architecture and framework for building LHCb data processing applications”, CHEP 2000

[15] KVM and Docker LXC Benchmarking with OpenStack, http://bodenr.blogspot.ch/2014/05/k...

[16] Felter W. et al., ”An Updated Performance Comparison of Virtual Machines and Linux Containers”, RC25482, 2014

[17] App Container Specification and Tooling, https://github.com/appc/spec

[18] rkt, an App Container runtime for Linux, https://github.com/coreos/rkt

[19] The Open Container Initiative, https://www.opencontainers.org

Infrastructure

Docker & HENP
Rechercher
     

Directeur de la publication  : Alain FUCHS.
Responsables éditoriaux : Giovanni LAMANNA et Pierre-Etienne MACCHI.
Comité de rédaction : Frédérique CHOLLET LE FLOUR, Virginie DELEBARRE DUTRUEL, Christian HELFT, Dirk HOFFMANN et Gaëlle SHIFRIN.

logo CCIN2P3
© CCIN2P3