Aller au contenu
  1. Posts/

Qu'est-ce qu'une plateforme CaaS et pourquoi nous en avons construit une

Chaque entreprise a son histoire de migration. La nôtre ne parle pas de “passer dans le cloud.” Elle parle de construire ce qu’on aurait aimé trouver quand on a commencé : une plateforme Container-as-a-Service qui rend Kubernetes invisible pour les équipes qui livrent du code dessus.

Ce n’est pas un article “on a adopté Kubernetes et c’est génial.” C’est un retour sur pourquoi on a choisi de construire une plateforme, de quoi elle est faite sous le capot, et ce qu’on a raté en chemin.

Pourquoi on n’a pas simplement “migré dans le cloud” #

Notre point de départ était classique : des workloads sur des machines virtuelles dans des datacenters on-premise. Les problèmes habituels.

Mais ces problèmes se cumulent de façons qu’on ne voit pas tant qu’on ne les a pas vécus pendant des années :

  • Les délais de provisioning tuaient la vélocité. Quand une équipe attend deux semaines pour un environnement, elle ne reste pas les bras croisés. Elle construit des contournements – staging partagé, hacks en local, shadow IT. Le temps que l’infra arrive, l’équipe a déjà livré quelque chose de fragile par-dessus des raccourcis. Ce délai était la cause racine de la moitié de notre dette technique.

  • Chaque équipe avait inventé sa propre pipeline de déploiement. Il n’y avait aucun chemin standardisé, donc chacun faisait à sa manière. L’équipe A utilisait Ansible. L’équipe B avait des scripts bash. L’équipe C déployait en SSH et à la prière. Quand un incident survenait, personne ne pouvait aider une autre équipe à débugger parce qu’aucun système ne fonctionnait de la même manière.

  • Le coût était une boîte noire. Des VMs à 10-15% d’utilisation, des licences pour des logiciels que plus personne ne se rappelait avoir achetés. Quand la direction demandait “combien coûte le service X ?” la réponse était “on ne sait pas, et on ne peut pas le savoir avec notre setup actuel.” Ce genre de réponse, ça détruit la confiance entre l’engineering et le business.

La réaction réflexe face à tout ça, c’est “migrons dans le cloud.” Et on a failli faire cette erreur. Soulever des VMs d’un datacenter vers des instances EC2 résout exactement un problème : on ne gère plus le matériel physique. Tous les autres problèmes – déploiements incohérents, provisioning lent, opacité des coûts, dérive sécuritaire – restent exactement les mêmes. On a juste déplacé notre bazar dans le datacenter de quelqu’un d’autre et on a commencé à payer à l’heure.

On avait besoin de quelque chose de plus haut niveau que de l’infrastructure. On avait besoin d’une plateforme.

Ce que CaaS veut vraiment dire (et pourquoi le terme compte) #

L’industrie parle d’“Internal Developer Platform” ou de “Platform Engineering.” On utilise Container-as-a-Service parce que ça décrit le contrat plus précisément :

  • As-a-Service signifie que les développeurs ne gèrent pas l’infrastructure sous-jacente. Ils ne provisionnent pas de clusters, ne configurent pas de CNI, ne débuggent pas des problèmes de nœuds. C’est le rôle de l’équipe plateforme.
  • Container signifie que l’unité de déploiement est une image container, pas une VM, pas un JAR, pas un zip. Cette contrainte est intentionnelle – elle impose la standardisation.

Un point souvent mal compris : le CaaS n’est pas lié au cloud public. Ça fonctionne tout aussi bien sur du cloud privé ou de l’infrastructure on-premise. L’abstraction est la même que vos clusters tournent sur AWS, sur OpenShift dans votre propre datacenter, ou sur les deux. C’est ce qui le rend pertinent pour les organisations qui ne peuvent pas tout mettre dans le cloud public pour des raisons de réglementation, de souveraineté des données, ou de contrats existants.

La distinction entre “faire tourner Kubernetes” et “faire tourner une plateforme CaaS”, c’est comme donner à quelqu’un un moteur de voiture versus lui donner une voiture. Kubernetes est le moteur. Sans le reste de la voiture autour, la plupart des gens ne vont nulle part.

Si vos développeurs doivent comprendre les internals de Kubernetes pour déployer leur service, vous n’avez pas construit une plateforme. Vous avez construit un cluster Kubernetes et vous l’avez appelé plateforme.

