IT-Admin.tech

Automatisation : configurer une pipeline CI/CD avec GitLab CI, le scan d'images Docker et des rollbacks automatisés

Architekturdiagramm einer CI/CD-Pipeline mit GitLab CI, Trivy Image-Scanning, Container Registry und automatischem...
Schematische Darstellung: GitLab CI, Image-Scanning und Canary-Deploy mit automatischem Rollback in Kubernetes.

Un processus de livraison automatisé et fiable réduit les temps d’arrêt et les erreurs humaines dans l’exploitation des solutions numériques d’entreprise. Dans cet article, j’explique de manière pragmatique comment mettre en place une pipeline CI/CD avec GitLab CI, intégrer le scan des images Docker et implémenter des rollbacks automatisés. L’objectif est une voie d’exploitation maintenable : Build → Test → Scan → Deploy → surveillance → rollback automatique en cas d’erreurs critiques. Le mot-clé principal « pipeline CI/CD avec GitLab CI » est déjà présent dans l’introduction afin de clarifier l’intention de recherche.

Pourquoi une pipeline CI/CD avec GitLab CI ?

GitLab CI est un système CI/CD intégré à GitLab, qui exécute des pipelines basés sur .gitlab-ci.yml. Pour les administrateurs, il est important de noter : GitLab CI orchestre des runners (agents d’exécution), dispose d’intégrations natives de registry et peut se connecter à des outils externes (scan, monitoring). Une pipeline structurée réduit le risque lié au déploiement, automatise les vérifications de sécurité (scan d’images) et permet des déploiements réversibles (rollbacks).

Vue d’architecture et prérequis

L’architecture typique comprend GitLab (repository + CI), GitLab Runners, une container registry (p. ex. GitLab Registry ou un Harbor privé), un outil de scan d’images (p. ex. Trivy, Clair ou GitLabs Container Scanning), un moteur d’orchestration (souvent Kubernetes) et du monitoring/alerting (p. ex. Prometheus + Alertmanager). Les prérequis sont :

  • Instance GitLab avec runners et accès à la registry.
  • Accès authentifiés à la registry (tokens/CI_JOB_TOKEN ou Deploy-Keys).
  • Environnement cible avec API de déploiement (kubectl + Kubeconfig ou Helm).
  • Monitoring avec métriques Health et SLO définies pour la prise de décision.
  • Mécanismes de rollback et playbooks documentés pour les équipes d’exploitation.

Terminologie

CI/CD (Continuous Integration / Continuous Deployment) décrit les étapes automatisées de l’intégration du code jusqu’à la livraison. Le scan d’images vérifie les images de conteneurs pour des vulnérabilités et des erreurs de configuration. Le rollback désigne la restauration d’une modification de déploiement lorsqu’une release est défectueuse. SBOM (Software Bill of Materials) est un inventaire de toutes les composantes d’un artefact et aide les analyses de conformité et de sécurité.

Conception de la pipeline : stages, responsabilités, politiques

Une structure de stages praticable :

  1. prepare : Checkout, préparation des artefacts
  2. build : build d’image et tagging
  3. scan : scan d’images (contrôles de sécurité/politiques)
  4. test : tests unitaires, d’intégration et smoke-tests
  5. deploy : canary / déploiement principal
  6. verify : healthchecks, contrôles de télémétrie
  7. promote / finalize : promotion après canary réussi

Il est important de séparer les responsabilités : les jobs de build et de scan ne doivent pas s’exécuter sur le même runner que les jobs de déploiement en production, afin de minimiser le blast radius et les droits.

Stratégie de tagging des images

Utilisez des tags immuables (p. ex. SHA du commit Git ou semver plus build-id). Les tags mutables comme latest posent problème en production, car ils compliquent la reproductibilité et le rollback.

Exemple .gitlab-ci.yml : minimal, mais sûr en exploitation

L’exemple suivant montre les éléments clés : build, scan avec Trivy, push et deploy dans un cluster Kubernetes. Faites attention aux secrets définis et à une configuration sécurisée des runners.

Yaml
stages:
  - build
  - scan
  - test
  - deploy
  - verify

variables:
  IMAGE_REGISTRY: registry.example.local
  IMAGE_NAME: "$IMAGE_REGISTRY/myapp"
  KUBE_CONTEXT: production

build:
  stage: build
  image: docker:24
  services:
    - docker:dind
  script:
    - docker build -t "$IMAGE_NAME:$CI_COMMIT_SHORT_SHA" .
    - docker push "$IMAGE_NAME:$CI_COMMIT_SHORT_SHA"
  only:
    - main

