Serverless vs conteneurs : quelle architecture choisir en 2025 ?
← Retour au blogCloud

Serverless vs conteneurs : quelle architecture choisir en 2025 ?

20 février 20259 min de lectureServerlessConteneursArchitecture

Serverless ou conteneurs ? Ce débat n'est pas tranché. Découvrez les critères de décision, les cas d'usage de chacun et comment combiner les deux dans une architecture moderne.

La fausse dichotomie

La question "serverless ou conteneurs ?" part d'une prémisse erronée. En 2025, les architectures cloud modernes combinent presque toujours les deux paradigmes selon les caractéristiques de chaque composant. L'enjeu n'est pas de choisir un camp, mais de savoir reconnaître quel outil sert le mieux chaque workload. Ce guide vous donne le cadre de décision que nous utilisons avec nos clients.

Caractéristiques fondamentales de chaque paradigme

Serverless (Lambda, Cloud Run, Azure Functions)

Le serverless exécute votre code en réponse à des événements dans des environnements éphémères. Vous ne payez que les invocations réelles — zéro coût au repos. Mais ce modèle implique des contraintes fortes :

  • Durée d'exécution limitée : 15 minutes maximum sur AWS Lambda, 60 minutes sur Cloud Run
  • Cold starts : 50 ms à 3 secondes selon le runtime et la taille du package, à chaque première invocation après une période d'inactivité
  • Facturation à l'invocation : très économique pour les trafics sporadiques, potentiellement coûteux pour les trafics soutenus à haute fréquence
  • Scalabilité automatique : de 0 à des milliers de concurrences sans configuration — c'est à la fois la force et le risque (une boucle infinie peut coûter cher)
  • Stockage éphémère : /tmp limité à 512 MB (10 GB avec Lambda SnapStart), pas d'état entre les invocations

Conteneurs (ECS Fargate, GKE, AKS, Cloud Run Jobs)

Les conteneurs tournent dans des environnements persistants. Le processus démarre une fois et reste actif pour servir de multiples requêtes, ce qui offre des caractéristiques radicalement différentes :

  • Aucune limite de durée : les processus long-running (ML inference, streaming, WebSockets) sont natifs
  • Latence prévisible : pas de cold start, les connexions à la base de données sont persistantes (connection pooling)
  • Contrôle total : runtime personnalisé, bibliothèques système, variables d'environnement, configuration réseau fine
  • Facturation à l'heure : coût fixe même sans trafic — rentable uniquement si le taux d'utilisation est élevé
  • Scalabilité configurée : HPA (Horizontal Pod Autoscaler) ou ECS Service Auto Scaling — la configuration est de votre responsabilité

Tableau de décision — 8 critères

Critère Serverless Conteneurs
Pattern de traficSporadique / pics imprévisiblesContinu / prévisible
Exigences de latenceP99 > 200 ms acceptableP99 < 100 ms requis
Durée d'exécution< 15 minIllimitée
État & connexionsStateless uniquementStateful, connexions persistantes
Modèle de coûtPay-per-use (optimal <5M req/mois)Capacité réservée (optimal >50M req/mois)
Expertise équipeDéveloppeurs orientés fonctionsCompétences Kubernetes/Docker
Vendor lock-inÉlevé (triggers propriétaires)Faible (Docker standard)
Dev localDifficile (SAM, emulation)Simple (docker-compose)

Architecture hybride recommandée

Le pattern le plus efficace que nous déployons consiste à utiliser Lambda pour tout ce qui est asynchrone et événementiel, et Fargate pour les APIs synchrones critiques. Voici un exemple d'architecture e-commerce :

# Architecture hybride e-commerce

# Couche synchrone (Fargate) — latence critique
API REST principale          → ECS Fargate (3 tasks minimum, ALB)
Service d'authentification   → ECS Fargate (connexions DB persistantes)
WebSocket chat               → ECS Fargate (connexions longues durée)

# Couche asynchrone (Lambda) — event-driven
S3 PUT image produit         → Lambda resize + conversion WebP
SQS commande passée          → Lambda validation + envoi email
EventBridge cron 02:00       → Lambda génération rapport nuit
SNS notification paiement    → Lambda mise à jour stock
DynamoDB Streams             → Lambda sync ElasticSearch

# Couche batch (Fargate Spot) — économique
Analytics quotidiens         → ECS Fargate Spot (tâche 45 min)
Export CSV client            → ECS Fargate Spot (tâche > 15 min)
ML inference batch           → ECS Fargate GPU (tâche lourde)

