Sommaire
Un cluster VKS provisionné et opéré ne devient une plateforme que lorsque les équipes applicatives peuvent y déployer sans dépendre du platform team pour chaque release. GitOps est le pattern qui rend ça possible — Argo CD est l’implémentation qui s’est imposée.
Cet article retrace la mise en place pas à pas : bootstrap, App-of-Apps, ApplicationSets pour le multi-cluster, secrets via External Secrets Operator, et patterns multi-tenant. L’objectif est de poser une fondation qui ne se renie pas dans 6 mois quand le périmètre triple.
Audience supposée : tu opères VKS, tu connais kubectl, tu as déjà entendu parler d’Argo CD ou Flux mais tu veux un parcours concret pour démarrer proprement.
Nature de cet article
Patterns testés en production sur des plateformes VKS multi-tenant. Pas une référence Argo CD complète — la doc officielle est excellente. La valeur est dans les choix de structure et les pièges à éviter.
Pourquoi GitOps sur VKS
Trois raisons concrètes, au-delà de la mode.
Auditabilité. Toute modification du cluster passe par un commit Git. Le git log est la source de vérité opérationnelle. Quand un incident remonte “qui a déployé quoi à quelle heure”, la réponse est dans le repo, pas dans la mémoire des équipes.
Cohérence multi-cluster. Avec deux clusters (dev + prod), la dérive est inévitable en mode push manuel. Avec dix clusters (dev + staging + prod × régions), elle est garantie. ApplicationSets éliminent la dérive en synchronisant un manifest unique sur N clusters.
Self-service applicatif. Les équipes applicatives gèrent leur propre repo et leur propre namespace. Elles déclenchent des déploiements sans intervention du platform team. Le platform team conserve la maîtrise du framework — RBAC, politiques, sécurité — mais sort du chemin critique des releases.
Argo CD vs Flux : le choix assumé
Les deux fonctionnent. Choisir l’un ou l’autre engage sur des années — les patterns d’organisation du repo, les outils tiers, les compétences de l’équipe se construisent autour.
Forces — UI riche, App-of-Apps natif, ApplicationSets puissants, Sync Waves intégrés, écosystème large (Notifications, Image Updater, Rollouts).
Limites — composants nombreux, courbe d’apprentissage côté CRDs. La UI peut donner une fausse impression de simplicité — penser GitOps d’abord.
Pour qui — équipes qui veulent une UX lisible pour les développeurs, ou qui ont besoin de patterns multi-cluster avancés.
Forces — design plus modulaire (Source/Kustomize/Helm controllers séparés), pas d’UI par défaut (philosophie “Git c’est l’UI”), intégration native CNCF.
Limites — pas d’UI native (à compenser par d’autres outils), patterns multi-cluster moins explicites qu’avec ApplicationSets.
Pour qui — équipes très orientées CLI/code, contextes où l’absence d’UI est une feature plutôt qu’un manque.
Recommandation assumée. Argo CD pour la plupart des plateformes VKS. La UI réduit drastiquement le ticket-volume vers le platform team (les équipes applicatives debug elles-mêmes leurs sync errors), et ApplicationSets sont le pattern multi-cluster de référence. Flux reste un excellent choix pour des contextes où la philosophie “no UI” est prioritaire.
Bootstrap : la première fois
Démarrer Argo CD sur un cluster VKS prend une vingtaine de minutes. Mais la structure choisie ce jour-là conditionne les six mois suivants.
Étape 1 — Installation. Via Helm, dans un namespace dédié argocd avec les paramètres de base.
# Ajout du repo
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
# Install Argo CD avec High Availability activée
helm install argocd argo/argo-cd \
--namespace argocd \
--create-namespace \
--version 7.7.0 \
--set controller.replicas=2 \
--set repoServer.replicas=2 \
--set redis-ha.enabled=true \
--set server.ingress.enabled=true \
--set server.ingress.hosts[0]=argocd.platform.example.com
Étape 2 — Premier accès. Récupérer le password admin initial puis le rotater immédiatement vers un secret généré ou une intégration SSO.
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
Étape 3 — Connecter le repo Git. Argo CD a besoin d’accéder au repo de configuration. Via SSH key (à privilégier) ou personal access token. Stocker la credential dans un Secret typé argocd-repo.
Étape 4 — App-of-Apps. Créer une première Application qui pointe vers un dossier du repo contenant… d’autres Applications. C’est le pattern fondateur.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root
namespace: argocd
spec:
project: default
source:
repoURL: git@github.com:org/platform-config.git
targetRevision: main
path: bootstrap
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
À partir de cette Application racine, tout le reste se déploie en cascade. C’est ce qui rend l’écosystème scalable.
HA dès le début
Les deux replicas du controller et du repo-server sont l’investissement minimal pour de la production. Avec un seul replica, un upgrade ou un crash interrompt toutes les sync — y compris celles des autres équipes. Le surcoût en CPU/RAM est marginal devant la résilience apportée.
Structure de repo : la décision qui dure
Une mauvaise structure de repo se paie pendant des mois. Trois patterns dominent.
Modèle — un seul repo qui contient tout : platform configs + applications + environnements.
Forces — atomicité des changements transverses, vue unique. Bonne pour les petites équipes.
Limites — RBAC Git complexe (qui peut éditer quoi), CI lent, conflits de merge fréquents quand les équipes grandissent. À abandonner au-delà de 5 équipes applicatives.
Modèle — un repo par équipe ou par application, plus un repo platform.
Forces — RBAC naturel (chaque équipe possède son repo), CI rapide.
Limites — coordination des changements transverses (changer une politique sur N repos = N PRs), risque de drift entre les configs.
Modèle — un repo platform-config (politiques, ApplicationSets, namespaces, RBAC) + un repo par équipe applicative pour leurs manifests.
Forces — sépare les responsabilités platform/app, RBAC clair, changements transverses centralisés. Le sweet spot pour la plupart des plateformes.
Limites — il faut maintenir la cohérence entre les deux niveaux via convention (templates, OPA/Kyverno), un peu plus de plomberie initiale.
Recommandation assumée. Pattern hybride. Le platform team possède platform-config (le source de vérité du cluster). Chaque équipe applicative possède son repo applicatif. ApplicationSets dans platform-config instancient automatiquement une Application Argo CD pour chaque repo applicatif découvert. C’est le modèle qui scale jusqu’à plusieurs dizaines d’équipes sans renégocier la structure.
ApplicationSets : multi-cluster sans douleur
Le composant qui change la perspective. Plutôt qu’écrire 30 Applications à la main pour 30 clusters, on écrit une ApplicationSet qui les génère.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cert-manager-fleet
namespace: argocd
spec:
generators:
- clusters:
selector:
matchLabels:
env: prod # tous les clusters labellisés "env=prod"
template:
metadata:
name: 'cert-manager-{{name}}'
spec:
project: platform
source:
repoURL: git@github.com:org/platform-config.git
targetRevision: main
path: platform/cert-manager
destination:
server: '{{server}}' # injecté par le generator
namespace: cert-manager
syncPolicy:
automated:
prune: true
selfHeal: true
Le pattern. Cluster generator + template = N Applications créées automatiquement. Ajouter un nouveau cluster ne demande qu’une chose : le déclarer comme cluster Argo CD avec les bons labels. L’ApplicationSet le détecte et déploie le bundle de référence dessus.
Combinaisons utiles. Cluster generator + Git generator (un dossier par environnement) = matrice complète. SCM Provider generator pour découvrir automatiquement tous les repos d’une org GitHub avec un label spécifique. Le pattern matrix permet d’éviter le copier-coller massif.
Sync Waves : ne pas zapper
Les ApplicationSets génèrent N Applications, mais l’ordre d’application matter. cert-manager doit être prêt avant que les Applications applicatives demandent des certificats TLS. ExternalDNS doit être prêt avant les Ingress avec annotations DNS. Utiliser les Sync Waves Argo CD (annotations argocd.argoproj.io/sync-wave: “-1”) pour ordonner. Sans Sync Waves, les premiers déploiements échouent en cascade et donnent l’illusion d’une plateforme instable.
Secrets : External Secrets Operator
Un pattern critique. Argo CD lit Git, et Git ne doit jamais contenir de secrets en clair. ESO résout le problème en récupérant les secrets depuis un store externe au moment du déploiement.
# Le SecretStore pointe vers Vault (ou autre)
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: vault-backend
namespace: app-namespace
spec:
provider:
vault:
server: "https://vault.example.com"
path: "kv-v2"
version: "v2"
auth:
kubernetes:
mountPath: "kubernetes-prod-cluster"
role: "app-namespace"
---
# L'ExternalSecret matérialise un Secret Kubernetes depuis Vault
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
namespace: app-namespace
spec:
refreshInterval: 5m
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: db-credentials # le Secret généré
data:
- secretKey: username
remoteRef:
key: prod/db
property: username
- secretKey: password
remoteRef:
key: prod/db
property: password
Le manifest dans Git ne contient que la référence. Les valeurs réelles vivent dans Vault (ou AWS Secrets Manager, GCP Secret Manager, vSphere Secret Store si ESO s’y connecte). Argo CD synchronise la référence, ESO matérialise le Secret. La rotation côté Vault est répercutée automatiquement après le refreshInterval.
Alternatives. Sealed Secrets de Bitnami (chiffrement avec clé du cluster — simple mais le secret reste in-Git, juste chiffré). SOPS via le plugin Argo CD (chiffre/décrypte au vol). ESO est plus opérationnellement satisfaisant à mon sens, mais Sealed Secrets reste un excellent point de départ pour les petites plateformes.
Multi-tenant : RBAC et AppProjects
Argo CD propose le concept d’AppProject pour isoler les tenants au niveau Argo CD lui-même.
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: team-data
namespace: argocd
spec:
description: "Data team workloads"
sourceRepos:
- 'git@github.com:org/team-data-*.git' # repos autorisés
destinations:
- namespace: 'data-*' # namespaces autorisés
server: 'https://kubernetes.default.svc'
clusterResourceWhitelist:
- group: ''
kind: Namespace
namespaceResourceBlacklist:
- group: ''
kind: ResourceQuota # géré par le platform team
roles:
- name: dev
policies:
- p, proj:team-data:dev, applications, sync, team-data/*, allow
- p, proj:team-data:dev, applications, get, team-data/*, allow
groups:
- org:team-data-dev # groupe SSO
Le pattern. Un AppProject par équipe applicative. Source repos restreints, namespaces restreints, certaines ressources interdites (ResourceQuota, NetworkPolicy gérés par le platform team). Les roles mappent vers les groupes SSO. Les développeurs ont accès uniquement à leurs Applications via la UI.
Combiner avec RBAC Kubernetes. AppProjects contrôlent ce qu’Argo CD peut faire au nom de l’équipe. RBAC Kubernetes contrôle ce que l’équipe peut faire avec son kubectl direct. Les deux doivent être cohérents — un dev qui peut bypass Argo CD pour kubectl apply directement casse le modèle GitOps.
Gotchas et patterns à connaître
Auto-prune en prod = couteau à double tranchant
Sync waves mal ordonnées = cascade d'échecs
ApplicationSets : drift entre clusters
ExternalSecret refresh : risque de rate-limit
AppProject permissions trop larges
ImageUpdater : à activer avec discernement
Webhooks Git : monitoring obligatoire
Conclusion
Ce qu’il faut retenir. Argo CD transforme un cluster VKS en plateforme self-service à condition de respecter trois piliers : structure de repo hybride (platform-config + repos applicatifs), ApplicationSets pour le multi-cluster, External Secrets Operator pour les secrets. Les AppProjects et le RBAC SSO délimitent les tenants. Les Sync Waves et l’auto-prune sont les leviers à manier avec discernement. Le bootstrap initial prend quelques heures ; la structure choisie engage pour des années — d’où l’importance de ne pas l’improviser.
Pour la suite. La série de trois articles sur VCF 9 + VKS s’arrête ici. Le prochain cycle traitera de l’industrialisation Terraform/Pulumi sur la plateforme et des patterns Crossplane pour exposer des services VKS comme des ressources Kubernetes natives.
Ressources.
Pour aller plus loin :
- Argo CD Documentation — référence officielle
- Argo CD ApplicationSets — guide complet des generators
- External Secrets Operator — documentation et providers supportés
- Codefresh — Argo CD Best Practices — patterns multi-tenant en production
- GitOps Working Group — principes GitOps formalisés
Reçois le prochain par email
Les nouveaux articles et séries, envoyés à leur publication. Aucun autre courrier.