scan:
  stage: scan
  image: aquasec/trivy:latest
  script:
    - trivy image --severity HIGH,CRITICAL --exit-code 1 --no-progress "$IMAGE_NAME:$CI_COMMIT_SHORT_SHA"
  allow_failure: false

deploy_canary:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl --context="$KUBE_CONTEXT" set image deployment/myapp myapp="$IMAGE_NAME:$CI_COMMIT_SHORT_SHA" --record
    - kubectl --context="$KUBE_CONTEXT" rollout status deployment/myapp --timeout=120s
  when: manual
  only:
    - main

verify_canary:
  stage: verify
  image: curlimages/curl:latest
  script:
    - /usr/local/bin/healthcheck.sh "$KUBE_CONTEXT" "myapp" || exit 1
  allow_failure: false

Pourquoi cela fonctionne : Build produit une image immuable ; Scan interrompt la pipeline en cas de vulnérabilités critiques ; Deploy utilise kubectl pour mettre à jour la ressource Deployment existante ; Verify exécute un healthcheck basé sur des métriques d’exécution ou des smoke-tests. Les erreurs dans Scan/Verify empêchent la promotion automatique en production.

Image-Scanning: Tools, Policies und Fallstricke

Les scanners courants sont Trivy (rapide, basé sur la CLI), Clair (serveur), Grype ou le Container Scanning intégré de GitLab (SAST/DAST). Les scanners fournissent des listes de CVE, des niveaux de gravité et des versions de correction. Choisissez la définition de politique avec soin :

  • Niveaux de gravité bloquants (p. ex. CRITICAL/HIGH) pour les décisions d’abandon automatique.
  • Allow-listing pour les vulnérabilités acceptées mais évaluées (avec processus de revue).
  • Mises à jour régulières de la base de données du scanner (flux de vulnérabilités) – des bases obsolètes génèrent des faux négatifs.

Pièges typiques :

  • Authentification manquante auprès du registre : CI_JOB_TOKEN ou deploy-keys manquants.
  • Le cache d’images dans les runners masque des problèmes : testez les scans contre des images pullées, pas seulement sur des couches locales.
  • Les versions des scanners varient dans les scans CVE – documentez les versions pour l’audit.

Deployment-Strategien und Automatisierte Rollbacks

Les rollbacks automatisés supposent que les déploiements sont réversibles et observables. Stratégies courantes :

  • Blue/Green : environnement parallèle complet, bascule du trafic en cas de succès.
  • Canary : trafic partiel vers la nouvelle release, des métriques observées déterminent la promotion.
  • Rolling update avec readiness-probes : comportement par défaut dans Kubernetes, mais garantie de sécurité limitée sans monitoring.

Rollback-Mechanismen in Kubernetes

Dans Kubernetes, le retour le plus simple est kubectl rollout undo, qui réactive le ReplicaSet précédent. Il est nécessaire que les ReplicaSets soient conservés (default : oui, tant qu’ils ne sont pas explicitement nettoyés). Pour les déploiements Helm, utilisez helm rollback avec des releases enregistrées.

Shell
# Rollback auf letzte Revision (kubectl)
kubectl --context=production rollout undo deployment/myapp

# Helm rollback auf Revision 2
helm --kube-context production rollback myapp 2

Quand cela échoue : les retours en arrière sont inefficaces si les étapes de migration de la base de données ne peuvent pas être annulées de manière compatible ou si des modifications de configuration ne sont pas réversibles. Planifiez les migrations de base de données comme des processus séparés et contrôlés (p. ex. des migrations compatibles en avant et en arrière).

Implémentation d’un déclencheur de rollback automatique

Un rollback automatique ne doit pas être exécuté à l’aveugle. De bons déclencheurs sont :

  • Les smoke-tests (vérifications d’endpoints, flux d’authentification, connectivité DB) échouent.
  • Le taux d’erreur dépasse des seuils définis (p. ex. 5xx > X%).
  • La latence ou le taux de réussite tombe en dessous des valeurs SLA définies.

Techniquement, le déclencheur est implémenté par un job de vérification dans la pipeline ou via du monitoring externe avec un webhook. Exemple d’un script de vérification de santé qui peut être utilisé dans la verify-Stage :

Shell
#!/usr/bin/env bash
# healthcheck.sh: einfache Smoke-Checks für Canary
set -euo pipefail
KUBE_CONTEXT="$1"
DEPLOYMENT="$2"
NAMESPACE="default"
# Beispiel: 3 Versuche, 2 Sekunden Pause
for i in 1 2 3; do
  POD=$(kubectl --context="$KUBE_CONTEXT" -n "$NAMESPACE" get pods -l app="$DEPLOYMENT" -o jsonpath='{.items[0].metadata.name}')
  kubectl --context="$KUBE_CONTEXT" -n "$NAMESPACE" exec "$POD" -- /bin/sh -c 'curl -fsS --max-time 5 http://localhost:8080/healthz' && exit 0 || sleep 2
done
exit 1

Si ce script se termine avec le code de sortie 1, un job de rollback automatique doit être exécuté dans la pipeline ou une alerte doit se déclencher, lançant une action automatisée du runbook.

Extension pratique de la pipeline : job de rollback

Ajoutez le fichier .gitlab-ci.yml un job de rollback dédié qui ne se déclenche qu’en cas d’absence de la verify-Stage. Important : les droits pour effectuer un rollback doivent être RESTrictifs (rôle RBAC avec des permissions minimales), et l’action de rollback doit être idempotente.

Yaml
rollback_on_verify_failure:
  stage: deploy
  image: bitnami/kubectl:latest
  when: on_failure
  script:
    - kubectl --context="$KUBE_CONTEXT" rollout undo deployment/myapp || true
  only:
    - main

Remarque : utilisez when: on_failure de façon ciblée – dans des pipelines complexes, cela peut provoquer des effets secondaires inattendus si plusieurs jobs échouent. Testez le comportement dans un environnement de staging.

CI/CD-Pipeline mit GitLab CI: Betrieb, Skalierung und Governance

La mise à l’échelle et la gouvernance sont aussi importantes en production que la logique de la pipeline. Sujets d’exploitation importants :

  • Mise à l’échelle des runners : activez l’autoscaling des GitLab Runners (p. ex. Kubernetes-Executor ou Docker Machine) pour absorber les pics de charge sans interventions manuelles.
  • Shared vs. Specific Runners : les shared runners sont pratiques, mais augmentent le risque de compétition pour les ressources. Utilisez des runners dédiés pour les jobs de déploiement privilégiés.
  • Audit et conformité : activez les audit logs dans GitLab et conservez les rapports de scan et les SBOM pour les vérifications.

Exemple : extrait d’un config.toml de GitLab Runner pour un Kubernetes-Executor avec autoscaling (représentation simplifiée) :

Ini
[[runners]]
  name = "k8s-runner"
  url = "https://gitlab.example.local/"
  token = ""
  executor = "kubernetes"
  [runners.kubernetes]
    namespace = "gitlab-runner"
    image = "alpine:3.18"
    idle_timeout = 1800
    poll_timeout = 180

Pourquoi cela aide : le Kubernetes-Executor crée un Pod par job et limite ainsi les effets secondaires liés aux hôtes runner partagés. Veillez aux Resource-Requests/Limits afin que les pods de job n’épuisent pas les ressources des nœuds.

Secrets, RBAC et principe du moindre privilège

Les secrets ne doivent jamais être inclus dans l’image. Dans GitLab, utilisez les Protected Variables (masquées, disponibles uniquement dans les branches protégées). Pour les déploiements dans le cluster Kubernetes, utilisez des ServiceAccounts avec des droits RBAC minimaux — et non des Cluster-Admin-Token.

Yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deployer
  namespace: production
