GitOps avec Flux CD : piloter Kubernetes depuis Git, sans kubectl en production
GitOps avec Flux CD sur Kubernetes : structure de dépôt, Kustomization, HelmRelease, secrets SOPS, promotion entre environnements et validation en CI.
Qui a modifié ce déploiement ? Pourquoi le cluster de production diffère-t-il de celui de recette ? Ces questions reviennent dès que des changements sont appliqués à la main avec kubectl apply. GitOps y répond en déplaçant la vérité du cluster vers Git : l'état souhaité est décrit dans un dépôt, et un contrôleur s'assure en continu que le cluster lui correspond. Flux CD est l'une des implémentations les plus matures de cette approche.
Le principe : Git comme source de vérité
Un déploiement GitOps repose sur quatre idées :
- L'état désiré du système est déclaratif (manifestes YAML, charts Helm, overlays Kustomize).
- Il est versionné dans Git, avec revue de code et historique.
- Un agent, dans le cluster, récupère cet état (modèle pull, pas push).
- Cet agent réconcilie en boucle : si quelqu'un modifie une ressource à la main, Flux la remet dans l'état décrit par Git.
Le modèle pull a un avantage de sécurité considérable : la CI n'a plus besoin d'identifiants d'accès au cluster. Seul Flux, à l'intérieur, détient les droits nécessaires.
Structure de dépôt recommandée
Nous utilisons une organisation simple, qui passe à l'échelle :
.
├── clusters/
│ ├── staging/
│ │ ├── flux-system/
│ │ ├── infrastructure.yaml
│ │ └── apps.yaml
│ └── production/
│ ├── flux-system/
│ ├── infrastructure.yaml
│ └── apps.yaml
├── infrastructure/
│ ├── base/
│ │ ├── ingress-nginx/
│ │ └── cert-manager/
│ ├── staging/
│ └── production/
└── apps/
├── base/
│ └── podinfo/
├── staging/
└── production/
clusters/contient le point d'entrée de chaque cluster : ce que Flux doit synchroniser.infrastructure/regroupe les composants transverses (ingress, cert-manager, monitoring).apps/décrit les applications métier, enbasecommune avec des surcharges par environnement.
Source, Kustomization et HelmRelease
Flux s'appuie sur des ressources personnalisées. La première déclare où lire :
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 1m
url: ssh://git@gitlab.example.org/platform/fleet.git
ref:
branch: main
secretRef:
name: flux-system
La Kustomization indique ensuite quel chemin appliquer, et dans quel ordre :
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 10m
retryInterval: 2m
timeout: 5m
dependsOn:
- name: infrastructure
sourceRef:
kind: GitRepository
name: flux-system
path: ./apps/production
prune: true
wait: true
prune: true supprime du cluster ce qui a disparu de Git, et dependsOn garantit que l'infrastructure (CRD, ingress) est prête avant les applications.
Pour les charts Helm, on déclare le dépôt puis la release :
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: podinfo
namespace: apps
spec:
interval: 1h
url: https://stefanprodan.github.io/podinfo
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: podinfo
namespace: apps
spec:
interval: 15m
chart:
spec:
chart: podinfo
version: "6.x"
sourceRef:
kind: HelmRepository
name: podinfo
values:
replicaCount: 3
ingress:
enabled: true
upgrade:
remediation:
retries: 3
Les options de remediation permettent un retour arrière automatique si une mise à jour Helm échoue.
Gestion des secrets
Ne jamais committer un secret en clair. Deux approches fonctionnent bien avec Flux :
- SOPS : les fichiers
Secretsont chiffrés dans Git (avec age, ou un KMS cloud) et Flux les déchiffre à l'application. C'est simple et auditable, la clé de déchiffrement restant uniquement dans le cluster. - External Secrets Operator : Git ne contient qu'une référence, et l'opérateur récupère la valeur dans Vault, AWS Secrets Manager ou GCP Secret Manager. Idéal quand un gestionnaire de secrets existe déjà.
Avec SOPS, il suffit d'ajouter le déchiffrement à la Kustomization :
spec:
decryption:
provider: sops
secretRef:
name: sops-age
Promotion entre environnements
La promotion devient une opération Git. Deux stratégies courantes :
- Une branche, des dossiers :
apps/stagingetapps/productionpartagent la mêmebase. La promotion consiste à reporter la version d'image ou de chart de l'un vers l'autre, via une merge request. - Automatisation des images : les contrôleurs d'automatisation d'images de Flux détectent un nouveau tag et ouvrent un commit en staging. La production reste validée manuellement.
Dans les deux cas, la production ne change jamais sans un commit relu et approuvé.
Valider en CI avant de fusionner
Une erreur de YAML ne doit jamais atteindre le cluster. Nous validons chaque merge request avec kustomize build et kubeconform :
validate-manifests:
stage: test
image: alpine:3.21
before_script:
- apk add --no-cache kustomize kubeconform
script:
- |
for env in staging production; do
kustomize build "./apps/$env" \
| kubeconform -strict -summary -ignore-missing-schemas \
-schema-location default \
-schema-location "https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json"
done
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
Le catalogue de CRD permet de valider aussi les ressources Flux. Vous pouvez compléter avec flux build kustomization pour tester le rendu exact tel que Flux le verra.
Ce que GitOps change au quotidien
- Audit : chaque modification est un commit signé, relu, daté et attribué.
- Rollback : un
git revertsuffit, Flux réconcilie le cluster vers l'état précédent. - Sécurité : plus d'accès
kubectlen écriture en production, les droits se gèrent dans Git et par RBAC. - Reproductibilité : recréer un cluster, c'est lancer
flux bootstrapsur le même dépôt. - Détection de dérive : toute modification manuelle est corrigée ou signalée.
Pour que l'adoption se passe bien, commencez par un cluster non critique, migrez une application à la fois et gardez un accès d'urgence documenté, en mettant la réconciliation en pause (flux suspend) le temps d'une intervention.
Les pièges à éviter
Quelques erreurs reviennent souvent lors d'une première adoption :
- Mélanger GitOps et modifications manuelles. Une ressource éditée à la main sera écrasée à la prochaine réconciliation, ce qui surprend les équipes. Communiquez la règle dès le départ.
- Un dépôt unique pour tout, sans droits différenciés. Séparez les droits d'écriture entre l'infrastructure et les applications, et protégez la branche principale par des revues obligatoires.
- Oublier la supervision de Flux lui-même. Exposez les métriques des contrôleurs et branchez des alertes sur les
KustomizationetHelmReleaseen échec : une réconciliation bloquée en silence est pire qu'un déploiement manuel. - Ne pas épingler les versions. Un chart suivi en
latestou une plage trop large rend les mises à jour imprévisibles. Préférez des versions explicites, mises à jour par des merge requests automatisées.
Besoin d'un coup de main ?
Structurer un dépôt GitOps, migrer des clusters existants vers Flux ou mettre en place une gestion des secrets robuste sont des chantiers que nous menons régulièrement. Pour en discuter, vous pouvez nous contacter.
Un projet similaire ?
Parlons-en : un expert vous répond sous 24 heures ouvrées.
À lire aussi
Application mobile : native, Flutter, PWA ou Tauri 2, comment choisir ?
Native, cross-platform, PWA ou Tauri 2 : comparatif concret selon l'accès matériel, le hors-ligne, la maintenance et la publication sur les stores.
Sécuriser une pipeline GitLab CI/CD sans ralentir vos livraisons
SAST, scan de dépendances et d'images, secrets, SBOM, signature cosign : comment intégrer la sécurité dans GitLab CI/CD sans freiner vos mises en production.
SEO technique avec Nuxt : le guide pour un site rapide et bien référencé
Rendu SSR ou pré-rendu, useSeoMeta, canoniques, sitemap, JSON-LD, Core Web Vitals : les réglages SEO techniques à maîtriser sur un site Nuxt 4.