GitOps : L’évolution du déploiement continu

Université de Toulon

LIS UMR CNRS 7020

2026-10-06

Qu’est-ce que GitOps ?

GitOps = Git + Operations : Git comme interface de contrôle pour l’infrastructure

%%{init: {
"theme": "base",
"themeVariables": {
"background": "#F7F9FC",
"primaryTextColor": "#2F2F2F",
"lineColor": "#B8C4CC",
"fontFamily": "Inter, Arial"
}
}}%%

graph LR
    A[👨‍💻 Developer] --> B[Git Commit]
    B --> C[Git Repository<br/>Single Source of Truth]
    C --> D[🤖 GitOps Operator<br/>ArgoCD/Flux]
    D --> E[☸️ Kubernetes]
    E --> F[🚀 Production]
    
    E -.->|Observe| D
    D -.->|Compare & Sync| C
    
    classDef git fill:#CDE7F0,stroke:#9FC7D8,stroke-width:2px,color:#2F2F2F
    classDef operator fill:#F5E6FF,stroke:#D4B8E8,stroke-width:2px,color:#2F2F2F
    classDef k8s fill:#DFF2E1,stroke:#A8D5B5,stroke-width:2px,color:#2F2F2F
    
    class C git
    class D operator
    class E k8s

GitOps est une méthodologie de déploiement où :

  1. Git = source de vérité
    • Tout est versionné dans Git
    • Infrastructure, apps, config
  2. Déclaratif
    • On décrit l’état désiré
    • Pas de scripts impératifs
  1. Automatique
    • Réconciliation continue
    • Self-healing
  2. Observable
    • État actuel = Git
    • Audit trail complet

L’évolution : De CI/CD traditionnel à GitOps

🔨 Génération 1 : Manuel

%%{init: {
"theme": "base",
"themeVariables": {
"background": "#F7F9FC",
"primaryTextColor": "#2F2F2F",
"lineColor": "#B8C4CC",
"fontFamily": "Inter, Arial"
}
}}%%

graph TD
    A[Developer] --> B[SSH Server]
    B --> C[Manual Commands]
    C --> D[Production]
    
    classDef manual fill:#FFE6E6,stroke:#E5A3A3,stroke-width:2px,color:#2F2F2F
    class C manual

  • Scripts shell

  • SSH manuelle

  • Restart services

  • ❌ Erreurs humaines

  • ❌ Pas reproductible

  • ❌ Pas d’historique

Problèmes :

  • Erreur humaine (mauvais fichier, mauvais serveur)
  • Pas de rollback facile
  • Pas d’historique des changements
  • Documentation outdated
  • “Snowflake servers” (chaque serveur différent)

⚙️ Génération 2 : CI/CD Push

%%{init: {
"theme": "base",
"themeVariables": {
"background": "#F7F9FC",
"primaryTextColor": "#2F2F2F",
"lineColor": "#B8C4CC",
"fontFamily": "Inter, Arial"
}
}}%%

graph TD
    A[Git Push] --> B[CI Pipeline]
    B --> C[Build & Test]
    C --> D[kubectl apply]
    D --> E[Kubernetes]
    
    classDef ci fill:#DFF2E1,stroke:#A8D5B5,stroke-width:2px,color:#2F2F2F
    classDef push fill:#FFF1D6,stroke:#E5CFA3,stroke-width:2px,color:#2F2F2F
    class B ci
    class D push

  • Automatisé

  • Tests intégrés

  • Pipeline as code

  • ⚠️ Push = one-way

  • ⚠️ Drift possible

  • ⚠️ Credentials dans CI

Améliorations :

  • Automatisation complète
  • Tests avant déploiement
  • Infrastructure as Code
  • Reproductible

Mais encore des problèmes :

  1. Configuration drift:
    • Changements manuels non détectés
    • État réel ≠ État désiré
  2. Security:
    • Credentials dans CI/CD
    • Risque si CI compromis
  3. One-way sync :
    • CI pousse vers K8s
    • Pas de feedback loop
  4. Disaster Recovery :
    • Cluster détruit → comment reconstruire ?
    • Pas de garantie Git = Production

🚀 Génération 3 : GitOps

%%{init: {
"theme": "base",
"themeVariables": {
"background": "#F7F9FC",
"primaryTextColor": "#2F2F2F",
"lineColor": "#B8C4CC",
"fontFamily": "Inter, Arial"
}
}}%%