rules:
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets"]
  verbs: ["get","list","watch","update","patch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: deployer-binding
  namespace: production
subjects:
- kind: ServiceAccount
  name: ci-deployer
  namespace: gitlab-runner
roleRef:
  kind: Role
  name: deployer
  apiGroup: rbac.authorization.k8s.io

L’exemple Role/RoleBinding ci‑dessous autorise le ServiceAccount uniquement pour les actions de déploiement et de rollback dans le namespace production. Cette granularité réduit le risque lié à la compromission des CI-Tokens.

SBOM, rétention des artefacts et gouvernance du registre

Les SBOM rendent vérifiables les dépendances et les bibliothèques incluses. Trivy peut générer des SBOM ; attachez-les comme artefacts aux jobs de build. Définissez une stratégie de rétention pour les artefacts et les images : une collecte de type garbage-collection trop agressive peut empêcher des rollbacks, des règles trop laxistes remplissent le stockage du registre.

Shell
# Trivy SBOM erzeugen
trivy image --format cyclonedx --output sbom.cdx.json registry.example.local/myapp:$CI_COMMIT_SHORT_SHA

Recommandation : conservez au minimum les N dernières images par service (par ex. N=10) ainsi que les SBOM pendant les durées de conservation légales, si la conformité l’exige.

Observability et intégration Alert-to-CI

Les décisions automatisées reposent sur des métriques. Définissez des règles d’alerte claires dans Prometheus et reliez Alertmanager à un webhook qui appelle un trigger GitLab ou crée un ticket. Exemple d’une AlertRule Prometheus simple (exemple simplifié) :

Yaml
groups:
- name: app.rules
  rules:
  - alert: HighErrorRate
    expr: rate(http_requests_total{job="myapp",status=~"5.."}[2m]) > 0.05
    for: 2m
    labels:
      severity: critical
    annotations:
      summary: "Hohe Fehlerquote bei myapp"
      runbook: "https://wiki.example.local/runbooks/myapp-rollback"

Alertmanager peut, lors du déclenchement, envoyer un webhook vers un endpoint de trigger CI. Assurez-vous que les endpoints de trigger sont sécurisés et que seules les alertes autorisées peuvent déclencher des actions.

Garbage-Collection, caching et remarques sur la performance

Les performances des scanners dépendent fortement de la disponibilité réseau et de la stratégie de cache locale. Évitez que les runners téléchargent continuellement de grosses images en utilisant un cache de registre local ou un proxy. N’utilisez Docker-in-Docker que si l’isolation des runners n’est pas possible autrement ; Kaniko, BuildKit ou Podman sont souvent des alternatives plus sûres pour l’executor Kubernetes.

Stratégie de test et de validation avant le déploiement en production

Testez chaque étape :

  • Valider l’accès des runners et du registre avec des images factices.
  • Vérifier les mises à jour de la DB du scanner et les codes de sortie (Trivy –version, trivy db update).
  • Effectuer plusieurs déploiements et rollbacks en staging ; vérifier les historiques ReplicaSet / Helm Release.
  • Simulez des échecs de health check pour vérifier les rollbacks automatisés.
Shell
# Trivy DB-Update (wichtig vor Scans)
trivy db update

Cas d’erreurs typiques et dépannage

Erreur : les jobs de scan prennent très longtemps ou expirent. Causes : base de données du scanner obsolète, proxy réseau bloquant l’accès aux feeds de vulnérabilités, cache des couches d’image volumineux. Vérifications : contrôler la version du scanner, tester l’accès réseau, vérifier l’exécution du scan de l’image en local.

Erreur : le rollback échoue car les ReplicaSets ont été supprimés. Cause : garbage-collection/cluster-cleanup. Mesures : configurez les politiques du cluster pour conserver les ReplicaSets/releases antérieurs pendant une durée définie.

Erreur : incompatibilité de base de données lors d’un rollback. Cause : migrations qui ne peuvent pas être annulées. Solution : migrations en deux étapes (conçues pour être compatibles vers l’avant), utiliser des Feature-Flags, planifier des stratégies séparées de rollback de base de données.

Runbook: Schnelle Schritt-für-Schritt-Aktionen bei Incident

  1. Vérifier l’alerte : métriques, logs, historique des déploiements.
  2. Isoler : basculer immédiatement le trafic canary ou remettre le service sur les réplicas précédents.
  3. Exécuter le rollback (kubectl rollout undo ou helm rollback).
  4. Post-mortem : analyser la cause, les résultats du scanner, la couverture de tests, les métriques.
  5. Leçons apprises : adapter la pipeline/tests/probes, fournir un correctif.

Fazit: Operative Reife statt nur Automatisierung

Des pipelines CI/CD automatisées avec GitLab CI, un scan intégré des images Docker et des processus de rollback clairement définis réduisent significativement les risques, mais exigent de la discipline : tags d’image immuables, politiques de scanner propres, décisions basées sur l’observabilité et stratégies de base de données compatibles avec le rollback. Testez régulièrement les rollbacks en staging, documentez les runbooks et maintenez des droits d’accès RESTrictifs. Ce n’est qu’ainsi que l’automatisation en exploitation devient réellement résiliente et ne se transforme pas en nouvelle source d’erreurs.

Étapes suivantes : Commencez par un petit proof-of-concept : Build → Trivy-Scan → Canary-Deploy → Verify → Rollback, et étendez progressivement la pipeline avec des contrôles de monitoring et de conformité. Planifiez des exercices réguliers (chaos-tests, rollback-drills) et des audits des politiques des runners/registries.

Le scanning d’images Docker et le déploiement canary sont également importants pour ce sujet. Cet article situe clairement ces aspects et montre ce qui compte au quotidien.

Weiterfuehrend

Passende weitere Inhalte