PerfectScalePerfectScale

PerfectScale

Kubernetes v1.35 : quoi de neuf ?

Kubernetes v1.35 : 'Timbernetes' prend le large avec 60 améliorations couvrant scaling, sécurité, gestion des périphériques, scheduling et plus encore.

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

Tania Duggal
By Tania Duggal
Jan 5, 202622 min read

Kubernetes v1.35, également connue sous le nom de "Timbernetes (The World Tree Release)", introduit de nombreuses nouvelles fonctionnalités qui rendent Kubernetes plus robuste et mieux à même de gérer les workloads modernes à grande échelle. Cette version compte 60 nouveautés : 17 passent en Stable (GA), 19 en Beta et 22 en Alpha. Le thème de l'arbre-monde ("World Tree") illustre la façon dont cette version renforce Kubernetes à tous les niveaux, de ses fondations à ses systèmes centraux et points d'extension. Il peut ainsi prendre en charge une grande variété de workloads, de l'IA/ML aux workloads stateful et edge.

Voici quelques-unes des fonctionnalités qui nous enthousiasment le plus dans Kubernetes v1.35 : la prise en charge du gang scheduling, la mise à jour in-place des ressources des Pods, le batching opportuniste dans le scheduler, et bien plus. Ces améliorations rendent Kubernetes nettement plus performant en matière d'optimisation des performances, de scalabilité et de gestion des ressources.

Passons en revue les principales améliorations de Kubernetes v1.35 :

Fonctionnalités stables de Kubernetes v1.35

1. Mise à jour in-place des ressources des Pods****

Groupe de fonctionnalités : SIG Node | KEP : #1287

Dans Kubernetes v1.35, la mise à jour in-place des ressources CPU et mémoire des Pods passe en disponibilité générale (GA).

Avant cette fonctionnalité, il fallait recréer le Pod à chaque modification de .spec.resources.requests ou .spec.resources.limits. Kubernetes traitait les changements de ressources comme des champs immuables : le moindre ajustement de CPU ou de mémoire entraînait donc un redémarrage complet. C'était particulièrement perturbant pour les services stateful, les jobs batch de longue durée et les applications sensibles à la latence, sans compter les interruptions de service que cela provoquait.

Avec la v1.35, Kubernetes vous permet de modifier les requests ou limits CPU et mémoire d'un Pod en cours d'exécution sans redémarrer le Pod ni ses conteneurs. Vous pouvez désormais appliquer les changements de ressources directement au conteneur en cours d'exécution lorsque le runtime et la configuration du nœud le permettent. Le kubelet met à jour les paramètres cgroup en place, et le Pod continue de fonctionner. Si un changement de ressources ne peut pas être appliqué en toute sécurité, Kubernetes revient à la recréation du Pod, préservant ainsi la rétrocompatibilité. Le scaling vertical devient ainsi plus simple, plus sûr et plus efficace.

2. Distribution du trafic PreferSameNode

Groupe de fonctionnalités : SIG Network | KEP :#3015

Dans Kubernetes v1.35, la distribution du trafic PreferSameNode passe en disponibilité générale (GA).

Avant ce changement, Kubernetes proposait l'option PreferClose dans le champ trafficDistribution. Elle était utile, mais ambiguë. PreferClose signifiait implicitement "préférer les endpoints proches", ce qui en pratique correspondait à une proximité au niveau de la zone, et non du nœud. Les utilisateurs n'avaient aucun moyen clair d'exprimer une préférence stricte pour les endpoints locaux au nœud, et l'API ne distinguait pas clairement le routage au niveau du nœud de celui au niveau de la zone.

Avec la v1.35, Kubernetes vous permet de choisir où le trafic d'un Service est acheminé. Il peut privilégier fortement les endpoints situés sur le même nœud que le Pod client et n'utiliser des endpoints distants qu'en l'absence d'endpoints locaux. Une nouvelle option, PreferSameNode, est introduite pour prioriser les endpoints sur le même nœud. Parallèlement, PreferClose est renommée PreferSameZone, rendant l'API plus explicite et plus claire. PreferClose reste prise en charge pour la rétrocompatibilité, mais PreferSameZone est désormais l'option privilégiée et explicite pour le routage zonal. Ensemble, ces changements séparent clairement les préférences de trafic au niveau du nœud et au niveau de la zone. C'est particulièrement utile pour les workloads exigeants en matière de performances, qui cherchent à réduire la latence et le trafic inter-nœuds.

apiVersion: v1
kind: Service
metadata:
name: node-local-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 8080
trafficDistribution: PreferSameNode

Avec cette configuration, si un Pod client et un Pod backend correspondant s'exécutent sur le même nœud, Kubernetes achemine le trafic localement. Ce n'est qu'en l'absence d'endpoints locaux que le trafic est envoyé vers des Pods situés sur d'autres nœuds.

3. Limite configurable de nœuds NUMA pour le Topology Manager

Groupe de fonctionnalités : SIG Node | KEP :#4622