graph TD
    A[Git Push] --> B[Config Repo]
    B <-.->|Pull & Sync| C[GitOps Operator]
    C --> D[Kubernetes]
    D -.->|Observe| C
    
    classDef git fill:#CDE7F0,stroke:#9FC7D8,stroke-width:2px,color:#2F2F2F
    classDef operator fill:#F5E6FF,stroke:#D4B8E8,stroke-width:2px,color:#2F2F2F
    class B git
    class C operator

  • Git = source de vérité

  • Pull continuous

  • Self-healing

  • Audit complet

  • ✅ Déclaratif

  • ✅ Convergence auto

  • ✅ Secure by design

Principes clés :

  1. Git = Single Source of Truth:
  • Toute la config dans Git
  1. Pull model :
  • GitOps operator pull config
  1. Continuous reconciliation :
  • Compare état réel vs désiré
  • Applique changements automatiquement
  1. Cryptographically signed commits :
  • Sécurité renforcée

Exemple concret

Quelqu’un fait un changement manuel :

kubectl scale deployment myapp --replicas=10

CI/CD traditionnel : Rien ne se passe, drift permanent

GitOps :

  • ArgoCD détecte : Git dit 3 replicas, K8s a 10
  • Status “OutOfSync”
  • Auto-sync (si activé) → Revient à 3 replicas
  • Notification “Manual change detected and corrected”

Les 4 principes de GitOps

OpenGitOps : Les principes fondamentaux

1️⃣ Déclaratif

# Pas "comment faire"
# Mais "quel état je veux"
apiVersion: apps/v1
kind: Deployment
spec:
  replicas: 3  # État désiré
  template:
    spec:
      containers:
      - image: myapp:v1.2.3

✅ Reproductible ✅ Idempotent ✅ Versionnable

2️⃣ Versionné et Immutable

git log --oneline
abc123 Update to v1.2.3
def456 Scale to 5 replicas
789abc Add health check

✅ Historique complet ✅ Rollback facile ✅ Audit trail

3️⃣ Pulled Automatiquement

%%{init: {
"theme": "base",
"themeVariables": {
"background": "#F7F9FC",
"primaryTextColor": "#2F2F2F",
"lineColor": "#B8C4CC",
"fontFamily": "Inter, Arial"
}
}}%%

graph LR
    A[Git Repo] <--> B[GitOps<br/>Operator]
    B --> C[Kubernetes]
    C -.->|Observe| B
    
    classDef git fill:#CDE7F0,stroke:#9FC7D8,stroke-width:2px,color:#2F2F2F
    classDef operator fill:#F5E6FF,stroke:#D4B8E8,stroke-width:2px,color:#2F2F2F
    class A git
    class B operator

✅ No push access needed ✅ Continuous sync ✅ Self-healing

4️⃣ Réconciliation Continue

%%{init: {
"theme": "base",
"themeVariables": {
"background": "#F7F9FC",
"primaryTextColor": "#2F2F2F",
"lineColor": "#B8C4CC",
"fontFamily": "Inter, Arial"
}
}}%%

graph TB
    A[Desired State<br/>Git] --> B{Compare}
    C[Actual State<br/>Cluster] --> B
    B --> D{Diff?}
    D -->|Yes| E[Apply Changes]
    D -->|No| F[Nothing]
    E --> C
    
    classDef action fill:#DFF2E1,stroke:#A8D5B5,stroke-width:2px,color:#2F2F2F
    class E action

✅ Auto-correction ✅ Drift detection ✅ Guaranteed convergence

Séparation Application Code vs Configuration Code

Deux repositories distincts : Une bonne pratique GitOps

📦 Application Repository

my-app-repo/
├── src/
│   └── main/
│       └── java/
├── tests/
├── pom.xml
├── Dockerfile
└── .github/
    └── workflows/
        └── ci.yml

Contenu : - Code source (Java, Python, Go…) - Tests unitaires & intégration - Dockerfile - CI pipeline

Responsabilité : - Developers - Build & test - Create Docker image - Push to registry

⚙️ GitOps Repository

gitops-repo/
├── apps/
│   └── my-app/
│       ├── deployment.yaml
│       ├── service.yaml
│       ├── ingress.yaml
│       └── configmap.yaml
├── infrastructure/
└── environments/
    ├── dev/
    ├── staging/
    └── production/

Contenu : - Kubernetes manifests - Helm charts / Kustomize - Configuration

Responsabilité : - Platform team / SRE - Deployment config - Infrastructure - ArgoCD/Flux watches this

Progressive Delivery avec GitOps

Stratégies de déploiement avancées : Canary et Blue/Green

%%{init: {
"theme": "base",
"themeVariables": {
"background": "#F7F9FC",
"primaryTextColor": "#2F2F2F",
"lineColor": "#B8C4CC",
"fontFamily": "Inter, Arial"
}
}}%%

