Aller au contenu
Conteneurs & Orchestration medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

ResourceQuota et LimitRange : contrôler les ressources par namespace

14 min de lecture

logo kubernetes

ResourceQuota limite la consommation totale d’un namespace (CPU, mémoire, nombre de pods…), tandis que LimitRange définit des valeurs par défaut et des bornes min/max pour chaque conteneur. Ensemble, ils empêchent qu’une équipe ou une application ne monopolise les ressources du cluster. Ce guide vous montre comment les configurer et les combiner efficacement.

  • Comprendre la différence entre ResourceQuota et LimitRange
  • Créer des quotas pour limiter CPU, mémoire et objets Kubernetes
  • Configurer des valeurs par défaut avec LimitRange
  • Combiner les deux mécanismes pour un namespace multi-tenant
  • Déboguer les erreurs liées aux quotas dépassés

Prérequis : connaître les namespaces Kubernetes et comprendre requests et limits.

Sans quota, un développeur peut déployer un pod qui consomme 100 Go de mémoire — et faire crasher tous les autres workloads du cluster. Dans un environnement multi-tenant (plusieurs équipes, plusieurs projets), c’est le problème du “noisy neighbor” : un voisin bruyant qui monopolise les ressources.

ScénarioSans quotaAvec ResourceQuota
Un pod demande 100 Go RAMSchedulé, crash du nœudRejeté immédiatement
Une équipe crée 500 podsCluster saturéLimité à 50 pods max
Création massive de ConfigMapsSurcharge etcdPlafonné à 100 ConfigMaps

Les quotas sont préventifs : ils bloquent le déploiement avant que le problème ne survienne.

Un ResourceQuota définit des limites agrégées pour tout un namespace. Il répond à la question : “Combien de ressources ce namespace peut-il consommer au total ?”

CatégorieExemples de ressourcesDescription
Computerequests.cpu, limits.memoryCPU et mémoire totaux
Objetspods, services, configmapsNombre d’objets Kubernetes
Stockagerequests.storage, persistentvolumeclaimsEspace disque et PVC
Étenducount/deployments.apps, count/jobs.batchTout type de ressource
  1. Créer le fichier de quota

    Ce quota limite le namespace à 4 CPU en requests, 8 Go de mémoire en limits, et 30 pods maximum.

    quota-team-backend.yaml
    apiVersion: v1
    kind: ResourceQuota
    metadata:
    name: compute-quota
    namespace: team-backend
    spec:
    hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    pods: "30"
  2. Appliquer le quota

    Fenêtre de terminal
    kubectl apply -f quota-team-backend.yaml
  3. Vérifier l’état du quota

    Fenêtre de terminal
    kubectl describe resourcequota compute-quota -n team-backend

    Sortie attendue :

    Name: compute-quota
    Namespace: team-backend
    Resource Used Hard
    -------- ---- ----
    limits.cpu 0 8
    limits.memory 0 16Gi
    pods 0 30
    requests.cpu 0 4
    requests.memory 0 8Gi

Vous pouvez limiter le nombre de n’importe quel type d’objet Kubernetes :

quota-objects.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-quota
namespace: team-backend
spec:
hard:
configmaps: "30"
secrets: "30"
services: "10"
services.loadbalancers: "2"
services.nodeports: "5"
persistentvolumeclaims: "10"
count/deployments.apps: "20"
count/jobs.batch: "50"

Vous pouvez segmenter les quotas selon la PriorityClass des pods :

quota-priority.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: high-priority-quota
namespace: team-backend
spec:
hard:
requests.cpu: "2"
requests.memory: 4Gi
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values: ["high-priority"]

Ce quota ne s’applique qu’aux pods avec priorityClassName: high-priority.

Un LimitRange définit des contraintes au niveau de chaque conteneur ou pod individuel. Il répond à : “Quelles sont les valeurs min, max et par défaut pour un conteneur ?”

Le LimitRange résout ce problème en définissant des valeurs par défaut automatiques.

  1. Créer le fichier LimitRange

    limitrange-team-backend.yaml
    apiVersion: v1
    kind: LimitRange
    metadata:
    name: container-limits
    namespace: team-backend
    spec:
    limits:
    - type: Container
    default:
    cpu: "500m"
    memory: "512Mi"
    defaultRequest:
    cpu: "100m"
    memory: "128Mi"
    max:
    cpu: "2"
    memory: "4Gi"
    min:
    cpu: "50m"
    memory: "64Mi"
  2. Appliquer le LimitRange

    Fenêtre de terminal
    kubectl apply -f limitrange-team-backend.yaml
  3. Tester avec un pod sans limits

    pod-sans-limits.yaml
    apiVersion: v1
    kind: Pod
    metadata:
    name: test-pod
    namespace: team-backend
    spec:
    containers:
    - name: nginx
    image: nginx:1.25
    # Pas de resources déclarées
    Fenêtre de terminal
    kubectl apply -f pod-sans-limits.yaml
    kubectl get pod test-pod -n team-backend -o yaml | grep -A 10 resources

    Résultat : Les valeurs par défaut sont automatiquement injectées.

ChampDescriptionAppliqué quand
defaultValeur limits par défautSi limits non spécifié
defaultRequestValeur requests par défautSi requests non spécifié
maxValeur maximale autoriséeToujours (rejet si dépassé)
minValeur minimale autoriséeToujours (rejet si inférieur)

Vous pouvez aussi définir des limites au niveau du pod entier (somme de tous les conteneurs) :