Une plateforme CaaS a une interface claire :

  1. Pousser du code vers un dépôt Git
  2. Ouvrir une PR pour demander de l’infrastructure (namespace, ressources, accès)
  3. Merger et la plateforme provisionne tout automatiquement
  4. Observer via des dashboards et des alertes intégrés

Tout le reste – gestion des clusters, réseau, politiques de sécurité, scaling – c’est la responsabilité de l’équipe plateforme. Cette séparation est tout l’enjeu.

Comment ça se compare #

DC traditionnelVMs Cloud (IaaS)Plateforme CaaS
ProvisioningJours à semainesHeures (si automatisé)Minutes (self-service)
DéploiementSpécifique par équipe, manuelSemi-automatisé, encore par équipeGitOps, standardisé pour toutes les équipes
ScalingLimité par le hardwarePlus rapide mais encore manuelAutomatique (Karpenter, HPA)
Modèle de coûtCapEx, opaqueOpEx, par VM (encore grossier)Par namespace, par équipe, attribuable
CohérenceAucunePossible avec effortImposée par design
SécuritéDépend de la rigueur des équipesDépend de la rigueur des équipesGuardrails imposés par la plateforme
Charge opérationnelleÉlevée (hardware + OS + app)Moyenne (OS + app)Faible pour les équipes (app uniquement)

Regardez la ligne sécurité : les VMs dans le cloud n’ont pas une sécurité faible parce que le cloud est insécure – elles ont une sécurité incohérente parce qu’elle dépend de la rigueur de chaque équipe. Le CaaS rend la sécurité imposable par défaut au lieu d’optionnelle.

À quoi ressemble notre plateforme CaaS #

On n’a pas essayé de tout construire d’un coup. On a commencé avec un fournisseur cloud, une distribution Kubernetes, et on a élargi une fois que les fondations étaient solides.

Infrastructure : Terraform sur AWS (EKS) #

Tout est codifié avec Terraform. VPC, sous-réseaux, rôles IAM, configuration IRSA, clusters EKS. Pas de click-ops, pas d’étapes manuelles, pas de snowflakes.

On a commencé avec EKS sur le cloud public parce que c’est là qu’on avait le plus d’expérience opérationnelle. Notre roadmap inclut OpenShift et Tanzu pour le cloud privé et les environnements on-premise – non pas parce que le multi-distribution est un objectif en soi, mais parce que différentes parties de l’organisation ont des contraintes différentes. Certains workloads ne peuvent pas quitter le datacenter pour des raisons réglementaires. D’autres ont des contrats fournisseurs existants. La plateforme doit couvrir les deux. Le défi est de fournir la même expérience développeur que le cluster tourne sur AWS ou dans notre propre datacenter. C’est plus difficile qu’il n’y paraît, et on n’y est pas encore.

Livraison : ArgoCD et le pattern App of Apps #

Chaque changement passe par Git. On utilise ArgoCD avec le pattern App of Apps comme source de vérité unique pour tout ce qui tourne sur la plateforme.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: platform-apps
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/jelhaouchi/caas-platform-blueprint.git
    targetRevision: HEAD
    path: gitops/platform
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Cette Application racine pointe vers un répertoire d’Applications enfants – chacune gérant un addon plateforme (cert-manager, ingress, monitoring, network policies). ArgoCD réconcilie l’état désiré en continu.

Pourquoi ArgoCD plutôt que Flux ? Honnêtement, les deux marcheraient. On a choisi ArgoCD parce que le pattern App of Apps nous donne une hiérarchie claire (bootstrap → plateforme → tenants), les ApplicationSets rendent l’onboarding des tenants piloté par des templates, et l’UI – bien que non essentielle – aide pendant les investigations d’incidents. La décision est documentée dans un ADR dans notre repo blueprint.

Réseau : Cilium comme CNI #

On a choisi Cilium plutôt que le CNI VPC AWS par défaut. Pas parce que c’est à la mode – parce qu’on avait de vrais problèmes avec le défaut.

