Microservices - 04 - L'infra : Docker, orchestration et service discovery

L'infrastructure des microservices : Docker Compose pour le dev, Kubernetes pour la prod, service discovery et reverse proxy.

04 - L'infra : Docker, orchestration et service discovery

Ce que tu vas apprendre

  • Comment faire tourner des microservices en local et en production
  • Le service discovery : comment un service trouve les autres
  • L'observabilité : logs, traces, metriques

Prerequisites

03 - Communication inter-services


Docker Compose : le dev local

En local, Docker Compose est le standard. Chaque service est un container, ils partagent un réseau Docker, et tu lances tout avec une commande.

C'est exactement ce que fait paltemps.fr aujourd'hui en monolithe : un container Bun, un container Caddy, un container base de donnees, le tout dans un docker-compose.yml. Si on devait ajouter des microservices, ca ressemblerait a ca :

yaml# docker-compose.yml
services:
  gateway:
    image: caddy:2
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - api
      - scraper

  api:
    build: ./services/api
    environment:
      - DATABASE_URL=postgres://db:5432/api
      - SCRAPER_URL=scraper:50051
    depends_on:
      - db

  scraper:
    build: ./services/scraper
    environment:
      - DATABASE_URL=postgres://db:5432/scraper
    ports:
      - "50051:50051"

  db:
    image: postgres:16
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Docker Compose gere le service discovery automatiquement : chaque service est accessible par son nom (scraper, api, db). Pas besoin de Consul ou d'etcd. Le DNS interne de Docker fait le job.

Limites de Docker Compose : pas de scaling automatique, pas de self-healing (si un container tombe, il reste tombe sauf avec restart: always), pas de rolling updates. C'est parfait pour le dev et pour les petites productions. Pas pour 50 services en prod.

Kubernetes : quand tu en as vraiment besoin

Kubernetes (K8s), c'est l'orchestrateur de containers le plus utilise. Il gere le scaling, le self-healing, les rolling updates, le service discovery, le load balancing, et la gestion des secrets. C'est aussi un monstre de complexité.

Ce que Kubernetes fait bien :

  • Scaling automatique : tu définis des regles (CPU > 80% = ajouter une instance) et K8s s'en occupe
  • Self-healing : si un container tombe, K8s en relance un automatiquement
  • Rolling updates : déploiement zero-downtime par défaut
  • Service discovery : chaque service a un DNS interne (scraper.default.svc.cluster.local)

Ce que Kubernetes coûte :

  • Une courbe d'apprentissage de plusieurs mois pour l'équipe
  • Un cluster a maintenir (ou un service manage type GKE/EKS/AKS)
  • Des fichiers YAML a n'en plus finir
  • Un besoin en RAM et CPU juste pour faire tourner K8s lui-meme

Mon opinion : ne deploie pas Kubernetes avant d'avoir au moins 5 services en production et une personne dédiée aux ops (ou un budget pour un cluster manage). Avant ca, Docker Compose avec un bon pipeline CI/CD fait le travail.

Pour les projets de taille intermediaire (3-8 services), Docker Swarm ou Nomad de HashiCorp sont des alternatives plus simples. Moins de features que K8s, mais aussi moins de YAML a écrire.

Service discovery

Comment le service "commandes" trouve-t-il le service "catalogue" ? C'est la question du service discovery.

DNS-based (Docker / Kubernetes) : chaque container a un hostname. Tu appelles http://catalogue:3000 et le DNS resout. C'est le plus simple. Ca marche en Docker Compose et en Kubernetes sans rien configurer.

Consul (HashiCorp) : un registre de services dédié. Chaque service s'enregistre au démarrage et Consul gere la découverte, le health checking, et le key-value store. Utile si tu n'es pas sur Kubernetes mais que tu as besoin de features avancees (service mesh, mTLS).

Le pattern API Gateway : un point d'entree unique qui route les requêtes vers les bons services. Caddy, Kong, Traefik, ou un Envoy. Le client ne connaît que le gateway, jamais les services individuels.

[Client] --> [API Gateway (Caddy/Kong)]
                 ├── /api/products/*  --> [Service Catalogue]
                 ├── /api/orders/*    --> [Service Commandes]
                 └── /api/users/*     --> [Service Auth]

Sur paltemps.fr, Caddy joue deja ce rôle de reverse proxy pour router les sous-domaines. En microservices, il deviendrait un API Gateway a part entière.

Health checks et circuit breakers

Deux patterns indispensables en microservices.

Health checks : chaque service expose un endpoint /health qui répond 200 si tout va bien. L'orchestrateur (Docker, K8s) ou le load balancer interroge ce endpoint régulièrement. Si un service ne répond plus, il est retire du routing.

typescript// Endpoint health check basique
app.get("/health", () => ({
  status: "ok",
  uptime: process.uptime(),
  timestamp: Date.now()
}));

Circuit breakers : si le service B est down, le service A ne devrait pas continuer a l'appeler et attendre le timeout a chaque requête. Un circuit breaker coupe les appels apres N échecs et les reprend progressivement quand B revient. C'est le pattern popularise par Netflix avec Hystrix.

Observabilite : la trilogie

Sans observabilité, les microservices sont une boîte noire. Il te faut trois choses.

1. Logs centralises

Chaque service écrit ses logs en JSON. Un collecteur (Loki, ELK, Datadog) les agregue. Tu cherches par service, par request ID, par niveau d'erreur.

json{"level":"error","service":"commandes","requestId":"abc-123","msg":"payment failed","userId":"usr-456","timestamp":"2026-03-28T10:30:00Z"}

2. Tracing distribue

Un request utilisateur traverse 5 services ? OpenTelemetry propage un trace ID a chaque appel. Tu vois le parcours complet dans Jaeger ou Zipkin. Sans ca, debugger un problème de latence entre services, c'est chercher une aiguille dans une botte de foin.

Le tracing est particulièrement important avec gRPC parce que les appels binaires ne sont pas lisibles dans les logs réseau.

3. Metriques

Prometheus scrape les metriques de chaque service (latence, taux d'erreur, utilisation CPU/RAM). Grafana les affiche dans des dashboards. Les alertes se declenchent quand un seuil est dépassé.

La regle d'or de l'observabilité : si tu ne peux pas voir ce qui se passe, ne mets pas en production. Un monolithe avec un console.log et un tail sur les logs, ca marche. Dix microservices avec des logs disperses sur 10 containers, ca ne marche pas.


Résumé

  • Docker Compose pour le dev local et les petites productions
  • Kubernetes quand tu depasses 5 services et que tu as un ops dédié
  • Service discovery : DNS natif (Docker/K8s) suffit dans la plupart des cas
  • Health checks + circuit breakers sont obligatoires
  • Observabilite (logs, traces, metriques) n'est pas optionnelle en microservices

Article précédent : 03 - Communication inter-services Article suivant : 05 - Les 7 erreurs classiques (et comment les éviter)

Sources

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.