apiVersion: v1
kind: LimitRange
metadata:
name: pod-limits
namespace: team-backend
spec:
limits:
- type: Pod
max:
cpu: "4"
memory: "8Gi"

Le LimitRange peut aussi contraindre la taille des PVC :

apiVersion: v1
kind: LimitRange
metadata:
name: storage-limits
namespace: team-backend
spec:
limits:
- type: PersistentVolumeClaim
max:
storage: 50Gi
min:
storage: 1Gi

En production, vous utilisez toujours les deux ensemble. Voici l’ordre d’application recommandé :

  1. Créer le namespace avec des labels

    apiVersion: v1
    kind: Namespace
    metadata:
    name: team-backend
    labels:
    team: backend
    environment: production
  2. Appliquer le LimitRange en premier

    Le LimitRange garantit que tous les pods auront des requests/limits, même non déclarés.

    apiVersion: v1
    kind: LimitRange
    metadata:
    name: container-limits
    namespace: team-backend
    spec:
    limits:
    - type: Container
    default:
    cpu: "500m"
    memory: "512Mi"
    defaultRequest:
    cpu: "100m"
    memory: "128Mi"
    max:
    cpu: "2"
    memory: "4Gi"
    min:
    cpu: "50m"
    memory: "64Mi"
  3. Appliquer le ResourceQuota ensuite

    Le ResourceQuota limite la consommation totale du namespace.

    apiVersion: v1
    kind: ResourceQuota
    metadata:
    name: compute-quota
    namespace: team-backend
    spec:
    hard:
    requests.cpu: "8"
    requests.memory: 16Gi
    limits.cpu: "16"
    limits.memory: 32Gi
    pods: "50"
    configmaps: "50"
    secrets: "50"
    services: "20"
    persistentvolumeclaims: "20"

Quand vous créez un pod, voici ce qui se passe :

1. Le pod arrive à l'API server
2. LimitRange injecte les defaults si manquants
3. LimitRange vérifie min/max par conteneur
4. ResourceQuota vérifie si le total du namespace permet ce pod
5. Si tout est OK → pod créé
6. Sinon → erreur avec message explicite
Fenêtre de terminal
# Voir tous les quotas d'un namespace
kubectl get resourcequota -n team-backend
# Détails avec utilisation actuelle
kubectl describe resourcequota compute-quota -n team-backend
# Voir les LimitRange
kubectl describe limitrange -n team-backend

L’API expose l’utilisation des quotas :

Fenêtre de terminal
kubectl get resourcequota compute-quota -n team-backend -o jsonpath='{.status}'

Pour le monitoring, kube-state-metrics expose les métriques :

  • kube_resourcequota : limites et utilisation
  • kube_limitrange : valeurs configurées
Error from server (Forbidden): pods "my-pod" is forbidden:
exceeded quota: compute-quota, requested: requests.memory=2Gi,
used: requests.memory=7Gi, limited: requests.memory=8Gi

Cause : Le namespace a déjà utilisé 7 Gi sur 8 Gi autorisés.

Solutions :

  1. Réduire les requests du nouveau pod
  2. Supprimer des pods existants
  3. Augmenter le quota (si justifié)
Fenêtre de terminal
# Voir l'utilisation actuelle
kubectl describe resourcequota -n team-backend
# Identifier les gros consommateurs
kubectl top pods -n team-backend --sort-by=memory
Error from server (Forbidden): pods "my-pod" is forbidden:
failed quota: compute-quota: must specify limits.cpu,limits.memory

Cause : Un ResourceQuota existe mais pas de LimitRange, et le pod ne déclare pas ses limits.

Solution : Ajouter un LimitRange avec des valeurs par défaut.

Error from server (Forbidden): pods "my-pod" is forbidden:
maximum cpu usage per Container is 2, but limit is 4

Cause : Le pod demande plus que le max autorisé par le LimitRange.

Solution : Réduire les limits du conteneur ou ajuster le LimitRange.

Un pod peut être créé (quota OK) mais rester Pending si le cluster n’a pas assez de ressources disponibles. Le quota ne garantit pas la disponibilité, il garantit seulement les limites.

Fenêtre de terminal
kubectl describe pod my-pod -n team-backend
# Regarder la section Events pour "Insufficient cpu" ou "Insufficient memory"
MétriqueRecommandation
requests.cpuSomme des requests de tous les pods attendus
limits.cpu1.5x à 2x les requests (marge pour burst)
podsNombre max réaliste + 20% marge
PVCBasé sur les besoins réels de stockage

Assurez-vous que le LimitRange est cohérent avec le ResourceQuota :

# Si LimitRange.default.cpu = 500m et ResourceQuota.limits.cpu = 8
# Alors max 16 conteneurs avec defaults (16 × 500m = 8 CPU)

Adaptez les quotas selon l’environnement :

EnvironnementQuota CPU requestsQuota mémoirePods max
dev24Gi20
staging48Gi30
production1632Gi100
  • ResourceQuota limite la consommation totale d’un namespace (CPU, mémoire, objets)
  • LimitRange définit des valeurs par défaut et des bornes min/max par conteneur
  • Avec un ResourceQuota, les pods doivent déclarer leurs requests/limits → utilisez LimitRange pour les defaults
  • Appliquez LimitRange avant ResourceQuota pour éviter les rejets de pods
  • Les quotas sont préventifs : ils bloquent avant que le problème ne survienne
  • Surveillez l’utilisation avec kubectl describe resourcequota

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

10 questions
8 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn