Passer au contenu principal

Workloads (Kubernetes)

Resource management

Le resource management dans Kubernetes repose sur deux concepts : requests (ressources garanties pour le scheduling) et limits (plafonds d'utilisation). Mal configurés, requests et limits sont la première cause de pods Pending, d'OOMKill, et de noeuds surchargés en production.

Requests et Limits

spec:
  containers:
  - name: app
    resources:
      requests:
        cpu: "250m"       # 250 millicores = 0.25 vCPU garanti au scheduling
        memory: "256Mi"   # 256 MiB garantis
      limits:
        cpu: "1"          # Throttling si dépassé (pas de kill)
        memory: "512Mi"   # OOMKill si dépassé

Le CPU est compressible : si la limite est atteinte, le conteneur est throttlé (ralenti) mais pas tué. La mémoire est incompressible : si la limite est atteinte, le conteneur est OOMKilled et redémarré.

Classes QoS

Kubernetes attribue automatiquement une classe QoS à chaque pod. Elle détermine l'ordre d'éviction sous pression mémoire sur un noeud :

  • Guaranteed : requests == limits sur CPU et mémoire pour tous les conteneurs. Éviction en dernier. Idéal pour les apps critiques.
  • Burstable : requests définis mais inférieurs aux limits, ou limits non définis. Éviction intermédiaire.
  • BestEffort : aucun request ni limit défini. Éviction en premier. À éviter en production.
kubectl get pod web-xxx -o jsonpath='{.status.qosClass}'

Dimensionner les requests

Sous-dimensionner les requests provoque du noisy-neighbor (pods qui se disputent les ressources sur un noeud). Sur-dimensionner provoque un gaspillage de capacité et des pods Pending inutiles. La bonne approche :

  1. Déployer sans requests (ou très faibles) dans un namespace de staging
  2. Laisser tourner sous charge représentative
  3. Analyser les métriques (kubectl top pods, Prometheus, VPA recommendations)
  4. Fixer requests à P95 de la consommation observée
  5. Fixer limits à 2-3x les requests pour absorber les pics

Debugging OOMKill

# Déterminer si un pod a été OOMKilled
kubectl describe pod web-xxx | grep -A5 "Last State"
# Chercher: Reason: OOMKilled

# Vérifier la limite mémoire actuelle
kubectl get pod web-xxx -o jsonpath='{.spec.containers[0].resources}'

# Métriques temps réel
kubectl top pods --sort-by=memory

CPU Throttling

Le CPU throttling est plus pernicieux : le pod tourne mais lentement. Les symptômes sont des latences élevées sans OOMKill visible. Pour le détecter :

# Avec metrics-server
kubectl top pods

# En Prometheus
rate(container_cpu_cfs_throttled_seconds_total[5m]) /
rate(container_cpu_cfs_periods_total[5m])
# > 25% de throttling = limite CPU trop basse

Resource Quotas et LimitRange

ResourceQuota et LimitRange (vus dans Namespaces) complètent le resource management au niveau du cluster. En production, il est fortement recommandé de définir des LimitRange par namespace pour éviter les pods BestEffort accidentels (développeurs qui oublient les requests).

Sources