Dans Kubernetes v1.35, la limite configurable de nœuds NUMA du Topology Manager passe en disponibilité générale (GA).

NUMA (Non-Uniform Memory Access) est une architecture matérielle dans laquelle un serveur est divisé en plusieurs régions mémoire (nœuds NUMA), chacune directement rattachée à un ensemble spécifique de CPU. Le Topology Manager est un composant du kubelet qui aligne les allocations de CPU, de mémoire et de périphériques afin que les workloads s'exécutent sur du matériel physiquement proche.

Avant cette fonctionnalité, Kubernetes imposait une limite stricte de 8 nœuds NUMA dès que le Topology Manager était activé. Cette mesure de sécurité visait à éviter une explosion d'états lors des calculs d'affinité NUMA. En conséquence, le kubelet désactivait complètement le Topology Manager sur les nœuds comptant plus de 8 nœuds NUMA. Cette limitation empêchait Kubernetes de tirer parti des grands serveurs multi-sockets, où la localité précise du CPU, de la mémoire et des périphériques est essentielle aux performances.

Avec la v1.35, l'option de politique max-allowable-numa-nodes est désormais stable. Kubernetes permet aux administrateurs de cluster d'exécuter le Topology Manager sur des machines comptant plus de 8 nœuds NUMA. Ce plafond artificiel disparaît, et Kubernetes peut coordonner le placement du CPU, de la mémoire et des périphériques même sur de très grandes machines. Des défis de performance subsistent pour les systèmes NUMA extrêmement grands, mais Kubernetes donne désormais aux opérateurs la possibilité d'activer cette option en fonction de leur matériel et des besoins de leurs workloads.

Cette fonctionnalité permet donc à Kubernetes de mieux exploiter les serveurs haut de gamme modernes couramment utilisés pour le HPC, l'IA/ML, les télécoms et les workloads à faible latence.

apiVersion: kubelet.config.k8s.io/v1
kind: KubeletConfiguration
topologyManagerPolicy: restricted
topologyManagerScope: pod
topologyManagerPolicyOptions:
max-allowable-numa-nodes: "true"

4. Ajout d'une option de politique CPUManager pour restreindre reservedSystemCPUs

Groupe de fonctionnalités : SIG Node | KEP : #4540

Avant cette fonctionnalité, Kubernetes permettait aux administrateurs de réserver des CPU spécifiques pour le système via reservedSystemCPUs. Cependant, cette réservation n'était appliquée que pour les Pods Guaranteed avec des requests CPU entières. Les Pods Burstable et BestEffort, ainsi que les Pods Guaranteed avec des requests CPU fractionnaires, pouvaient toujours consommer du temps CPU sur ces cœurs réservés. Dans les clusters en conditions réelles, cela entraînait des problèmes de type noisy neighbor, où les workloads applicatifs interféraient avec les processus système, provoquant instabilité des nœuds, retards de scheduling ou dégradation des performances sous charge.

Avec Kubernetes v1.35, l'option strict-cpu-reservation de la politique static du CPUManager passe en disponibilité générale (GA). Lorsqu'elle est activée, Kubernetes empêche strictement tous les Pods, quelle que soit leur classe QoS, de s'exécuter sur les CPU listés dans reservedSystemCPUs. L'isolation CPU devient ainsi prévisible et fiable, garantissant que les démons système disposent toujours d'une capacité CPU dédiée. Résultat : des nœuds plus stables et de meilleures performances pour les workloads sensibles à la latence et à haut débit qui cohabitent avec des composants système critiques.

apiVersion: kubelet.config.k8s.io/v1
kind: KubeletConfiguration
cpuManagerPolicy: static
reservedSystemCPUs: "0-1"
cpuManagerPolicyOptions:
strict-cpu-reservation: "true"

Avec cette configuration, les CPU 0-1 sont exclusivement réservés à l'OS et aux démons système de Kubernetes. Aucun Pod applicatif, qu'il soit BestEffort, Burstable ou Guaranteed, ne peut s'exécuter sur ces CPU.

5. Limite de pulls d'images parallèles du kubelet

Groupe de fonctionnalités : SIG Node | KEP : #3673

La limite de pulls d'images parallèles du kubelet contrôle le nombre d'images de conteneurs qu'un nœud est autorisé à télécharger simultanément. Le pull d'image est une opération intensive en réseau et en disque.

Avant cette fonctionnalité, le comportement du kubelet était essentiellement binaire. Avec serializeImagePulls à true, les images étaient téléchargées une par une, ce qui évitait la contention des ressources mais ralentissait considérablement le démarrage des pods lors des montées en charge ou des redémarrages de nœuds. Avec serializeImagePulls à false, il n'existait aucune limite supérieure au nombre de pulls d'images parallèles. Sur les nœuds très sollicités, cela pouvait saturer le réseau et les disques, et retarder d'autres opérations critiques sur le nœud.

Avec Kubernetes v1.35, le paramètre maxParallelImagePulls passe en disponibilité générale (GA). Les administrateurs peuvent ainsi définir une limite explicite au nombre de pulls d'images simultanés. Kubernetes peut désormais télécharger plusieurs images en parallèle, mais uniquement jusqu'à une limite sûre définie par l'opérateur. Tout pull supplémentaire est mis en file d'attente jusqu'à la fin d'un pull en cours, offrant une concurrence maîtrisée plutôt qu'un comportement tout ou rien.

apiVersion: kubelet.config.k8s.io/v1
kind: KubeletConfiguration
serializeImagePulls: false
maxParallelImagePulls: 3

Avec cette configuration, le kubelet autorise jusqu'à trois pulls d'images simultanés sur un nœud.

6. Garbage collection des images du kubelet après un âge maximal

Groupe de fonctionnalités : SIG Node | KEP :#4210

Avant cette fonctionnalité, la garbage collection des images du kubelet était principalement pilotée par des seuils d'utilisation disque. Les images n'étaient supprimées que lorsque l'utilisation disque dépassait HighThresholdPercent, et le nettoyage se poursuivait jusqu'à ce qu'elle repasse sous LowThresholdPercent. Efficace pour éviter la saturation du disque, ce mécanisme laissait toutefois les images rarement utilisées ou obsolètes sur le disque indéfiniment tant que le nœud n'était pas sous pression disque. Avec le temps, cela conduisait à des caches d'images surchargés et à une utilisation inefficace du disque.

Avec Kubernetes v1.35, le paramètre imageMaximumGCAge est désormais stable : il permet au kubelet de supprimer les images inutilisées depuis une durée donnée, indépendamment de l'utilisation disque. Les administrateurs peuvent définir un âge maximal pour les images inutilisées, exprimé sous forme de durée. Dès qu'une image dépasse cet âge sans être utilisée, elle devient éligible à la suppression. Ce mécanisme complète la GC basée sur le disque et rend le nettoyage des images proactif plutôt que réactif.

apiVersion: kubelet.config.k8s.io/v1
kind: KubeletConfiguration
imageMaximumGCAge: 24h
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 70

Avec cette configuration, toute image de conteneur inutilisée depuis 24 heures peut être supprimée par le kubelet, même si l'utilisation disque est inférieure au seuil haut.

7. Mécanisme managedBy de l'API Job

Groupe de fonctionnalités : SIG Apps | KEP :#4368

Avant cette fonctionnalité, chaque objet Job était systématiquement réconcilié par le contrôleur Job intégré. Même si un système externe (comme un contrôleur personnalisé ou un scheduler multi-cluster) souhaitait gérer l'exécution ou le statut, Kubernetes continuait de créer les Pods, de mettre à jour les conditions du Job, de réessayer en cas d'échec et d'appliquer la sémantique de complétion. Les cas d'usage avancés, comme la réplication de Jobs entre clusters, nécessitaient donc des annotations, des contournements au niveau des contrôleurs ou une logique de suppression pour éviter les conflits.

Avec Kubernetes v1.35, le champ managedBy passe en disponibilité générale (GA). Lorsqu'il est défini, Kubernetes considère le Job comme géré en externe et ne réconcilie ni ses Pods ni son statut. Cela rend possibles des systèmes comme MultiKueue, où un Job est créé dans un cluster de gestion, exécuté dans un cluster worker, et son statut synchronisé en retour sans interférence du contrôleur Job natif. La fonctionnalité est volontairement limitée : elle permet de déléguer la gestion des Jobs, mais ne modifie ni la sémantique des Jobs, ni le comportement des CronJobs, et ne transmet aucune configuration au contrôleur externe.

apiVersion: batch/v1
kind: Job
metadata:
name: delegated-job
spec:
managedBy: kueue.x-k8s.io/multikueue
........

8. Pod Generation (suivi fiable des mises à jour de Pods)

Groupe de fonctionnalités : SIG Node | KEP : #5067

Avant cette fonctionnalité, les Pods ne disposaient pas d'un champ metadata.generation, contrairement aux objets de plus haut niveau comme les Deployments ou les StatefulSets. Les contrôleurs pouvaient mettre à jour la spec d'un Pod, mais il n'existait aucun moyen natif et monotone de savoir si le kubelet avait déjà traité un changement donné. Il était donc difficile de détecter de manière fiable si une mise à jour de Pod était encore en attente, partiellement appliquée ou entièrement reflétée dans le statut — en particulier pour les mises à jour in-place et les changements rapides et successifs.

Avec Kubernetes v1.35, le suivi de génération des Pods passe en disponibilité générale (GA). Chaque Pod démarre avec metadata.generation: 1, et chaque mise à jour d'un champ mutable de la spec du Pod incrémente cette valeur. Le kubelet enregistre la génération qu'il a traitée dans status.observedGeneration. Cela indique explicitement si le statut actuel du Pod reflète la dernière spec souhaitée ou une version antérieure. Les contrôleurs externes peuvent comparer ces deux champs en toute sécurité pour déterminer si la réconciliation est terminée, sans dépendre du timing ni de suppositions.

Fonctionnalités Beta de Kubernetes v1.35

9. Tolérance configurable pour les HorizontalPodAutoscalers

Groupe de fonctionnalités : SIG Autoscaling | KEP : #4951

L'Horizontal Pod Autoscaler (HPA) ajuste automatiquement le nombre de réplicas de Pods d'un workload en fonction de métriques observées, comme l'utilisation du CPU ou de la mémoire.

Avant cette fonctionnalité, le HPA utilisait une tolérance fixe de 10 %, appliquée à l'échelle du cluster, pour décider s'il devait scaler. Cette valeur n'était pas configurable par workload. Résultat : des applications très sensibles pouvaient ne pas scaler alors qu'elles devaient réagir à de petites hausses de charge, tandis que d'autres workloads subissaient des scalings inutiles ou des oscillations. Ajuster ce comportement nécessitait de modifier un flag global du contrôleur, impactant tous les HPA du cluster.

Avec Kubernetes v1.35, la tolérance configurable passe en Beta et est activée par défaut. Vous pouvez désormais définir des valeurs de tolérance par HPA et par sens de scaling via le champ behavior. Cela offre un contrôle fin de la sensibilité de l'autoscaling sans affecter les autres workloads. Les opérateurs peuvent régler les services critiques pour qu'ils scalent de manière agressive tout en maintenant la stabilité des workloads moins sensibles.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleUp:
tolerance: 0.05

Avec cette configuration, le HPA ne scale à la hausse que lorsque l'utilisation CPU dépasse 65 % (5 % au-dessus de la cible).

10. Limites d'attachement de volumes mutables

Groupe de fonctionnalités : SIG Storage | KEP :#4876

Les limites d'attachement de volumes définissent combien de volumes de stockage peuvent être attachés à un nœud à un instant donné. Kubernetes s'appuie sur cette information pour décider où planifier les Pods utilisant des volumes persistants. Les drivers CSI communiquent ces limites via l'objet CSINode.

Avant cette fonctionnalité, la capacité d'attachement de volumes rapportée dans CSINode.spec.drivers[*].allocatable.count était statique. Une fois que le driver CSI avait enregistré sa limite d'attachement au démarrage, Kubernetes considérait cette valeur comme toujours exacte. Si des emplacements de volumes étaient consommés par la suite — à cause d'opérations externes, de redémarrages de nœuds ou de défaillances transitoires — le scheduler pouvait encore placer des Pods sur des nœuds n'ayant plus de capacité. Les Pods restaient alors bloqués en ContainerCreating, car le volume ne pouvait pas réellement être attaché.

Avec Kubernetes v1.35, la limite allocatable d'attachement de volumes devient mutable et la fonctionnalité passe en Beta, activée par défaut. Les drivers CSI peuvent mettre à jour dynamiquement la capacité d'attachement disponible d'un nœud à l'exécution. Kubernetes introduit également un intervalle de rafraîchissement configurable via l'objet CSIDriver, permettant aux drivers de contrôler la fréquence de recalcul des compteurs allocatable. De plus, Kubernetes met automatiquement à jour le compteur allocatable lorsqu'il détecte des échecs d'attachement dus à une capacité insuffisante. Les décisions de scheduling gagnent en précision, et les démarrages de Pods échoués ou bloqués diminuent nettement.

apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:
name: example.csi.storage
spec:
attachRequired: true
nodeAllocatableUpdatePeriodSeconds: 30 # Note: minimum is 10 seconds

Cette configuration déclenche des appels périodiques du kubelet vers l'endpoint NodeGetInfo du driver CSI toutes les 30 secondes afin de rafraîchir CSINode.spec.drivers[].allocatable.count

11. Batching opportuniste

Groupe de fonctionnalités : SIG Scheduling | KEP : #5598

Le batching opportuniste est une optimisation du scheduler qui améliore les performances lorsque Kubernetes planifie de nombreux Pods aux exigences de scheduling identiques ou équivalentes.

Avant cette fonctionnalité, le kube-scheduler traitait les Pods un par un, avec une complexité de scheduling proportionnelle au nombre de Pods multiplié par le nombre de nœuds. Même lorsque plusieurs Pods étaient identiques du point de vue du scheduling — mêmes requests de ressources, mêmes affinités et mêmes contraintes — le scheduler répétait les mêmes calculs de filtrage et de scoring pour chaque Pod. Cela générait du travail redondant et un scheduling lent, en particulier pour les jobs batch, les workloads ML et la création de réplicas à grande échelle.

Avec Kubernetes v1.35, le batching opportuniste est introduit en Beta, activé par défaut. Le scheduler calcule désormais une signature de scheduling de Pod, qui capture tous les aspects pertinents pour le scheduling, y compris les specs du Pod, les attributs des nœuds et l'état du cluster. Lorsque des Pods partageant la même signature arrivent successivement dans la file de scheduling, le scheduler les regroupe. Il met en cache les résultats de scheduling du premier Pod et les réutilise pour les Pods suivants ayant la même signature, évitant ainsi des calculs répétés. Le cache est de courte durée et automatiquement rafraîchi pour garantir l'exactitude à mesure que l'état du cluster évolue.

Cette optimisation fonctionne de manière transparente — aucune configuration utilisateur n'est requise — et bénéficie principalement aux workloads comportant de nombreux Pods identiques, comme les Jobs, les workers ML parallèles et les déploiements à grande échelle. En réduisant le travail de scheduling redondant, Kubernetes peut placer les Pods plus rapidement et scaler les workloads plus efficacement sous forte charge.

12. maxUnavailable pour les StatefulSets

Groupe de fonctionnalités : SIG Apps | KEP : #961

Un StatefulSet gère un ensemble de Pods nécessitant des identités stables, un démarrage et un arrêt ordonnés, ainsi qu'un stockage persistant.

Avant cette fonctionnalité, les StatefulSets utilisant la stratégie RollingUpdate mettaient à jour les Pods strictement un par un, en commençant par l'ordinal le plus élevé. Il n'existait aucun moyen de contrôler combien de Pods pouvaient être indisponibles pendant une mise à jour. Même si une application stateful pouvait tolérer l'indisponibilité temporaire de plusieurs Pods, Kubernetes imposait des mises à jour sérialisées, entraînant de longs déploiements pour les grands StatefulSets.

Avec Kubernetes v1.35, le champ maxUnavailable pour les rolling updates de StatefulSets passe en Beta et est activé par défaut. Les opérateurs peuvent spécifier combien de Pods peuvent être indisponibles pendant une mise à jour, en nombre absolu ou en pourcentage des réplicas. Combiné à podManagementPolicy: Parallel, Kubernetes peut mettre à jour plusieurs Pods à la fois tout en respectant les contraintes de disponibilité. En l'absence de valeur, la valeur par défaut reste 1, préservant le comportement antérieur.

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: database
spec:
replicas: 10
podManagementPolicy: Parallel
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 20%
........

13. Statut de Deployment : nombre de réplicas en cours de terminaison

Groupe de fonctionnalités : SIG Apps | KEP : #3973

Un Deployment gère les rolling updates et le scaling des Pods, et son statut est utilisé par les opérateurs et l'automatisation pour suivre la progression des déploiements.

Avant cette fonctionnalité, le statut du Deployment n'exposait que des champs comme replicas, updatedReplicas, readyReplicas et availableReplicas. Les Pods en cours de terminaison n'étaient pas explicitement visibles dans le statut du Deployment. Il était donc difficile de savoir si un Deployment était réellement stable ou si des Pods étaient encore en cours de nettoyage en arrière-plan. Les opérateurs et contrôleurs devaient lister les Pods manuellement et filtrer par deletionTimestamp, une approche inefficace et sujette aux erreurs.

Avec Kubernetes v1.35, le champ status.terminatingReplicas est promu en Beta et activé par défaut (avec la feature gate DeploymentReplicaSetTerminatingReplicas activée sur l'API server et le controller manager). Ce champ indique le nombre de Pods en cours de terminaison mais pas encore entièrement supprimés. Il améliore l'observabilité pendant les déploiements et les réductions de capacité, et pose les bases de futures améliorations du comportement des Deployments, comme des politiques de remplacement de Pods plus intelligentes tenant compte de la progression de l'arrêt.

apiVersion: apps/v1
kind: Deployment
metadata:
name: web
status:
replicas: 5
updatedReplicas: 5
readyReplicas: 4
availableReplicas: 4
terminatingReplicas: 1
........

14. Exposition des labels de topologie des nœuds via la Downward API

Groupe de fonctionnalités : SIG Node | KEP :#4742

Les labels de topologie des nœuds décrivent où un Pod s'exécute dans l'infrastructure, par exemple la région ou la zone de disponibilité du nœud.

Avant cette fonctionnalité, les Pods ne pouvaient pas accéder directement aux informations de topologie des nœuds. Les workloads ayant besoin des données de zone ou de région devaient interroger l'API server de Kubernetes, s'appuyer sur des sidecars ou recevoir des permissions RBAC supplémentaires. Cela augmentait la complexité opérationnelle et introduisait des risques de sécurité en élargissant les permissions des Pods applicatifs au-delà du strict nécessaire.

Avec Kubernetes v1.35, les labels de topologie des nœuds sont désormais injectés dans les Pods et exposés via la Downward API, la fonctionnalité étant en Beta et activée par défaut. Le kubelet propage des labels standard tels que topology.kubernetes.io/zone et topology.kubernetes.io/region du nœud vers le Pod, les rendant disponibles sous forme de variables d'environnement ou de fichiers projetés. Les workloads peuvent ainsi tenir compte de la topologie sans accès à l'API, ce qui simplifie la configuration et respecte le principe du moindre privilège.

apiVersion: v1
kind: Pod
metadata:
name: topology-aware-pod
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "env"]
env:
- name: ZONE
valueFrom:
fieldRef:
fieldPath: metadata.labels['topology.kubernetes.io/zone']
- name: REGION
valueFrom:
fieldRef:
fieldPath: metadata.labels['topology.kubernetes.io/region']

Avec cette configuration, le Pod reçoit automatiquement la zone et la région du nœud sur lequel il s'exécute.

Fonctionnalités Alpha de Kubernetes v1.35

15. Prise en charge du gang scheduling dans Kubernetes

Groupe de fonctionnalités : SIG Scheduling | KEP : #4671

Avant cette fonctionnalité, Kubernetes planifiait les Pods individuellement. Pour les workloads fortement couplés, cela entraînait un scheduling partiel : certains Pods démarraient tandis que d'autres restaient en attente faute de ressources. Ces jobs partiellement planifiés pouvaient créer des interblocages, gaspiller des ressources du cluster et bloquer d'autres workloads, forçant les utilisateurs à recourir à des schedulers externes ou à des contrôleurs personnalisés pour imposer une sémantique de gang.

Avec Kubernetes v1.35, le gang scheduling natif est introduit en Alpha via la nouvelle API Workload et les politiques de groupes de pods. Les utilisateurs définissent un Workload qui regroupe des Pods et spécifie une exigence minCount. Le scheduler retient les Pods jusqu'à ce que le groupe soit complet, puis tente de les placer ensemble. S'il ne parvient pas à planifier au moins le nombre requis de Pods dans le délai imparti, aucun n'est lié, et les Pods attendent que suffisamment de ressources soient disponibles. Kubernetes intègre ainsi nativement, au niveau du scheduler, la prise en charge de la sémantique de gang.

Exemple :

Workload définissant un gang de Pods

apiVersion: scheduling.k8s.io/v1alpha1
kind: Workload
metadata:
name: ml-training
spec:
podGroups:
- name: workers
policy:
gang:
minCount: 4

Pod lié au Workload :

apiVersion: v1
kind: Pod
metadata:
name: worker-0
spec:
workloadRef:
name: ml-training
podGroup: workers
containers:
- name: trainer
image: <your-image>

Avec cette configuration, Kubernetes ne planifie les Pods que lorsqu'au moins quatre workers peuvent s'exécuter ensemble. Si le cluster ne peut pas satisfaire cette exigence, aucun des Pods n'est démarré.

16. Opérateurs de toleration étendus pour un placement basé sur des seuils

Groupe de fonctionnalités : SIG Scheduling | KEP : #5471

Les taints et tolerations servent dans Kubernetes à contrôler où les Pods peuvent s'exécuter. Les nœuds utilisent des taints pour dire "ne placez pas de Pods ici", et les Pods utilisent des tolerations pour dire "je suis autorisé à m'exécuter sur ce nœud".

Avant cette fonctionnalité, les tolerations ne prenaient en charge que des opérateurs basiques comme Exists et Equal. Un Pod pouvait donc tolérer un taint ou non, sans pouvoir exprimer de degrés de tolérance. Par exemple, un workload ne pouvait pas dire "exécute-toi uniquement sur des nœuds avec un SLA ≥ 99,9" ou "évite les nœuds dont la fiabilité est inférieure à un certain seuil". Les clusters souhaitant un placement basé sur les SLA devaient donc recourir à des schedulers personnalisés, à plusieurs pools de nœuds ou à une logique d'admission complexe.

Avec Kubernetes v1.35, les tolerations bénéficient désormais d'opérateurs de comparaison numérique (sémantique supérieur à ou inférieur à, par exemple) dans le cadre du scheduling étendu. Les nœuds peuvent exposer des taints orientés SLA (par exemple des scores de fiabilité ou la qualité du domaine de panne), et les Pods peuvent spécifier des tolerations qui ne correspondent que si la valeur du taint du nœud satisfait une condition numérique. Les workloads critiques peuvent ainsi cibler des nœuds à SLA élevé, tandis que les workloads best-effort peuvent délibérément s'exécuter sur une infrastructure moins coûteuse et à SLA plus faible, améliorant l'utilisation sans sacrifier la fiabilité.

Taint de nœud exprimant un niveau de SLA :

kubectl taint nodes node-a
servicelevel.org.example/agreed-service-level=800:NoSchedule

Pod ne tolérant que les nœuds avec un SLA suffisant :

apiVersion: v1
kind: Pod
metadata:
name: sla-tolerant-pod
spec:
tolerations:
- key: servicelevel.org.example/agreed-service-level
operator: LessThan
value: "900"
effect: NoSchedule
containers:
- name: app
image: busybox
command: ["sh", "-c", "echo running on lower-SLA node"]

Avec cette configuration, le Pod ne sera planifié que sur des nœuds dont la valeur du taint SLA est inférieure à 900.

17. Ressources de conteneurs mutables lorsqu'un Job est suspendu

Groupe de fonctionnalités : SIG Apps | KEP : #5440

Un Job Kubernetes exécute une tâche jusqu'à sa réussite et s'assure qu'elle se termine.

Avant cette fonctionnalité, le template de Pod d'un Job était de fait immuable. Si un Job échouait à cause d'un manque de CPU ou de mémoire (par exemple des OOM kills répétés), les utilisateurs n'avaient aucun moyen d'ajuster les valeurs de ressources sur le Job existant. La seule option était de supprimer le Job et d'en créer un nouveau avec des ressources mises à jour, ce qui faisait perdre l'historique du Job, son statut et tout outillage suivant la progression ou les tentatives.

Avec Kubernetes v1.35, il devient possible de modifier les requests et limits de ressources des conteneurs d'un Job à l'état suspendu, lorsque la feature gate MutableJobPodResourcesForSuspendedJobs est activée. Les utilisateurs peuvent suspendre un Job en échec, mettre à jour le template de Pod avec des valeurs de ressources appropriées, puis reprendre le Job. Kubernetes poursuit l'exécution avec la configuration mise à jour tout en préservant l'identité et l'état du cycle de vie du Job, rendant la récupération après une mauvaise configuration des ressources bien plus fluide.

apiVersion: batch/v1
kind: Job
metadata:
name: data-processor
spec:
suspend: true
template:
spec:
restartPolicy: OnFailure
containers:
- name: worker
image: busybox
command: ["sh", "-c", "echo processing && sleep 30"]
resources:
requests:
cpu: "1"
memory: "1Gi"
limits:
cpu: "2"
memory: "2Gi"

Après la mise à jour des ressources, le Job peut être repris en passant spec.suspend à false. Le Job continue avec les nouvelles valeurs de CPU et de mémoire, sans suppression ni recréation du Job.

18. Fonctionnalités déclarées par les nœuds avant le scheduling

Groupe de fonctionnalités : SIG Node | KEP : #5328

Avant cette fonctionnalité, Kubernetes supposait que les nœuds étaient globalement compatibles avec le control plane, dans les limites du décalage de versions pris en charge. Lorsque de nouvelles fonctionnalités étaient activées au niveau du control plane, le scheduler pouvait quand même placer des Pods utilisant ces fonctionnalités sur des nœuds plus anciens ne les prenant pas encore en charge. Cela entraînait des échecs à l'exécution, des comportements subtilement erronés ou des Pods bloqués après le scheduling, alors même que la décision de placement semblait valide.

Avec Kubernetes v1.35, une fonctionnalité Alpha introduit un mécanisme formel permettant aux nœuds de déclarer les fonctionnalités qu'ils prennent en charge via un nouveau champ status.declaredFeatures sur l'objet Node. Une fois la fonctionnalité activée, les nœuds publient l'ensemble des fonctionnalités Kubernetes qu'ils comprennent. Le scheduler, les contrôleurs d'admission et les composants externes peuvent alors utiliser cette information pour valider les Pods et restreindre le scheduling aux nœuds compatibles, prévenant les problèmes de décalage de fonctionnalités avant que les Pods ne soient liés.

Dynamic Resource Allocation (DRA) - Travaux en cours

Groupe de fonctionnalités : SIG Node / SIG Scheduling

Dynamic Resource Allocation (DRA) est le framework natif de Kubernetes pour gérer les ressources matérielles spécialisées (GPU, accélérateurs et périphériques) d'une manière intégrée au scheduler et sûre pour le cycle de vie. Il lève de nombreuses limitations des device plugins traditionnels en intégrant l'allocation de périphériques directement dans le processus de scheduling et de binding de Kubernetes.

Avant Kubernetes v1.35, les fonctionnalités centrales de DRA étaient déjà passées en stable avec la v1.34.

Avec Kubernetes v1.35, DRA est désormais activé en permanence et plusieurs fonctionnalités alpha importantes ont considérablement mûri. L'objectif de la v1.35 n'est pas d'introduire de nouvelles API, mais de rendre les concepts existants de DRA plus complets, plus fiables et plus observables.

Voyons cela en détail :

Requests de ressources étendues via DRA

Les requests de ressources étendues permettent aux Pods de demander des périphériques avec une sémantique plus riche, y compris la réutilisation entre init containers et un meilleur scoring lors du scheduling.****

****Avant Kubernetes v1.35, DRA accusait un retard sur les device plugins dans certains scénarios. Par exemple, les périphériques ne pouvaient pas être réutilisés proprement entre init containers et conteneurs applicatifs, et les décisions de scheduling manquaient de signaux de scoring adéquats pour certains types de périphériques.

Désormais, avec Kubernetes v1.35, ces lacunes ont été comblées. La réutilisation des périphériques entre init containers fonctionne correctement, et la logique de scheduling évalue mieux le placement des périphériques. DRA devient ainsi viable pour des cycles de vie de Pods plus complexes et des workloads multi-étapes.

