Infrastructure

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.

CloudCorner6 min de lecture

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 :

  1. L'état désiré du système est déclaratif (manifestes YAML, charts Helm, overlays Kustomize).
  2. Il est versionné dans Git, avec revue de code et historique.
  3. Un agent, dans le cluster, récupère cet état (modèle pull, pas push).
  4. 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, en base commune 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 Secret sont 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/staging et apps/production partagent la même base. 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 revert suffit, Flux réconcilie le cluster vers l'état précédent.
  • Sécurité : plus d'accès kubectl en écriture en production, les droits se gèrent dans Git et par RBAC.
  • Reproductibilité : recréer un cluster, c'est lancer flux bootstrap sur 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 Kustomization et HelmRelease en échec : une réconciliation bloquée en silence est pire qu'un déploiement manuel.
  • Ne pas épingler les versions. Un chart suivi en latest ou 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.

#gitops#flux#kubernetes#infrastructure

Un projet similaire ?

Parlons-en : un expert vous répond sous 24 heures ouvrées.

Nous contacter