Installer GitLab Runner : donnez vie à votre pipeline

« J’ai bien envoyé les instructions, alors pourquoi rien ne se passe ? »

La dernière fois, plein d’enthousiasme, j’avais rédigé le fichier .gitlab-ci.yml et l’avais poussé avec push. « Le déploiement va se faire automatiquement maintenant, n’est-ce pas ? », me disais-je avec impatience en cliquant sur le menu ‘CI/CD > Pipelines’ de GitLab.

Mais au lieu d’un joli marqueur vert de réussite, je n’ai vu qu’une barre de chargement qui tournait sans fin et le message de statut ‘Pending (en attente)’. En cliquant sur le message, j’ai découvert cet avertissement :

This job is stuck because the project doesn't have any runners online assigned to it.

En clair : « Une tâche est arrivée, mais aucun travailleur (Runner) ne s’est présenté pour la traiter. » Eh oui, j’avais transmis l’ordre de travail au chef d’usine (le serveur GitLab), mais j’avais oublié d’embaucher l’employé (Runner) qui devait réellement faire le travail à l’usine.

Aussi parfait que soit le plan, sans ‘ouvrier’ pour l’assembler, l’usine ne peut pas tourner.

GitLab Runner : les bras et les jambes de la pipeline

GitLab se compose essentiellement de deux éléments.

  1. GitLab Server (siège / chef d’usine) : il stocke le code, gère l’état des pipelines et donne les ordres.
  2. GitLab Runner (succursale / ouvrier sur le terrain) : installé sur le serveur réel, il reçoit les ordres du siège, récupère le code, effectue le build et exécute les commandes de déploiement.

« Mais pourquoi GitLab ne se connecte-t-il pas tout simplement à mon serveur pour déployer à ma place ? » À bien y réfléchir, ce serait extrêmement dangereux. Si un site web sur Internet (GitLab) pouvait, sur simple clic, se connecter à l’ordinateur situé dans votre chambre (le serveur) et y exécuter n’importe quelle commande, cela reviendrait à du ‘piratage’. Si quelqu’un parvenait à compromettre votre compte GitLab, il pourrait transformer votre serveur en machine à miner du Bitcoin.

C’est pourquoi GitLab ne se connecte jamais directement à votre serveur. À la place, il installe un ‘mandataire identifié (Runner)’ qui n’opère qu’à l’intérieur de votre serveur, et toutes les tâches passent par ce mandataire. Le processus d’installation et d’enregistrement, un peu fastidieux, que nous allons suivre est précisément la ‘procédure de sécurité’ permettant d’authentifier ce mandataire.

Étape 1 : consulter l’offre d’emploi (obtenir le token)

Avant d’installer le runner, il faut d’abord publier au siège (GitLab) une ‘offre d’emploi’ annonçant « notre projet a besoin d’un travailleur », puis récupérer un ‘badge d’identification (Token)’.

Dans les versions récentes de GitLab, la méthode pour consulter le token est légèrement masquée pour des raisons de sécurité.

  1. Accéder au projet GitLab
  2. Menu de gauche : Settings > CI/CD
  3. Dans la section Runners, cliquer sur Expand
  4. Cliquer sur le bouton à trois points (⋮) en haut à droite de la section Project runners

En cliquant sur ce bouton, un menu contextuel s’ouvre avec les informations recherchées. Notez et copiez l’URL et le Registration token.

(Note : un avertissement assez inquiétant peut apparaître : ‘Support for registration tokens is deprecated’. Cela signifie que cette méthode est vouée à disparaître, mais elle reste prise en charge pour des raisons de compatibilité. Pas de panique, copiez simplement le token.)

[Astuce] Plusieurs projets ? (Group Runner) Si, comme moi, vous gérez plusieurs projets – frontend, backend, etc. – regroupés en un seul groupe, enregistrer un runner pour chaque projet n’est pas efficace. Dans ce cas, enregistrez le runner non pas dans les paramètres du projet, mais dans Group Settings > CI/CD. Le ‘Group Runner’ ainsi créé peut traiter à lui seul toutes les tâches de tous les projets du groupe. (Comme j’ai beaucoup de projets, j’ai opté pour cette solution.)

Il faut ouvrir le menu caché (⋮) pour voir le token. Ce token est la ‘clé secrète’ qui relie le runner au serveur ; ne le divulguez jamais.

Étape 2 : embaucher l’ouvrier (installation du Runner)

