Lorsqu'un travail s'exécute sur GitLab, un processus distinct appelé GitLab Runner le récupère, prépare un environnement d'exécution, lance vos scripts et renvoie les résultats. Comprendre comment ce runner est construit et comment il déplace les données vous donne le contrôle sur la stabilité, la vitesse et le dépannage.
Ce guide explique l'architecture de GitLab Runner du point de vue d'un opérateur. Vous découvrirez les composants principaux, la façon dont le contrôle et les données circulent pendant un travail, et où les pannes surviennent généralement. Nous parcourons un chemin sûr pour démarrer avec l'exécuteur shell, puis ajoutons des exemples pratiques avec Docker et Kubernetes. Enfin, nous couvrons les étapes de vérification, les modes de défaillance, la récupération et une liste de contrôle d'opérations reproductible.
Inventaire des versions et de l'environnement
Avant de modifier quoi que ce soit, capturez un inventaire minimal afin de pouvoir reproduire et déboguer :
- Édition et version de GitLab (auto-hébergé ou SaaS)
- Version de GitLab Runner et méthode d'installation
- Système d'exploitation et système d'initialisation pour chaque hôte runner (par exemple, Linux avec systemd)
- Sortie réseau vers GitLab et vers les registres de conteneurs ou stockages d'artefacts
- Types d'exécuteurs prévus (shell, Docker, Kubernetes)
- Jetons, portée et étiquettes des runners
- Limites de concurrence et volume de charge attendu
Commandes utiles pour capturer ces informations sur un hôte runner Linux :
gitlab-runner --version
- Afficher la version du runner :
sudo systemctl status gitlab-runner
- Confirmer l'état du service (exemple systemd) :
uname -a lsb_release -a (si disponible) ou cat /etc/os-release
- Vérifier les bases du système :
curl -I https://gitlab.example.com/ (remplacez par votre hôte)
- Vérifier l'accès HTTPS sortant vers GitLab :
Topologie à noter (texte simple) :
- Où résident les runners (VM unique, flotte de VMs, cluster Kubernetes)
- Si les runners sont partagés ou spécifiques à un projet/groupe
- Attentes d'isolation des exécuteurs (shell hôte vs conteneurs vs pods)
- Chemins de stockage pour les builds, le cache et les artefacts
Vue d'ensemble de l'architecture : composants et rôles
À haut niveau, GitLab Runner interroge en continu l'API du coordinateur GitLab, réclame un travail correspondant à ses étiquettes et permissions, prépare un environnement d'exécution via un exécuteur, lance les scripts du travail, téléverse les artefacts et le cache, et rapporte le statut.
Composants clés et leurs rôles :
- Coordinateur : les endpoints d'API GitLab qui annoncent les travaux et acceptent les résultats
- Gestionnaire du runner : le démon qui interroge pour obtenir du travail et orchestre les exécuteurs
- Exécuteur : l'adaptateur qui exécute réellement le travail (shell, Docker, Kubernetes, etc.)
- Espace de travail : le répertoire builds où les fichiers du travail sont extraits et exécutés
- Cache et artefacts : sorties persistées téléversées après la fin du travail
- Étiquettes et concurrence : boutons de planification qui régissent qui exécute quoi et combien à la fois
| Composant | Rôle | Exemples de paramètres |
|---|---|---|
| Coordinateur (GitLab) | Met en file les travaux et enregistre les résultats | URL, jetons d'enregistrement et de runner |
| Gestionnaire du runner | Interroge pour les travaux et orchestre les exécuteurs | concurrent, check_interval |
| Exécuteur | Exécute les scripts dans un environnement | executor = shell|docker|kubernetes |
| Espace de travail | Stocke l'extraction du dépôt et les fichiers du travail | builds_dir, permissions |
| Cache | Accélère les téléchargements répétés | Backend de cache, clé, chemins |
| Artefacts | Stocke les sorties du travail pour usage ultérieur | Expiration, when, chemins |
Flux de données et flux de contrôle
Flux de contrôle pour un travail unique :
- Un travail entre dans la file d'attente du projet dans GitLab avec les étiquettes et règles requises.
- Le gestionnaire du runner interroge le coordinateur et voit un travail correspondant.
- Le runner réclame le travail et télécharge les métadonnées du travail.
- L'exécuteur prépare l'environnement :
- Shell : bascule vers l'utilisateur de service et prépare l'espace de travail.
- Docker : télécharge l'image si nécessaire, monte les volumes, définit l'environnement.
- Kubernetes : crée un pod avec l'image et les montages spécifiés.
- Le runner récupère le dépôt selon la stratégie (fresh, fetch, ou none) et extrait le commit.
- Le runner exécute les étapes before_script, script et after_script.
- Le runner téléverse les artefacts et le cache si configurés.
- Le runner renvoie les journaux du travail et le statut final à GitLab.
Points clés du flux de données :
- Entrée : métadonnées du travail, variables d'environnement, données du dépôt, et images de conteneurs (si utilisées)
- Exécution : stdout/stderr diffusés vers les journaux du travail, fichiers temporaires dans l'espace de travail
- Sortie : archive d'artefacts et contenu du cache téléversés vers GitLab ou le stockage configuré
Boutons de planification :
- Étiquettes : un travail s'exécute seulement sur un runner qui annonce toutes les étiquettes requises
- Portée protégée : restreint les runners aux refs protégées si activé
- Concurrence : la valeur concurrent limite le nombre de travaux que le runner peut exécuter en parallèle
Paramètres minimaux de config.toml qui affectent le flux de contrôle et le débit :
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
Chemin de configuration sûr : commencer avec l'exécuteur shell
Démarrez avec un pilote simple et auditable sur une seule VM en utilisant l'exécuteur shell. Cela maintient la complexité d'isolation faible pendant que vous validez les étiquettes, la planification, les journaux et la gestion des artefacts.
Prérequis :
- VM Linux avec HTTPS sortant vers votre instance GitLab
- Un utilisateur système dédié, par exemple gitlab-runner
- Un jeton de runner de projet ou groupe et une étiquette unique, par exemple local-shell
Étapes (exemple Debian/Ubuntu) :
- Créez un utilisateur dédié et installez le runner.
sudo useradd --create-home --shell /bin/bash gitlab-runner || true
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt-get install -y gitlab-runner
- Installez et activez le service sous l'utilisateur dédié.
sudo gitlab-runner install --user=gitlab-runner --service=systemd
sudo systemctl enable --now gitlab-runner
- Enregistrez un exécuteur shell avec une étiquette unique.
sudo -u gitlab-runner gitlab-runner register \
--url https://gitlab.example.com/ \
--registration-token VOTRE_JETON_PROJET_OU_GROUPE \
--description "local-shell" \
--tag-list "local-shell" \
--executor shell \
--locked=false \
--run-untagged=false
- Définissez une concurrence conservatrice et confirmez les répertoires.
sudo cp /etc/gitlab-runner/config.toml /etc/gitlab-runner/config.toml.bak
sudo sed -i 's/^concurrent = .*/concurrent = 1/' /etc/gitlab-runner/config.toml
sudo systemctl restart gitlab-runner
Résultats attendus :
systemctl status gitlab-runneraffiche active (running)gitlab-runner listmontre le nouveau runner avec executor: shell- Un travail étiqueté local-shell est récupéré rapidement et s'exécute sur cet hôte
Un travail de vérification minimal (à stocker dans votre projet) pour prouver le comportement de bout en bout :
stages: [verify]
runner_verify:
stage: verify
tags: [local-shell]
script:
- echo "hello from runner on $(hostname)"
- echo "workspace: $PWD"
- uname -a
artifacts:
when: always
expire_in: 1 day
paths:
- verify.log
after_script:
- echo "verification complete" | tee verify.log
Exemple pratique : exécuteur Docker
Passez à l'exécuteur Docker lorsque vous avez besoin de chaînes d'outils isolées et reproductibles. Le runner lance chaque travail dans un conteneur basé sur l'image du travail ou une image par défaut.
Enregistrement (l'hôte runner doit avoir Docker installé et l'utilisateur runner doit avoir accès au socket Docker) :
sudo -u gitlab-runner gitlab-runner register \
--url https://gitlab.example.com/ \
--registration-token VOTRE_JETON \
--description "docker-shared" \
--tag-list "docker" \
--executor docker
Éditez /etc/gitlab-runner/config.toml pour définir des valeurs par défaut saines :
runners
name = "docker-shared"
url = "https://gitlab.example.com/"
token = "REDACTED"
executor = "docker"
[runners.docker]
image = "alpine:3.19"
privileged = false
disable_cache = false
pull_policy = ["if-not-present"]
volumes = ["/cache"]
Un exemple de travail qui utilise ce runner :
stages: [build]
container_build:
stage: build
tags: [docker]
image: alpine:3.19
script:
- apk add --no-cache bash
- echo "build step in container: $(uname -a)"
artifacts:
paths: ["build/output.txt"]
Comparatif des exécuteurs en un coup d'œil :
| Exécuteur | Isolation | Surcharge | Usage typique |
|---|---|---|---|
| shell | Faible (hôte) | Minimale | Pilote rapide, hôtes de confiance |
| docker | Moyenne (conteneur) | Modérée | Chaînes d'outils reproductibles |
| kubernetes | Élevée (pod) | Plus élevée | Mise à l'échelle élastique sur les nœuds |
Exemple pratique : exécuteur Kubernetes
Utilisez l'exécuteur Kubernetes lorsque vous voulez mettre à l'échelle horizontalement sur un cluster. Chaque travail s'exécute dans un pod créé à la demande.
Prérequis :
- Un cluster Kubernetes accessible
- Compte de service avec permissions pour créer des pods dans un namespace choisi
- Sortie réseau du cluster vers GitLab et les registres
Enregistrement et configuration (simplifiés) :
sudo -u gitlab-runner gitlab-runner register \
--url https://gitlab.example.com/ \
--registration-token VOTRE_JETON \
--description "k8s-exec" \
--tag-list "k8s" \
--executor kubernetes
Puis éditez /etc/gitlab-runner/config.toml :
runners
name = "k8s-exec"
url = "https://gitlab.example.com/"
token = "REDACTED"
executor = "kubernetes"
[runners.kubernetes]
namespace = "ci"
image = "alpine:3.19"
service_account = "gitlab-runner"
poll_timeout = 600
Un travail simple pour cet exécuteur :
stages: [test]
cluster_smoke:
stage: test
tags: [k8s]
image: alpine:3.19
script:
- echo "running in k8s pod"
- cat /etc/os-release || true
Comportement attendu :
- Le runner crée un pod par travail dans le namespace ci
- Les journaux sont diffusés vers la page de détails du travail
- Les artefacts sont téléversés vers GitLab quand le pod se termine
Vérification et diagnostics
Confirmez la santé de base après tout changement :
- État du service runner
systemctl status gitlab-runnerjournalctl -u gitlab-runner -n 200 --no-pager
- Enregistrement du runner
gitlab-runner list
- Accessibilité réseau
curl -I https://gitlab.example.com/depuis le runner
- Planification des travaux
- Déclenchez le travail de vérification avec l'étiquette correspondante
- Observez que le travail est récupéré par l'exécuteur attendu
- Artefacts et cache
- Confirmez que l'artefact est attaché au travail
- Si vous utilisez le cache, confirmez les hits de cache sur les exécutions suivantes
Pour une inspection plus approfondie (exemples construits) :
sudo -u gitlab-runner ls -lah /home/gitlab-runner/builds
- Espace de travail de l'exécuteur shell : vérifiez les permissions et l'espace libre
docker info et docker images (sur l'hôte runner)
- Tirages d'images et montages de volumes de l'exécuteur Docker
kubectl -n ci get pods et kubectl -n ci describe pod <nom>
- Événements de pod de l'exécuteur Kubernetes
Résultats de vérification attendus :
- Les travaux étiquetés pour local-shell, docker et k8s sont routés uniquement vers les runners correspondants
- Les journaux du travail affichent les détails d'environnement comme scriptés
- Aucun travail bloqué en pending au-delà de l'intervalle d'interrogation
Modes de défaillance et récupération
Casses courantes et remèdes pratiques :
| Symptôme | Cause probable | Correctif |
|---|---|---|
| Travail reste en Pending | Aucun runner avec les étiquettes correspondantes | Ajoutez la bonne étiquette ou un runner correspondant |
| Runner ne répond pas | Sortie réseau bloquée ou URL incorrecte | Vérifiez l'URL, les certificats et le HTTPS sortant |
| Permission refusée dans l'espace de travail | Mauvais utilisateur ou permissions de répertoire | Assurez-vous que l'utilisateur runner possède le répertoire builds |
| Échec du tirage d'image Docker | Authentification registre ou réseau | Connectez-vous au registre ou ouvrez la sortie |
| Pod Kubernetes en CrashLoopBackOff | Image manquante ou erreur script d'init | Utilisez une image connue fonctionnelle et relancez |
Étapes de récupération exécutables en toute sécurité :
- Mettre en pause ou désenregistrer un runner défaillant
- Mettre en pause dans l'interface GitLab pour isolation rapide
- Ou exécuter :
gitlab-runner unregister --name "local-shell"
- Restaurer une configuration connue fonctionnelle
- Gardez une sauvegarde de /etc/gitlab-runner/config.toml
sudo cp /etc/gitlab-runner/config.toml.bak /etc/gitlab-runner/config.tomlsudo systemctl restart gitlab-runner
- Relancer un travail de vérification minimal
- Confirmez la planification et les journaux avant d'activer plus de concurrence
Conseils de retour arrière :
- Limitez le rayon d'impact en gardant concurrent = 1 pendant les changements
- Utilisez des étiquettes uniques par exécuteur pour rediriger les travaux rapidement
- Revenez au dernier exécuteur fonctionnel (par exemple, shell) pendant que vous corrigez la configuration Docker ou Kubernetes
Liste de contrôle des opérations
Utilisez cette liste après l'installation, après tout changement, et périodiquement :
| Fréquence | Vérification | Commande ou preuve |
|---|---|---|
| Quotidien | Service actif | systemctl status gitlab-runner est active |
| Quotidien | Travaux non bloqués en Pending | Travaux récents démarrent dans le temps attendu |
| Quotidien | Espace disque OK | df -h sur les chemins builds et cache |
| Hebdomadaire | Dérive de version runner | Comparez gitlab-runner --version à la cible |
| Hebdomadaire | Alignement des étiquettes | Les travaux ont des étiquettes correspondant aux runners disponibles |
| Hebdomadaire | Santé artefacts et cache | Artefacts attachés, hits de cache observés |
| Mensuel | Concurrence vs capacité | Ajustez concurrent selon la charge |
| Mensuel | Revue sécurité | Revoyez l'utilisateur runner, volumes et permissions |
Conseils pratiques :
- Gardez un petit travail de vérification que vous pouvez déclencher à la demande pour chaque exécuteur
- Sauvegardez config.toml avant tout changement
- Documentez le mappage des projets aux étiquettes de runners pour un onboarding prévisible
Conclusion
Vous avez vu comment les composants de GitLab Runner s'assemblent, comment le contrôle et les données circulent pendant un travail, et où regarder quand les choses tournent mal. Démarrer avec un pilote étroit d'exécuteur shell vous permet de valider la planification, la journalisation et les artefacts avec un risque minimal. À partir de là, vous pouvez ajouter Docker pour des chaînes d'outils reproductibles et Kubernetes pour une mise à l'échelle élastique. Utilisez les étapes de vérification après chaque changement, surveillez les modes de défaillance courants, et gardez la liste de contrôle à portée de main pour maintenir des opérations prévisibles à mesure que votre utilisation grandit.