Taints et tolerations de périphériques

Les taints de périphériques permettent à des périphériques individuels — et non à des nœuds entiers — d'exprimer des conditions affectant le scheduling et l'éviction, à l'image des taints de nœuds.

Avant Kubernetes v1.35, les taints de périphériques étaient limités et n'offraient aucun moyen sûr d'évaluer leur impact avant de déclencher des évictions. Tout taint avec NoExecute évinçait immédiatement les Pods utilisant le périphérique.

Désormais, avec Kubernetes v1.35, un nouvel effet None est introduit. Il permet aux opérateurs d'effectuer un dry run : vous pouvez vérifier combien de pods seraient affectés et ne passer à NoExecute que lorsque vous êtes prêt.

De plus, DeviceTaintRule rapporte désormais des informations de statut, rendant les évictions observables et plus sûres à gérer.

Périphériques partitionnables

Les périphériques partitionnables sont des périphériques physiques pouvant être divisés en unités logiques plus petites (par exemple des tranches de GPU).

Avant**,** toutes les partitions d'un périphérique devaient être définies au sein d'un seul ResourceSlice, limitant la flexibilité de modélisation et de publication des périphériques.

Désormais, avec Kubernetes v1.35, les périphériques appartenant au même périphérique partitionnable peuvent être définis dans plusieurs ResourceSlices. La modélisation gagne en flexibilité et s'aligne mieux sur la façon dont le matériel moderne expose ses ressources partitionnées.

Capacité consommable

La capacité consommable suit les ressources de périphériques qui s'épuisent progressivement plutôt que d'être allouées de manière exclusive (par exemple la bande passante mémoire ou des accélérateurs à usage limité).

Les premières implémentations présentaient des problèmes d'exactitude et une couverture de tests incomplète, limitant la confiance dans le comportement de scheduling et de comptabilisation.

Désormais (v1.35), plusieurs bugs ont été corrigés et la couverture de tests élargie. Le comportement de consommation et de libération de capacité est plus fiable, rendant cette fonctionnalité plus sûre pour l'expérimentation.

Conditions de binding des périphériques

Les conditions de binding définissent quand et comment l'allocation d'un périphérique devient définitive lors du scheduling et de l'admission d'un Pod.

Avant, des cas limites existaient où le comportement de binding pouvait être ambigu ou mal géré en cas de défaillance.

Désormais (v1.35), plusieurs correctifs et validations améliorent l'exactitude. Les décisions de binding sont plus prévisibles et résilientes, notamment lors des retries et des défaillances partielles.

Sémantique de versions de ressources comparables

Les versions de ressources permettent aux clients et aux contrôleurs de suivre les changements des objets Kubernetes au fil du temps.

Avant Kubernetes v1.35, les versions de ressources ne pouvaient être comparées que pour l'égalité, pas pour l'ordre. Les clients ne pouvaient pas déterminer de manière fiable si une version était plus récente qu'une autre sans l'aide du serveur.

Désormais, avec Kubernetes v1.35, toutes les versions de ressources in-tree suivent un format numérique strict et comparable. Les clients peuvent comparer les versions eux-mêmes en toute sécurité. Cela améliore les performances des informers et la fiabilité des contrôleurs. Ce changement est fondamental et ouvre la voie à de multiples améliorations de plus haut niveau dans Kubernetes.

Dépréciations / Suppressions

Suppression de la prise en charge de cgroup v1

Kubernetes utilise les cgroups pour gérer le CPU et la mémoire des conteneurs. Les versions précédentes prenaient en charge à la fois cgroup v1 et v2, principalement pour la rétrocompatibilité.

Avec la v1.35, la prise en charge de cgroup v1 est entièrement supprimée, et cgroup v2 devient obligatoire.

Dépréciation du mode IPVS dans kube-proxy

kube-proxy achemine le trafic des Services vers les Pods à l'aide de différents modes de backend. Le mode IPVS est déprécié dans la v1.35 en raison de sa complexité opérationnelle et de son chevauchement avec les dataplanes modernes.

Kubernetes encourage désormais le mode iptables ou les CNI basés sur eBPF pour un réseau scalable.

Cela réduit la charge de maintenance et améliore la fiabilité réseau à long terme.

Dernier appel pour containerd v1.x

Containerd est le runtime de conteneurs par défaut utilisé par Kubernetes.
Les anciennes versions containerd v1.x approchent de leur fin de support.
Kubernetes v1.35 lance un dernier appel à migrer vers des versions plus récentes de containerd.

Kubernetes 1.35 apporte au total 60 Kubernetes Enhancement Proposals (KEPs). Ces améliorations couvrent les fonctionnalités de Kubernetes, la flexibilité, la gestion des ressources, l'observabilité, et plus encore.

Au-delà des changements majeurs abordés ici, l'équipe k8s a ajouté d'autres fonctionnalités. Nous vous invitons à consulter les notes de version de Kubernetes v1.35 et cette page pour plus de détails.