graph TB
    A[v1.0 Stable<br/>90% traffic] --> C[Load Balancer]
    B[v2.0 Canary<br/>10% traffic] --> C
    C --> D[Monitor Metrics]
    D --> E{Success?}
    E -->|✅ Yes| F[Scale v2.0 to 100%]
    E -->|❌ No| G[Rollback to v1.0]
    
    classDef stable fill:#E8F5E9,stroke:#B8D8BA,stroke-width:2px,color:#2F2F2F
    classDef canary fill:#FFF1D6,stroke:#E5CFA3,stroke-width:2px,color:#2F2F2F
    classDef rollback fill:#FFE6E6,stroke:#E5A3A3,stroke-width:2px,color:#2F2F2F
    
    class A stable
    class B canary
    class G rollback

Principe : Déploiement progressif

🐤 Canary Deployment : Déploiement d’une nouvelle version à un petit pourcentage d’utilisateurs avant de l’étendre.

  1. v2.0 déployé pour 10% users
  2. Monitoring (erreurs, latence)
  3. Si OK → 25%, 50%, 100%
  4. Si KO → Rollback immédiat

GitOps : Changer replicas progressivement dans Git

🔵🟢 Blue/Green Deployment

%%{init: {
"theme": "base",
"themeVariables": {
"background": "#F7F9FC",
"primaryTextColor": "#2F2F2F",
"lineColor": "#B8C4CC",
"fontFamily": "Inter, Arial"
}
}}%%

graph TB
    A[Blue Environment<br/>v1.0 PROD] --> C[Load Balancer]
    B[Green Environment<br/>v2.0 STAGING] 
    C --> D{Switch Traffic}
    D -->|Deploy| E[Green becomes PROD]
    D -->|If issues| F[Switch back to Blue]
    
    classDef blue fill:#CDE7F0,stroke:#9FC7D8,stroke-width:2px,color:#2F2F2F
    classDef green fill:#DFF2E1,stroke:#A8D5B5,stroke-width:2px,color:#2F2F2F
    
    class A,F blue
    class B,E green

Principe : Deux environnements identiques

  1. Blue (v1.0) = Production actuelle
  2. Green (v2.0) = Nouvelle version testée
  3. Switch load balancer Blue → Green
  4. Rollback = Switch Green → Blue

GitOps : Basculer Ingress/Service dans Git

Outils GitOps principaux

ArgoCD et Flux : Les deux leaders

ArgoCD 🐙

  • UI/Dashboard riche
  • Créé par Intuit (2018)
  • CNCF Graduated
  • Multi-cluster natif
  • CLI puissant
  • SSO intégré

Avantages : ✅ Interface graphique ✅ Facile à démarrer ✅ Écosystème plugins

Usage : Équipes préférant UI, multi-tenancy

Flux 🌊

  • GitOps Toolkit modulaire
  • Créé par Weaveworks (2016)
  • CNCF Graduated
  • Approche “toolkit”
  • CLI flux
  • Notifications avancées

Avantages : ✅ Léger et composable ✅ Helm natif ✅ Progressive delivery

Usage : Équipes cloud-native, automation

Avantages de GitOps

Les bénéfices concrets de l’approche GitOps

🔒 Sécurité

  • Pas de credentials externes
  • Audit trail complet
  • Commits signés
  • RBAC via Git

📜 Traçabilité

  • Historique complet dans Git
  • Qui, quoi, quand, pourquoi
  • Compliance (SOC2, ISO27001)

🔄 Rollback instantané

  • git revert = rollback production
  • Retour à n’importe quelle version
  • Pas de procédure complexe

🛡️ Fiabilité

  • Self-healing automatique
  • Drift detection
  • État convergent garanti

🚀 Productivité

  • Déploiements reproductibles
  • Multi-environnements facile
  • Disaster recovery simplifié

👥 Collaboration

  • Pull Request (PR) = Review process
  • GitOps Repo = Documentation vivante
  • Changements atomiques et versionnés

Quand adopter GitOps ?

GitOps est idéal si…

✅ Vous devriez utiliser GitOps si :

  • Déploiements sur Kubernetes
  • Besoin d’audit trail complet
  • Multi-environnements (dev/staging/prod)
  • Équipe cloud-native
  • Besoin de self-healing
  • Compliance stricte (finance, santé)
  • Multi-cluster management

Cas d’usage typiques : - Microservices sur K8s - SaaS multi-tenant - Infra as Code (IaC) - Platform engineering

⚠️ GitOps peut être overkill si :

  • Applications monolithiques
  • Déploiement sur VMs traditionnelles
  • Pas de Kubernetes
  • Très petite équipe (1-2 devs)
  • Déploiements rares
  • Environnement unique

Alternatives : - CI/CD classique (GitHub Actions, GitLab CI) - Scripts Ansible - Docker Compose pour dev/staging - Cloud-native solutions (AWS ECS, Cloud Run)