blog.bressure.net

Carnet professionnel d'un informaticien

Application, Gestion de projet, Paramétrage

Job GitLab et build docker

admin

Dans mon article d’il y a 3 jours j’ai enfin compris pourquoi depuis mon job de build je ne pouvais pas monter un répertoire du conteneur lancé par le job. Je pensais à tord que DIND me permettait de le faire mais cela n’était qu’un effet de bord de mes multiples build en parallèles que je gérais mal.

Pour comprendre pourquoi ça ne peut pas marcher il suffit de revenir à la définition de ce qu’est un conteneur docker. La job GitLab est un conteneur docker ie un conteneur qui donne accès à la commande docker ie docker-cli. Ce conteneur ligne de commande docker est configuré comme partout par défaut pour communiquer avec le démon docker par /var/run/docker.sock c’est-à-dire qu’il dialogue avec le démon docker local au système. Pour rappel je voulais monter un répertoire /ouput du conteneur en local sur le système qui utilise docker-cli ie celui qui fait docker run !

Ceci est FAUX pour la partie du schéma montrant DIND : output n’est pas sur conteneur job image

Le schéma précédent est donc FAUX et la réalité est plutôt décrite par:

Monter un répertoire c’est monter un répertoire du système où est démon docker

Comment le job peut accéder au données d’un conteneur

Ma problématique est de pouvoir tester le fonctionnement du conteneur lancé par le job dans la phase test du CI/CD. Je veux donc interagir (lire ou écrire) sur avec les données du conteneur. Comme la cinématique d’un test est généralement : exécuter l’objet du test puis vérifier le résultat, mon problème c’est d’aller lire les données produites par le conteneur après son exécution. J’ai donc besoin idéalement d’avoir accès à un volume (persistance) du conteneur.

Les conteneurs c’est l’isolation !

Je pense qu’il y a moyen de modifier la définition du runner pour mapper un répertoire du runner avec un répertoire de l’hôte docker et associer ensuite un répertoire. Mais cela rendrait difficile la parallélisation des job. Mon idée a été plutôt de définir à la volée, quand le job s’exécute un chemin unique parmi les instances d’exécution du job et temporaire sur l’hôte docker. Je passe pour cela par la variable d’environnement du CI/CD $CI_JOB_ID pour nommer le répertoire temporaire créé par mktemp. Dans le cas de DIND l’unicité du chemin sur l’hôte n’est pas nécessaire car un « hôte » docker est instancié par instance du job ! Mais la méthode doit être agnostique de ce fait afin de pouvoir passer d’un build avec DIND à un build sans DIND.

Utiliser docker cp

Cette méthode consiste à un instant donnée (après l’exécution du conteneur) de sortir les données pour les manipuler en dehors du conteneur. Le job du runner a alors le loisir de vérifier la cohérence des données produites avec les attendus du test. On n’a pas besoin de volume pour cela. Il suffit de conserver l’identifiant du conteneur pour exécuter la commande suivante dans le runner

docker cp <cid>:/output/. ./output

Si le test nécessite d’injecter des données dans le conteneur entre 2 étapes d’exécution de son exécution comme pour mettre le conteneur dans un certain état avant le test alors la méthode docker cp peut ne plus être suffisante. Selon la conception du conteneur ce dernier peut être un exécutable one shot. On le lance, il s’exécute et il termine. Dans ce cas la passage par un volume est obligatoire. C’est le cas de mes archétype de génération de projet.

Utiliser un volume

Selon le principe que je décrivais plus haut il suffit de bien choisir le nom du répertoire servant de volume sur l’hôte afin de mapper un répertoire dans le conteneur. Ce volume est alors modifié depuis le job (docker-cli) e,n montant le répertoire en volume d’un autre conteneur de travail. Idéalement il faut lancer le conteneur de travail juste pour avoir un volume de transfert entre le job et le conteneur à tester. C’est la méthode « dockerish »


La mise en œuvre de la technique présentée dans cet article est visible dans le code source de mes projets archétypes notamment celui ci

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Back to top