Installons maintenant concrètement le runner sur un serveur Linux (ou sur votre PC). La méthode la plus propre, sans surprise, consiste à utiliser notre cher ‘Docker’.

# 1. Lancer le conteneur GitLab Runner
docker run -d --name gitlab-runner --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v gitlab-runner-config:/etc/gitlab-runner \
  gitlab/gitlab-runner:latest

  • -v /var/run/docker.sock:/var/run/docker.sock : c’est le point important. Comme le runner doit lancer d’autres conteneurs Docker (pour le build), on lui partage le socket Docker de l’hôte. (Méthode Docker in Docker)

Étape 3 : signer le contrat de travail (enregistrement du Runner)

Installer le runner ne suffit pas. Il faut encore qu’il s’enregistre auprès du serveur GitLab en disant : « Je suis l’ouvrier du projet A. »

Entrons dans le conteneur runner que nous venons de lancer et exécutons la commande d’enregistrement.

# Executer la commande d enregistrement dans le conteneur runner
docker exec -it gitlab-runner gitlab-runner register

Le terminal vous pose alors une série de questions, comme un jeu de devinettes. Saisissez simplement les informations obtenues à l’étape 1.

  1. Enter the GitLab instance URL:
    • https://gitlab.com/ (ou l’adresse de votre GitLab privé)
  2. Enter the registration token:
    • (Collez le token copié tout à l’heure)
  3. Enter a description for the runner:
    • my-runner-01 (n’importe quel nom, du moment qu’il est facile à reconnaître)
  4. Enter tags for the runner:
    • (Vous pouvez passer cette étape en appuyant sur Entrée. Cela sert à ne confier au runner que les tâches portant un tag précis.)
  5. Enter an executor:
    • docker (Comme nous allons faire le build sur Docker, saisissez docker.)
  6. Enter the default Docker image:
    • docker:latest (l’image utilisée par défaut)

« Runner registered successfully. » Si ce message s’affiche, l’embauche est conclue ! Rafraîchissez maintenant l’écran de GitLab : vous verrez le runner avec une lumière verte, criant « Prêt (Online) ».

En cas de connexion réussie, l’indicateur d’état du runner devient vert sur l’écran de GitLab.

Étape 4 : lancement de la pipeline !

Dès que le runner est enregistré, la pipeline qui était en attente (Pending) se met automatiquement en marche. Running… puis, peu après, Passed !

Sans que je ne fasse quoi que ce soit, la machine a lancé les tests, effectué le build, créé l’image et l’a envoyée dans le registre, le tout toute seule. En consultant les logs dans le terminal, j’ai constaté que tout le processus s’était déroulé bien plus rapidement et plus précisément que lorsque je le faisais à la main.

« Waouh… ça marche vraiment ? »

Le déploiement manuel qui prenait 10 minutes se règle désormais en un seul git push. Je peux maintenant lancer un déploiement et aller boire un café tranquillement.

Conseil pratique : problème de permissions Docker (Permission Denied)

Lors de la première configuration du runner, dans 99 % des cas, vous tomberez sur cette erreur : dial unix /var/run/docker.sock: connect: permission denied

Le problème vient du fait que le runner tente d’utiliser des commandes Docker sans en avoir la permission. Dans ce cas, il faut ouvrir le fichier de configuration de gitlab-runner (config.toml) et activer l’option privileged = true.

# /etc/gitlab-runner/config.toml (fichier de config runner)
[[runners]]
  name = "my-runner-01"
  executor = "docker"

[runners.docker]

privileged = true # Mettre cette valeur à true pour que Docker-in-Docker fonctionne correctement. # …

Pour conclure : je peux enfin rentrer chez moi

J’ai enfin mon propre ‘robot de déploiement’. Je peux désormais me concentrer uniquement sur l’écriture du code. Les tâches répétitives et fastidieuses de vérification et de déploiement seront prises en charge par mon fidèle robot (Runner).

Mais il reste un petit 2 % à régler. Pour l’instant, la pipeline s’exécute systématiquement à chaque push sur la branche master. « Et si je voulais déployer automatiquement sur le serveur de développement (dev), mais ne déployer sur le serveur de production (prod) que lorsque j’appuie sur un bouton de validation ? »

La prochaine fois, nous verrons comment piloter la pipeline plus intelligemment, avec les ‘stratégies de déploiement par branche’ et les ‘procédures de validation manuelle (Manual)’.

Laisser un commentaire