J’ai choisi de mettre en place l’intégration continue avec un gitlab-runner conteneurisé et Docker in docker (Dind) pour lancer les commandes docker.
L’avantage du gitlab-runner conteneurisé est de ne pas se soucier de l’installation sur le système hôte qui effectue la construction. Gitlab-runner est un processus client qui communique avec le serveur gitlab afin de récupérer les constructions à faire.
Docker in docker permet de démarrer un démon docker (docker engine) vierge auquel va se connecter le docker CLI (ou docker-compose) pour lancer les conteneurs. Les 2 grosses flèches dans le schémas suivant signifient « lance un processus »
Gitlab-runner en service
Le démon gitlab-runner est lancé en service docker via docker-compose. Dans un repertoire disons runner créer le fichier docker-compose.yml suivant:
version: "3.7"
services:
docker:
image: 'gitlab/gitlab-runner:alpine'
restart: always
volumes:
- '/srv/gitlab-runner/config:/etc/gitlab-runner'
- '/var/run/docker.sock:/var/run/docker.sock'
Le premier volume permet de rendre persistant la configuration tandis que le second permet de se connecter au démon docker de l’hôte. Ainsi le gitlab-runner va pouvoir lancer des conteneurs frères via docker CLI.
Lancer le service par
docker-compose up -d
Il faut ensuite connecter le runner avec gitlab. Pour cela la documentation du gitlab-runner conteneurisé propose de lancer un autre conteneur temporaire qui partage le même répertoire de config persistant sur l’hôte. A par de montrer que les conteneurs peuvent partager un même repertoire, je trouve que cela complique la compréhension. Il est plus simple de se connecter au conteneur que l’on vient de lancer et d’y effectuer la tâche d’administration consistant à enregistrer un nouveau runner.
le démon gitlab-runner peut gérer plusieurs runner.
Determiner le nom du conteneur en faisant un
docker ps
La sortie doit contenir une ligne de la forme
746a1ebc7908 gitlab/gitlab-runner:alpine "/usr/bin/dumb-init …" 3 days ago Up 3 days runner_docker_1
Disposant de cette information, on peut lancer un shell dans le conteneur par
docker exec -it runner_docker_1 bash
On dispose alors d’un shell en tant que root. On doit y entrer la commande:
gitlab-runner register -n --url \n https://gitlab.bressure.net \n --registration-token xxxxxxx-yyyyyyy \n --executor docker \n --description 'docker runner' \n --docker-image 'docker:18.09.06' \n --docker-privileged
et renseigner les informations obligatoires suivantes
- serveur gitlab: https://gitlab.bressure.net
- token de connexion: voir dans l’admin du serveur gitlab pour obtenir un token pour un runner partagé
- type de d’executor: docker
- image par defaut: docker:18.09.06
- utiliser le mode privilégié
Construction docker-compose
L’application est un blog worpdress composée d’un service wordpress et d’un service mysql. Pour mémoire voici son fichier docker-compose.yml
version: '3.3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- www_data:/var/www/html
ports:
- "8180:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
www_data: {}
Comme il n’y a pas d’utilisation d’image docker personnalisées, la construction se limite la phase de test pour vérifier que l’application démarre. On utilise donc l’image docker/compose pour lancer principalement la commande docker-compose up
Voici le fichier CI de gitlab pour le projet blog
image:
name: docker/compose:1.24.0
entrypoint: [""]
before_script:
- docker info
- docker-compose version
run_blog:
stage: test
tags:
- docker
variables:
# For non-Kubernetes executors, we use tcp://docker:2375/
DOCKER_HOST: tcp://docker:2375/
# When using dind, it's wise to use the overlayfs driver for
# improved performance.
DOCKER_DRIVER: overlay2
services:
- docker:dind
script:
- echo "run blog for testing"
- docker-compose up -d
- docker-compose ps
Performances
Ce premier essai avec Dind révèle une première caractéristique. Chaque lancement d’une construction semble utiliser un nouveau conteneur docker. En tout cas il n’y a aucune persistance des images téléchargées. Ainsi à chaque exécution déclenchée par une modification de source (ici le fichier docker-compose.yml) les images de wordpress et mysql sont téléchargées. Avec ma connexion cela prend 5 minutes à chaque fois !
L’utilisation d’un proxy par le démon docker (dockerd) pourra être une solution que je mettrai en œuvre dans le prochain billet qui sera aussi l’occasion de faire du déploiement automatisé en environnement de préprod.
Tags: devOps Docker git
Comments