Introduction
Aujourd’hui, je vais vous parler d’une nouvelle fonctionnalité de Kubernetes 1.34 qui est passée en béta : les Pod-level resources.
Et pour illustrer cette nouvelle fonctionnalité, je vais prendre l’exemple d’un pod pour lequel je souhaite avoir la QoS Guaranteed.
Pendant un temps, j’étais persuadé (mais alors je sais pas pourquoi… parce que la doc est claire 🤔) que pour avoir la QoS Guaranteed, il fallait que tous les containers du pod aient limits=requests, mais les mêmes pour tous les containers (ce qui est faux). Et c’est super pénible parce que des fois on a une grosse app principale et un tout petit sidecar et ça n’a pas de sens de leur mettre les mêmes valeurs.
Si on relit la doc, ce qui compte pour la QoS Guaranteed (doc officielle), c’est que :
- Chaque container doit avoir
cpu.limit = cpu.request - Chaque container doit avoir
memory.limit = memory.request
Mais les valeurs peuvent être différentes entre les containers !
Pour s’en convaincre, il suffit de tester ce manifest :
apiVersion: v1
kind: Pod
metadata:
name: ctrlevel-demo1
namespace: pod-resources-example
spec:
containers:
- name: ctrlevel-demo1-ctr-1
image: nginx
resources:
limits:
cpu: "0.8"
memory: "100Mi"
requests:
cpu: "0.8"
memory: "100Mi"
- name: ctrlevel-demo1-ctr-2
image: fedora
resources:
limits:
cpu: "0.2"
memory: "200Mi"
requests:
cpu: "0.2"
memory: "200Mi"
command:
- sleep
- inf
Et devinez quoi ? QoS Class: Guaranteed.
Le premier container a 0.8 CPU / 100Mi, le second a 0.2 CPU / 200Mi, et ça ne pose aucun problème tant que chaque container respecte individuellement limit=request pour cpu et ram.
Bon. Maintenant que j’ai admis mon erreur publiquement (shame shame shame), on va quand même parler de Pod-level resources, parce que cette fonctionnalité reste utile.

Alors, à quoi ça sert, les Pod-level resources ?
Dans certains cas, il arrive que les containers (init, sidecar, …) soient très peu consommateurs. Certains sont aussi injectés à la volée (service mesh, auto instrumentation) de manière généralisée. Spécifier explicitement des limits / requests pour ces “petits” containers annexes peut être pénible, chronophage, difficile à tuner s’il y en a beaucoup…
Exemple typique : on injecte un sidecar qui expose juste des métriques Prometheus. Il consomme 10m de CPU et 20Mi de RAM. Vous pourriez écrire :
containers:
- name: mon-app
resources:
limits:
cpu: "1"
memory: "100Mi"
requests:
cpu: "1"
memory: "100Mi"
- name: metrics-exporter
resources:
limits:
cpu: "10m"
memory: "20Mi"
requests:
cpu: "10m"
memory: "20Mi"
Mais franchement, c’est chi**t. Et si demain l’exporter a besoin d’un poil plus de mémoire dans certains cas mais pas tous, il faut modifier le manifest pour l’augmenter partout, ou alors gérer l’exception…
Avec Pod-level resources, vous pouvez faire :
#fichier podlevel-demo1.yaml
apiVersion: v1
kind: Pod
metadata:
name: podlevel-demo1
namespace: pod-resources-example
spec:
resources:
limits:
cpu: "1"
memory: 100Mi
requests:
cpu: "1"
memory: 100Mi
initContainers:
- name: sidecar-test
image: busybox:latest
command: ["sh", "-c", "while true; do sleep 3600; done"]
restartPolicy: Always
containers:
- name: podlevel-demo1-ctr
image: vish/stress
args:
- -cpus
- "2"
Ici :
- Les
resourcessont déclarées au niveau duspecdu Pod - Les containers eux-mêmes n’ont PAS de déclaration de ressources
- Le sidecar (déclaré en tant qu’initContainer avec
restartPolicy: Always, cf. mon article précédent sur les sidecars) se partage les ressources du Pod avec le container.
Dans cet exemple, c’est un container et un sidecar, mais ça aurait très bien pu être n’importe quel autre mix de containers, d’init containers classiques et de sidecars.
Testons ça !
kubectl create namespace pod-resources-example
kubectl apply -f podlevel-demo1.yaml
Maintenant, vérifions que nous avons bien obtenu la QoS Guaranteed avec ce oneliner des enfers 😈 :
kubectl get pod podlevel-demo1 -n pod-resources-example -o jsonpath=$'Pod-level resources:\n Requests: {.spec.resources.requests}\n Limits: {.spec.resources.limits}\n\nContainer podlevel-demo1-ctr:\n Requests: {.spec.containers[0].resources.requests}\n Limits: {.spec.containers[0].resources.limits}\n\nSidecar sidecar-test:\n Requests: {.spec.initContainers[0].resources.requests}\n Limits: {.spec.initContainers[0].resources.limits}\n\nQoS Class: {.status.qosClass}\n'
Résultat :
Pod-level resources:
Requests: {"cpu":"1","memory":"100Mi"}
Limits: {"cpu":"1","memory":"100Mi"}
Container podlevel-demo1-ctr:
Requests:
Limits:
Sidecar sidecar-test:
Requests:
Limits:
QoS Class: Guaranteed
Les containers individuels n’ont PAS de ressources déclarées, mais le Pod dans son ensemble a des ressources. Et on obtient quand même la QoS Guaranteed !
Tout fonctionne comme prévu.