Mitigation des cold starts Lambda

Les cold starts restent le principal frein à l'adoption du serverless pour les APIs critiques. En 2025, les solutions disponibles sont :

# Option 1 : Provisioned Concurrency (Lambda)
# Maintient N instances chaudes — coût : ~$0.015/GB-h
resource "aws_lambda_provisioned_concurrency_config" "api" {
  function_name                  = aws_lambda_function.api.function_name
  qualifier                      = aws_lambda_alias.live.name
  provisioned_concurrent_executions = 5
}

# Option 2 : Lambda SnapStart (Java uniquement)
# Snapshote l'état après l'init — cold start réduit à ~100ms
resource "aws_lambda_function" "java_api" {
  runtime    = "java21"
  snap_start {
    apply_on = "PublishedVersions"
  }
}

# Option 3 : Image conteneur légère (Node.js)
# Dockerfile optimisé pour réduire la taille = cold start plus rapide
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
# Image < 50 MB = cold start < 200ms

Comparaison de coûts : 10 millions de requêtes/mois

Scénario 1 — trafic sporadique (pics 10x la charge de base) :

# Lambda (512 MB, durée moyenne 300 ms)
Compute : 10M × 0.3s × 0.0000000083 $/GB-s × 0.5 GB = 0.01 $
Requêtes : 10M × 0.0000002 $ = 2.00 $
Total Lambda : ~2 $/mois

# Fargate (0.25 vCPU, 0.5 GB, 1 task 24h/24 pour absorber les pics)
vCPU    : 0.25 × 0.04048 $/h × 730 h = 7.39 $
Mémoire : 0.5  × 0.004445 $/h × 730 h = 1.62 $
Total Fargate : ~12 $/mois (1 task)

→ Lambda 6x moins cher pour du trafic sporadique

Scénario 2 — trafic continu (100 req/s en permanence) :

# Lambda (512 MB, durée 200 ms, 259M req/mois)
Compute : 259M × 0.2s × 0.0000000083 × 0.5 = 0.21 $
Requêtes : 259M × 0.0000002 = 51.80 $
Total Lambda : ~52 $/mois

# Fargate (2 tasks 1 vCPU pour tenir 100 req/s)
vCPU    : 2 × 1 × 0.04048 × 730 = 59.10 $
Mémoire : 2 × 2 × 0.004445 × 730 = 12.98 $
Total Fargate : ~72 $/mois (ou ~50 $ avec Savings Plans)

→ Équivalent, mais Fargate offre latence et connexions persistantes

Patterns serverless avancés

Le serverless brille dans les patterns architecturaux asynchrones que les conteneurs gèrent moins élégamment :

  • Fan-out : un événement SNS déclenche simultanément N Lambdas en parallèle — traitement distribué sans orchestration
  • Saga (Step Functions) : orchestration de transactions distribuées avec compensation automatique en cas d'échec
  • Event Sourcing avec EventBridge : les événements métier publiés sur EventBridge déclenchent les consommateurs Lambda sans couplage direct entre services
  • CQRS : DynamoDB Streams → Lambda pour projeter les writes vers des read models optimisés (ElasticSearch, Redis)

Patterns conteneurs avancés

  • Sidecar : conteneur de proxy (Envoy, AWS App Mesh) accolé au conteneur applicatif pour gérer TLS, retry, circuit breaker
  • Service mesh : Istio ou Linkerd pour l'observabilité et la sécurité inter-services sans modifier le code applicatif
  • Blue/Green avec Fargate : ECS + CodeDeploy pour des déploiements sans downtime avec basculement instantané
  • Spot Instances : ECS Fargate Spot pour les workloads tolérants aux interruptions — économie de 70% sur les tâches batch

Conclusion : choisir par forme de trafic, pas par hype

En 2025, la réponse à "serverless ou conteneurs ?" est presque toujours "les deux, selon le workload". La règle d'or : analysez la forme du trafic de chaque composant, pas sa technicité. Un événement S3 qui déclenche un traitement 3 fois par heure → Lambda sans hésitation. Une API qui reçoit 200 requêtes par seconde en permanence avec des connexions PostgreSQL persistantes → Fargate sans hésitation. La mauvaise décision, c'est de forcer un seul paradigme sur toute l'architecture pour simplifier les choix. La bonne architecture choisit le bon outil pour chaque composant et accepte cette hétérogénéité comme une force, pas comme une complexité.

← Retour au blog