Kubernetes 1.37 ajoute la préemption du planificateur pour les redimensionnements de pods en place
Le 10 septembre 2026, Kubernetes 1.37 introduit, derrière la feature gate InPlacePodVerticalScalingSchedulerPreemption, la préemption du planificateur pour les redimensionnements de pods en place restés bloqués à l’état Deferred. Les opérateurs peuvent désormais bin-packer leurs nœuds avec des charges basse priorité sans risquer de bloquer la montée en charge des services critiques.
10 septembre 2026. Natasha Sarkar (Google) annonce sur le blog Kubernetes l’arrivée en alpha de la préemption du planificateur pour le redimensionnement de pods en place, derrière la feature gate InPlacePodVerticalScalingSchedulerPreemption. Elle comble la dernière lacune du scaling vertical sans redémarrage : jusqu’ici, une demande de montée en charge qui dépassait la capacité libre du nœud restait bloquée indéfiniment à l’état Deferred. Le planificateur peut désormais évincer des charges basse priorité pour faire de la place. Pour qui bin-packe ses nœuds, c’est un changement de paradigme de densité.
Le trou laissé par le redimensionnement en place
Le redimensionnement en place (in-place Pod resize) est passé stable dans Kubernetes 1.35. Il permet d’ajuster le CPU et la mémoire alloués à un conteneur en cours d’exécution, sans redémarrage ni interruption. Mais il a introduit une faille d’ordonnancement précise.
Quand un utilisateur ou un contrôleur — comme le Vertical Pod Autoscaler — augmente les requests d’un conteneur actif, le Kubelet vérifie si le nœud dispose de la capacité allocable nécessaire. Si le nœud est saturé et ne peut pas satisfaire les nouvelles limites, le Kubelet place le resizeStatus du conteneur à Deferred. Contrairement à un redimensionnement Infeasible — rejeté immédiatement parce qu’il dépasse les limites physiques de la machine, les limit ranges de l’espace de noms ou les quotas d’admission — le statut Deferred signifie que la demande est valide mais temporairement inapplicable, en attente de capacité disponible.
Avant cette fonctionnalité, cette attente pouvait devenir permanente. Si une base de données en mémoire ou un serveur web temps réel avait besoin de plus de mémoire pour éviter un crash OOM, et que le nœud était plein, le redimensionnement restait Deferred. Les choix de l’administrateur étaient alors limités et douloureux : évincer manuellement les pods basse priorité, attendre que l’autoscaler de cluster provisionne un nœud plus gros (opération lourde qui viole la promesse « sans redémarrage » du scaling en place), ou déployer une solution d’autoscaling maison.
La cause racine est simple : le kube-scheduler ignorait l’existence des redimensionnements différés. Il ne pouvait donc pas appliquer sa préemption basée sur les priorités — l’éviction de workloads moins prioritaires pour libérer la ressource — aux pods déjà placés.
Ce que change la préemption en alpha
La nouvelle feature gate reconnecte le planificateur au problème. Quand un pod à haute priorité exige un redimensionnement qui excède la capacité du nœud, le planificateur évince automatiquement les pods basse priorité du même hôte pour dégager de la marge. Vous récupérez à la fois la densité (bin-packing des nœuds avec des jobs batch ou best-effort) et la réactivité des services critiques.
La mécanique repose sur quatre principes d’architecture.
Suivi centralisé par le planificateur. Le kube-scheduler surveille les pods porteurs d’un resizeStatus Deferred. Normalement, un pod avec un spec.nodeName rempli est considéré comme placé et sort de la file d’ordonnancement active. Sous cette feature gate, le planificateur intercepte les pods Deferred et les maintient dans les évaluations actives, précisément pour déclencher une préemption, jusqu’à ce que le Kubelet ait terminé l’actuation du redimensionnement.
Frontière de préemption limitée au nœud. Contrairement à la préemption de placement — qui évalue tous les nœuds du cluster pour trouver le meilleur point de chute — la préemption de redimensionnement est strictement locale au nœud où tourne déjà le pod. Le planificateur identifie les pods « victimes » basse priorité sur le même hôte et lance leur éviction gracieuse. Si, même après éviction de toutes les charges éligibles, le nœud ne peut pas absorber le redimensionnement, le pod reste Deferred.
Réservation de ressource sûre. Pour éviter les courses d’ordonnancement et la double allocation, le planificateur considère les ressources demandées pour le redimensionnement comme déjà consommées. Le Kubelet peut ainsi actuater le redimensionnement dès que la préemption produit son effet, sans qu’un autre pod ne s’insère dans la marge libérée.
Séparation des responsabilités avec le Kubelet. Sous pression de ressource, le Kubelet dispose d’un mécanisme local, le critical Pod admission handler, qui peut évincer des pods basse priorité pour garantir l’admission d’un pod système critique. Ici, la feature gate retire explicitement cette logique au Kubelet pour le redimensionnement en place : il délègue la décision de préemption au planificateur, garantissant un orchestre unique qui respecte les priorités globales, les Pod Disruption Budgets (PDB) et les politiques de terminaison gracieuse.
Les demandes concurrentes sont traitées dynamiquement. Si un redimensionnement plus prioritaire survient sur le même nœud pendant un cycle de préemption actif, le Kubelet le priorise, et le planificateur observe le changement pour déclencher un nouveau tour de préemption si nécessaire.
Configurer ou désactiver la préemption par nœud
La fonctionnalité s’active au niveau du cluster : Kubernetes 1.37 ou plus sur le plan de contrôle et les nœuds de calcul, avec la feature gate InPlacePodVerticalScalingSchedulerPreemption activée sur kube-apiserver, kube-scheduler et kubelet.
Elle offre aussi un contrôle fin par nœud. Administrateurs et contrôleurs (comme un autoscaler de cluster) peuvent désactiver la préemption de redimensionnement sur des nœuds précis via le nouveau champ spec.podPreemptionPolicy :
apiVersion: v1
kind: Node
metadata:
name: batch-workload-node
spec:
podPreemptionPolicy:
disableResizePreemption:
- "cluster-autoscaler.kubernetes.io/disable-preemption"
- "operator.example.com/policy-override" Le cas d’usage type est celui d’un contrôleur qui préfère réduire d’autres pods ou ajuster dynamiquement la capacité du nœud lui-même, et ne souhaite activer la préemption du planificateur qu’en dernier recours. La granularité du champ disableResizePreemption permet de réserver cette politique à des nœuds dédiés aux charges batch, tout en laissant la préemption active sur les nœuds des services critiques.
Tester la préemption en local avec kind
La documentation propose un scénario reproductible sur un cluster kind à un seul nœud, avec une marge de CPU volontairement réduite. Objectif : observer la préemption en action, sans déployer un cluster complet.
Première étape — un cluster 1.37 avec la feature gate. Créez un fichier kind-config.yaml qui active la gate InPlacePodVerticalScalingSchedulerPreemption :
# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
InPlacePodVerticalScalingSchedulerPreemption: true Puis créez le cluster en imposant une image Kubernetes 1.37 ou plus récente, faute de quoi la gate ne sera pas reconnue :
kind create cluster --config kind-config.yaml --image kindest/node:v1.37.0 Deuxième étape — saturer le nœud. Déployez deux PriorityClasses — une high-priority (valeur 1000000) et une low-priority (valeur 1000) — puis deux pods : un pod basse priorité qui demande 3 CPU et un pod haute priorité qui demande 4 CPU. Ensemble ils consomment 7 des 8 CPU allocables d’un nœud kind standard, ne laissant qu’1 CPU de marge libre.
Troisième étape — provoquer un redimensionnement Deferred. Patchez le pod haute priorité pour faire passer sa demande CPU de 4 à 6 (un delta de +2 CPU). Comme il ne reste qu’un seul CPU libre, la demande dépasse la capacité allocable restante. Le sous-ressource resize est la porte d’entrée du scaling en place :
kubectl patch pod high-priority-pod --subresource resize --patch \
'{"spec":{"containers":[{"name":"app","resources":{"requests":{"cpu":"6"},"limits":{"cpu":"6"}}}]}}' Quatrième étape — observer l’éviction. Avec la gate active, le kube-scheduler intercepte le statut Deferred du pod haute priorité et cible le pod basse priorité pour la préemption. Inspectez les événements du pod basse priorité pour confirmer que l’éviction a bien été déclenchée par le planificateur, puis vérifiez que le pod haute priorité sort de l’état Deferred une fois la marge libérée.
Le scénario illustre le comportement exact promis par l’architecture : une préemption locale au nœud, déclenchée uniquement quand la capacité libre ne suffit pas, et respectueuse des priorités déclarées.
Verdict
Kubernetes 1.37 ne force personne : la préemption de redimensionnement est alpha, derrière une feature gate, et réversible nœud par nœud. Mais son intérêt est immédiat pour les opérateurs qui bin-packent.
Si vous bin-packez déjà vos nœuds avec des charges basse priorité, activez InPlacePodVerticalScalingSchedulerPreemption en environnement de staging, validez le comportement des PDB (la préemption les respecte, mais une éviction est une éviction), puis généralisez aux nœuds des services critiques. Le gain est double : densité conservée et fin des redimensionnements Deferred qui s’éternisent.
Si vous ne bin-packez pas, la fonctionnalité n’est pas urgente : elle ne sert que lorsque le nœud est saturé au moment d’une montée en charge. Concentrez plutôt vos efforts sur la montée vers 1.37 et l’adoption du Vertical Pod Autoscaler, qui reste le déclencheur naturel des redimensionnements en place. La préemption viendra consolider un scaling vertical que vous aurez d’abord mis en route.