Dans mon infra j’utilise gitlab-runner dockerisé pour déployer. Comme j’entrevois de devoir modifier souvent la configuration du service gitlab-runner, il me faut la mettre sous intégration continue au moins et voire en déploiement continue dans un second temps.
Un runner qui s’arrête lui-même
En intégrant le fichier de configuration standard de mon projet blog, le déploiement en environnement staging commence par arrêter le service et là:
docker-compose version 1.24.0, build 0aa59064
docker-py version: 3.7.2
CPython version: 3.6.8
OpenSSL version: OpenSSL 1.1.0j 20 Nov 2018
$ echo "deploy to staging"
deploy to staging
$ docker-compose down
Stopping runner_docker_1 ...
ERROR: Job failed (system failure): aborted: terminated
En effet le job s’execute dans un runner géré par le démon (service) gitlab-runner. En arrêtant le service, on arrête le runner et donc le job.
Un gitlab-runner bootstrap
Le gitlab-runner dockerisé sert à déployer les services. Si lui-même est un service déployable comme un autre, il faut donc un gitlab-runner de démarrage dédié. Ce dernier n’a pas intérêt à être dockerisé car on ne pourrait pas le mettre à jour comme les autres services.
Il faut donc avoir un gitlab-runner dit de bootstrap qui sera une installation système native. Ce dernier enregistera un runner marqué bootstrap qui communiquera avec le docker engine via le lancement d’un conteneur docker-compose.
Mise à jour du service gitlab conteneurisé
La mise à jour du service gitlab promettait de poser le même problème. Si un runner l’arrête, la constructions va s’arrêter. Voilà que je risquais d’atteindre la limite de mon infra à base de gitlab pour déployer !
Il en est rien ! Le runner peut stoper le service gitlab via docker-compose. A ce moment gitlab ne répond plus mais le runner continue de s’exécuter et redémarre le service gitlab. Gitlab est de nouveau disponible et reçoit le résultat du job.
Donc je peux mettre a jour mon service Gitlab via gitlab-runner. Pour cela j’utilise le gitlab-runner conteneurisé mais avec un runner docker utilisant la socket de l’hôte. Dans le schéma plus haut on voit que le gitlab-runner dockerisé gère 2 runner:
- l’un utilisant Dind pour l’intégration continue
- l’autre par socket binding pour le déploiement automatique du service gitlab conteneurisé
Tag de job
J’utilise les tag pour sectionner le bon runner en fonction du stage du job. Chaque runner est caractérisé par une combinaison de tag qui le définit de manière unique.
Voici le fichier docker-compose.yml du service GitLab:
image:
name: docker/compose:1.24.0
entrypoint: [""]
before_script:
- docker info
- docker-compose version
stages:
- build
- test
- staging
- production
run_gitlab:
stage: test
tags:
- dind
- infra
- regular
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
deploy_to_staging:
stage: staging
tags:
- staging
- docker
- regular
script:
- echo "deploy to staging"
- docker-compose down
- docker-compose up -d
only:
- master
deploy_to_infra:
stage: production
tags:
- infra
- docker
- regular
script:
- echo "deploy to dev infra"
- docker-compose down
- docker-compose up -d
only:
- master
when: manual
Dans le cas où le service est le gitlab-runner conteneurisé lui-même, il faut que le job utilise le gitlab-runner natif (que je qualifie de bootstrap). Voici le fichier docker-compose.yml du service gitlab-runner:
image:
name: docker/compose:1.24.0
entrypoint: [""]
before_script:
- docker info
- docker-compose version
stages:
- build
- test
- staging
- production
run_runner:
stage: test
tags:
- dind
- infra
- regular
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
deploy_to_staging:
stage: staging
tags:
- staging
- docker
- bootstrap
script:
- echo "deploy to staging"
- docker-compose down
- docker-compose up -d
only:
- master
deploy_to_production:
stage: production
tags:
- production
- docker
- bootstrap
script:
- echo "deploy to production"
- docker-compose down
- docker-compose up -d
only:
- master
when: manual
deploy_to_infra:
stage: production
tags:
- infra
- docker
- bootstrap
script:
- echo "deploy to dev infra"
- docker-compose down
- docker-compose up -d
only:
- master
when: manual