« Kubernetes répartit les ressources tout seul, je n’ai rien à déclarer. »
Sans contrat de ressources, un Pod peut consommer tout le CPU et la RAM d’un node, et rien ne garantit qu’il aura de quoi tourner. On déclare donc ce dont chaque Pod a besoin (requests) et son maximum (limits) — et on découvre les classes QoS qui décident qui est protégé sous pression.
À la fin de ce module, tu sauras…
- Distinguer requests (scheduling) et limits (plafond d’exécution)
- Lire la classe QoS d’un Pod
- Passer de BestEffort à Burstable, puis Guaranteed
- Choisir des valeurs raisonnables sans casser l’appli
01Le concept, en une page
| Notion | Sens | Qui l’utilise |
|---|---|---|
| requests | « ce dont j’ai besoin pour tourner » | le scheduler (où placer le Pod) |
| limits | « mon maximum autorisé » | le runtime (throttle CPU, OOMKill mémoire) |
Comprends requests vs limits, concrètement
Requests = réservation pour le scheduling : si aucun node n’a assez de CPU/RAM libre pour la requête, le Pod reste Pending. Limits = plafond : dépasser le CPU → throttling (l’appli ralentit) ; dépasser la mémoire → OOMKilled (le conteneur est tué). Les limits protègent le node, mais trop basses elles créent de l’instabilité.
02L’état de départ : BestEffort
Prouver l’absence de contrat
Manipulekubectl get deploy demo-deploy -o yaml | grep -A3 -i 'resources:'
kubectl describe pod <POD_NAME> | grep -i 'QoS Class'Observeresources: {}
QoS Class: BestEffortresources: {} = ni requests ni limits. Le Pod est en BestEffort : la classe la moins protégée — la première évincée sous pression.Comprends les trois classes QoS
BestEffort : aucune requête ni limite → premier évincé. Burstable : requests définies (limits optionnelles ou plus hautes) → protection moyenne. Guaranteed : requests == limits pour CPU et mémoire → protection maximale. La classe est déduite automatiquement de ce que tu déclares.
03Passer à Burstable (requests)
Ajouter des requests, puis des limits
Manipulekubectl patch deploy demo-deploy --type='json' -p='[
{"op":"replace","path":"/spec/template/spec/containers/0/resources","value":{
"requests":{"cpu":"50m","memory":"64Mi"},
"limits":{"cpu":"200m","memory":"128Mi"}
}}
]'Manipulekubectl describe pod <NOUVEAU_POD> | grep -i 'QoS Class'ObserveQoS Class: BurstableComprends les unités : m et Mi
50m = 50 millicores = 0,05 cœur CPU. 64Mi = 64 mébioctets de RAM. Les requests réservent au scheduling, les limits plafonnent à l’exécution. Ici : besoin garanti modeste, plafond plus haut pour absorber les pics.
04Guaranteed (requests == limits)
La classe la plus protégée
Manipulekubectl patch deploy demo-deploy --type='json' -p='[
{"op":"replace","path":"/spec/template/spec/containers/0/resources","value":{
"requests":{"cpu":"100m","memory":"128Mi"},
"limits":{"cpu":"100m","memory":"128Mi"}
}}
]'
kubectl describe pod <NOUVEAU_POD> | grep -i 'QoS Class'ObserveQoS Class: GuaranteedComprends quand Guaranteed est-il judicieux ?
Guaranteed offre la meilleure priorité d’éviction et une performance stable — idéal pour des composants critiques. Mais c’est plus strict : pas de burst au-delà de la limite, et une mémoire trop basse rend les OOMKills plus probables. Sur un cluster aux ressources serrées (ton cas), attention : trop de Pods Guaranteed avec des requests élevées peuvent laisser des Pods en Pending faute de place. On choisit des valeurs raisonnables.
05Quand ça ne rentre pas : Pending
Comprendre un Pod bloqué
Si tu demandes plus que ce que les nodes offrent, le Pod reste Pending. Diagnostique :
kubectl get pods -o wide
kubectl describe pod <POD_PENDING> | grep -iA2 'Events\|Insufficient'ObserveWarning FailedScheduling ... Insufficient cpuComprends le lien requests ↔ scheduling
Pending + Insufficient cpu/memory = les requests dépassent la capacité libre. Le scheduler ne place jamais un Pod qu’il ne peut pas satisfaire. C’est la preuve concrète que requests pilote le scheduling. Sur ton cluster à ressources limitées, ce cas est fréquent : dimensionne prudemment.
✓Ce que tu retiens
Un contrat de ressources protège le cluster : requests (besoin, utilisé par le scheduler) et limits (plafond, appliqué par le runtime). Les classes QoS — BestEffort, Burstable, Guaranteed — déterminent qui survit sous pression. Bien dimensionner, c’est éviter le gaspillage et les Pods bloqués en Pending.
Un contrat de ressources sain
À faire
- Prouve la classe de départ (BestEffort) de
demo-deploy. - Ajoute requests + limits, prouve le passage à Burstable.
- Mets requests == limits, prouve Guaranteed.
- Provoque volontairement un
Pending(requests trop hautes) et lis l’événement. - Reviens à des valeurs raisonnables pour ton cluster (ressources limitées).
- Documente dans BookStack : requests vs limits, les 3 classes QoS, l’arbitrage Guaranteed.
?Auto-évaluation
1. Quelle est la différence entre requests et limits ?
Requests = ce dont le Pod a besoin (utilisé par le scheduler pour le placer) ; limits = son maximum autorisé (throttle CPU, OOMKill mémoire).
2. Qu’est-ce qui distingue la classe Guaranteed ?
requests == limits pour CPU et mémoire. C’est la classe la plus protégée, mais sans burst possible.
3. Pourquoi un Pod peut-il rester Pending à cause des ressources ?
Parce qu’aucun node n’a assez de CPU/RAM libre pour satisfaire ses requests. Le scheduler ne le place pas.