On peut aussi mixer pod level et container level
Au-delà de cet exemple, sachez qu’il est possible de mixer du container level (classique) avec du pod level.
Voici un exemple inspiré par la doc officielle :
#fichier podlevel-demo2.yaml
apiVersion: v1
kind: Pod
metadata:
name: podlevel-demo2
namespace: pod-resources-example
spec:
resources:
limits:
cpu: "1"
memory: "200Mi"
requests:
cpu: "1"
memory: "200Mi"
containers:
- name: podlevel-demo2-ctr-1
image: nginx
resources:
limits:
cpu: "0.5"
memory: "100Mi"
requests:
cpu: "0.5"
memory: "100Mi"
- name: podlevel-demo2-ctr-2
image: fedora
command:
- sleep
- inf
Ici, le container podlevel-demo2-ctr-1 spécifie ses ressources, mais on spécifie aussi des ressources pour tout le pod, et pas du tout dans podlevel-demo2-ctr-2.
Pour info, l’exemple de ce pod est aussi Guaranteed, malgré l’absence de limits/requests sur podlevel-demo2-ctr-2
kubectl get pod podlevel-demo2 -n pod-resources-example -o jsonpath=$'Pod-level resources:\n Requests: {.spec.resources.requests}\n Limits: {.spec.resources.limits}\n\nContainer podlevel-demo2-ctr-1:\n Requests: {.spec.containers[0].resources.requests}\n Limits: {.spec.containers[0].resources.limits}\n\nContainer podlevel-demo2-ctr-2:\n Requests: {.spec.containers[1].resources.requests}\n Limits: {.spec.containers[1].resources.limits}\n\nQoS Class: {.status.qosClass}\n'
Résultat :
Pod-level resources:
Requests: {"cpu":"1","memory":"200Mi"}
Limits: {"cpu":"1","memory":"200Mi"}
Container podlevel-demo2-ctr-1:
Requests: {"cpu":"500m","memory":"100Mi"}
Limits: {"cpu":"500m","memory":"100Mi"}
Container podlevel-demo2-ctr-2:
Requests:
Limits:
QoS Class: Guaranteed
Conclusion
Les Pod-level resources sont une fonctionnalité qui simplifie la vie dans certains cas d’usage, notamment quand on utilise des sidecars légers ou des containers injectés à la volée.
Est-ce révolutionnaire ? Non. Est-ce que ça va changer votre vie ? Probablement pas. Mais ça peut toujours servir.
On en apprend tous les jours. Même (surtout ?) quand on se plante. 😌