Les raisons concrètes :

  • eBPF remplace iptables. À grande échelle, les CNIs basés sur iptables se dégradent. Les chaînes de règles croissent linéairement avec le nombre de services. On voyait déjà des pics de latence lors des mises à jour de politiques sur des clusters avec des centaines de services. Le datapath eBPF de Cilium gère ça au niveau du kernel sans le goulot d’étranglement iptables.

  • Politiques réseau L7. La NetworkPolicy native de Kubernetes ne fonctionne qu’en L3/L4 (IP + port). Avec Cilium, on impose des politiques en L7 – autoriser le trafic vers /api/v1/health mais refuser /admin. C’est essentiel pour le zero-trust, et ça signifie que les équipes n’ont pas besoin d’un service mesh juste pour le contrôle du trafic.

  • Hubble pour l’observabilité réseau. Hubble nous donne une carte de services en temps réel des flux de trafic à travers chaque namespace. Quand un développeur dit “mon service n’arrive pas à joindre la base de données,” on ouvre le flow log Hubble et on voit exactement ce qui est refusé et pourquoi. Avant Cilium, ce genre de debug pouvait prendre des heures. Maintenant c’est l’affaire de quelques minutes.

Le compromis : Cilium ajoute de la complexité opérationnelle. C’est un composant de plus à upgrader, monitorer et comprendre. On a accepté ce compromis parce que les problèmes réseau qu’il résout auraient été plus difficiles à résoudre sans.

Modèle de tenants : namespace-as-a-service #

Les équipes n’ont pas de cluster-admin. Elles obtiennent un namespace – préconfiguré avec du RBAC, des network policies Cilium, des resource quotas et du monitoring par défaut.

L’onboarding d’une nouvelle équipe est une pull request Git :

  1. Ajouter un répertoire dans tenants/ du repo GitOps
  2. Définir le namespace, les rôles RBAC, la network policy et le resource quota
  3. Ouvrir une PR. Review. Merge.
  4. ArgoCD provisionne tout automatiquement

Pas de tickets. Pas de messages Slack à l’équipe plateforme pour demander “vous pouvez nous créer un namespace ?” La PR est la demande. On merge et tout est provisionné.

Observabilité : OpenTelemetry comme fondation #

On est partis sur OpenTelemetry comme standard d’instrumentation pour toute la plateforme. OTel est encore en cours de maturation et l’écosystème de collectors évolue vite, donc ce n’était pas un choix évident. Mais on ne voulait pas de vendor lock-in sur l’observabilité, et on ne voulait pas que les équipes s’instrumentent différemment selon le backend populaire du trimestre.

Le pipeline :

  • OpenTelemetry Collector en DaemonSet sur chaque nœud. Collecte les traces, métriques et logs de tous les workloads via un agent unique.
  • Prometheus pour le stockage de métriques et l’alerting (receiver OTLP activé).
  • Grafana pour les dashboards et la visualisation.
  • Hubble (de Cilium) pour l’observabilité au niveau réseau – ça complète la télémétrie applicative avec des données de trafic au niveau infrastructure.

Chaque namespace de tenant reçoit automatiquement des dashboards et des règles d’alerting de base. Les équipes peuvent les étendre mais ne peuvent pas supprimer la baseline. Avec OpenTelemetry, les équipes instrumentent une fois avec des standards ouverts. Si on décide de remplacer Prometheus par Mimir ou d’ajouter Tempo pour les traces, le code applicatif ne change pas.

Un bémol : le support des logs dans OpenTelemetry est encore en retard. Les traces et les métriques marchent bien. Les logs progressent. On fonctionne avec une approche hybride pour l’instant et on consolidera quand l’écosystème se calmera.

On construit aussi un produit d’observabilité dédié aux pipelines de données – un sujet pour un futur article.

Sécurité : imposer, pas espérer #

Au lieu de publier des guidelines de sécurité en espérant que les équipes les suivent, on les impose au niveau de la plateforme :

  • Network policies – propulsées par Cilium, deny-all par défaut. Les équipes déclarent explicitement quel trafic est autorisé, y compris en L7. Si ce n’est pas déclaré, c’est bloqué.
  • RBAC – scopé aux namespaces, moindre privilège. Aucune équipe n’a d’accès cluster-wide.
  • Application des politiques – OPA/Gatekeeper valide chaque manifest avant qu’il ne soit appliqué. Pas de containers privilégiés. Pas de tags latest. Resource limits obligatoires. Si un manifest viole une politique, il ne se déploie pas – ArgoCD le marque comme dégradé et l’équipe voit exactement pourquoi.

C’est la philosophie “guardrails, pas barrières.” On ne bloque pas les équipes dans leur livraison. On les bloque quand elles tentent de livrer des configurations non sécurisées. Il y a une différence.

Ce qu’on a appris (y compris ce qui a mal tourné) #

Commencer avec un cloud, une distribution. Sérieusement. #

Partir en multi-cloud ou multi-distribution dès le premier jour est un piège à abstractions. On passe des mois à construire une couche de compatibilité pour des problèmes qui n’existent pas encore. On a commencé avec AWS et EKS. On a construit des patterns, documenté les décisions, et validé le tout en production. C’est seulement ensuite qu’on a commencé à planifier OpenShift et Tanzu. Si on avait essayé de supporter trois distributions dès le départ, on serait encore en train de construire la couche d’abstraction au lieu de faire tourner des workloads.

L’expérience développeur est le produit – mais l’adoption est la vraie bataille #

Tout le monde dit “l’expérience développeur compte.” Ce qu’on ne vous dit pas, c’est que même avec une excellente plateforme, les équipes résistent au changement. Elles ont passé des années à construire leur propre outillage. Leurs scripts bash marchent. Leurs playbooks Ansible sont éprouvés. Leur demander de tout lâcher pour faire confiance à un truc qu’elles n’ont pas construit, c’est un problème humain, pas technique.

Ce qui a marché pour nous : on n’a rien imposé. On a commencé avec une équipe volontaire, on a rendu leur vie visiblement meilleure, et les autres équipes ont vu le résultat. Elles sont venues vers nous. Forcer l’adoption, ça ne fait que créer du ressentiment.

Le GitOps est non-négociable – mais la structure du repo va vous hanter #

ArgoCD avec App of Apps est puissant. C’est aussi très facile de créer une structure de repo GitOps qui devient inmaintenable. On a restructuré le nôtre trois fois avant de trouver quelque chose de durable. La leçon : investissez du temps dans l’organisation de votre repo dès le début. Pensez à comment ça scale à 50 équipes, pas juste 5. Je détaillerai notre structure finale dans le prochain article.

La visibilité des coûts a changé la conversation avec la direction #

Dans le datacenter, le coût était une ligne CapEx que personne ne questionnait. Passer au CaaS a rendu le coût visible – et attribuable. Par namespace, par équipe, par workload. Les resource requests et limits ne sont pas juste des contrôles de stabilité ; ce sont les fondations de la responsabilité financière.

Quand les équipes voient ce qu’elles consomment, le comportement change. Les services sur-provisionnés sont redimensionnés – pas parce qu’on a dit aux équipes de le faire, mais parce qu’elles pouvaient voir le gaspillage elles-mêmes. Si je pouvais revenir en arrière et donner un seul conseil : intégrez des dashboards de coûts dans la plateforme dès le premier jour. Rien ne gagne la confiance de la direction plus vite.

Le platform engineering est un travail de produit, pas d’infrastructure #

Vos utilisateurs sont des développeurs. Si vous traitez le CaaS comme un projet d’infrastructure, vous construirez quelque chose de techniquement solide que personne n’utilise. On traite la plateforme comme un produit – backlog, feedback utilisateur, démos, métriques d’adoption. Le succès de l’équipe plateforme, ce n’est pas l’uptime. C’est combien d’équipes livrent dessus et à quelle vitesse elles avancent.

La suite #

C’est le premier article d’une série sur la construction d’une plateforme CaaS en production. À venir :

  • Structurer un dépôt GitOps pour du Kubernetes multi-environnement – l’organisation de repo sur laquelle on a atterri après trois réécritures
  • ArgoCD App of Apps à l’échelle – sync waves, health checks, et les pièges que personne ne documente
  • Patterns de migration DC-vers-CaaS – le playbook pour migrer des workloads hors du datacenter sans tout casser

Je publie aussi en open source le blueprint de notre architecture plateforme :

caas-platform-blueprint – Terraform, ArgoCD, Cilium, et self-service pour les tenants. Le scaffold qu’on aurait aimé avoir quand on a commencé.

Si vous faites quelque chose de similaire – migration de datacenter, construction d’une plateforme interne, tentative de faire disparaître Kubernetes pour vos développeurs – ça m’intéresse vraiment de savoir comment ça se passe. Contactez-moi sur LinkedIn ou suivez ce blog pour les prochains articles.