DevOps

Kubernetes 1.37 : KYAML passe en stable, HPA à zéro réplique et kubelet rootless — ce qui change concrètement le 26 août

Kubernetes v1.37 est annoncé pour le 26 août 2026 avec un volume d'enhancements conforme aux cycles récents et une part importante de graduations. Cet article passe en revue les changements qui auront un impact réel sur les plateformes en production — KYAML en sortie stable de kubectl, HPA à zéro réplique, Pod Level Resources, kubelet en user namespace — et propose une méthode de préparation de la montée de version.

| | | 12 min read · by
Terminal affichant un manifeste Kubernetes au format KYAML, avec accolades et chaînes entre guillemets.

Kubernetes v1.37 est attendue le 26 août 2026. À ce stade du cycle, le tracking board du SIG Release fait état d’environ 86 enhancements retenus, dont une petite trentaine de graduations (alpha → bêta, bêta → stable). Ce ratio est caractéristique des cycles récents : peu de nouveautés spectaculaires, beaucoup de consolidation — c’est précisément ce qui rend une release intéressante pour une équipe plateforme, parce que les graduations sont les seules choses qu’on peut raisonnablement mettre en production.

Un avertissement méthodologique avant d’entrer dans le détail : tant que les release notes finales ne sont pas publiées, le contenu d’une version reste mouvant. Chaque cycle voit des KEP retirés dans les derniers jours (code freeze non tenu, tests d’intégration insuffisants, blocage sur la revue d’API). Ce qui suit est donc à lire comme une préparation de montée de version, pas comme une source normative : vérifiez systématiquement le CHANGELOG définitif avant de planifier un upgrade.

Comment lire un cycle de release sans se noyer

La liste des enhancements n’est pas un plan de travail. Trois filtres suffisent à la réduire à quelque chose d’actionnable :

  1. Le niveau de maturité. Une alpha est désactivée par défaut, sans garantie de compatibilité ni de migration des données. Une bêta est activée par défaut depuis la politique de 2022 uniquement pour les API existantes : les nouvelles API en bêta restent opt-in. Une graduation en stable signifie que le feature gate va disparaître à terme — c’est là qu’il faut agir.
  2. Le composant touché. Un changement dans kubectl se déploie poste par poste et n’a aucun impact sur le cluster. Un changement dans le kubelet ou dans kube-proxy touche le plan de données et se teste sur un node pool isolé.
  3. Les dépréciations. Ce sont les seules entrées qui peuvent casser un cluster à l’upgrade, et elles arrivent souvent plusieurs versions avant la suppression effective.

KYAML en stable : la fin des surprises de typage

KYAML est apparu en 1.34 comme format de sortie expérimental de kubectl. Sa promesse est étroite et bien définie : c’est un sous-ensemble de YAML 1.2, entièrement en style flow. Les maps sont délimitées par des accolades, les listes par des crochets, et toutes les chaînes de caractères sont entourées de guillemets doubles. Comme il s’agit de YAML valide, n’importe quel parser YAML existant le lit sans modification — un fichier KYAML reste un .yaml, il n’y a pas de nouveau format à supporter côté outillage.

{
  apiVersion: "apps/v1",
  kind: "Deployment",
  metadata: {
    name: "web",
    labels: {
      app: "web",
    },
  },
  # les commentaires sont conservés
  spec: {
    replicas: 3,
    template: {
      spec: {
        containers: [{
          name: "web",
          image: "registry.example.com/web:1.20",
          env: [{
            name: "COUNTRY",
            value: "NO",
          }],
        }],
      },
    },
  },
}

Ce que KYAML conserve de YAML : les commentaires (contrairement à JSON), les virgules finales (contrairement à JSON), et la lisibilité multi-lignes. Ce qu’il supprime : la coercition de type implicite et la sensibilité à l’indentation.

Le second point est celui qui coûte le plus cher en production. Le fameux « problème norvégien » vient de YAML 1.1, où NO, no, n, off, y sont des booléens. La plupart des bibliothèques YAML de l’écosystème restent alignées sur ce comportement.

# YAML classique : trois pièges dans quatre lignes
env:
  - name: COUNTRY
    value: NO        # booléen false
  - name: VERSION
    value: 1.20      # float 1.2
  - name: BUILD
    value: 0755      # selon le parser, octal ou chaîne

Dans le cas précis d’un manifeste envoyé à l’API server, le champ value est typé string et la conversion échoue de façon bruyante — c’est le meilleur scénario. Le problème réel se situe avant : dans les values.yaml Helm, les patches Kustomize, les variables de CI, les pipelines yq. Là, la valeur est silencieusement transformée, sérialisée en "false" ou "1.2", et le bug se manifeste trois environnements plus loin. KYAML élimine cette classe de bug par construction, puisqu’il n’y a plus de scalaire non quoté à interpréter.

KYAML en pratique

L’usage principal reste la sortie de kubectl :

# sortie explicite en KYAML
kubectl get deployment web -o kyaml

# faire de KYAML la sortie par défaut de -o yaml
export KUBECTL_KYAML=true

# générer un manifeste propre sans l'appliquer
kubectl create deployment web --image=registry.example.com/web:1.20 \
  --dry-run=client -o kyaml > deploy.yaml

Côté dépôts GitOps, l’intérêt est immédiat sur les diffs : le style flow réduit les faux positifs liés à la réindentation et rend les revues de PR plus lisibles sur les structures profondes (probes, securityContext, affinity). Argo CD et Flux ne voient aucune différence, puisqu’ils consomment du YAML standard.

Il faut en revanche être clair sur ce que KYAML ne résout pas. Ce n’est pas un langage de templating : Helm continue de générer du YAML classique à partir de ses templates, et rien n’oblige les charts à émettre du KYAML. Kustomize normalise ses sorties selon son propre sérialiseur. KYAML n’apporte ni validation de schéma, ni typage fort côté API : la validation reste le rôle de l’OpenAPI publié par l’API server, de kubectl apply --dry-run=server, de kubeconform ou des policies CEL. Concrètement, l’adoption réaliste est progressive : KYAML pour les manifestes écrits à la main et pour les sorties d’outillage, YAML classique partout où un moteur de template intervient.

Les autres graduations à surveiller

HPA scale to/from zero. Le KEP-2021 traîne en alpha depuis Kubernetes 1.16. Il autorise minReplicas: 0 lorsque l’autoscaling s’appuie sur des métriques external ou object — typiquement une profondeur de file. Sans lui, tout workload event-driven exigeait KEDA ou Knative pour descendre à zéro. Avec lui, le cas simple « une file, un worker » devient natif :

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: worker
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: worker
  minReplicas: 0
  maxReplicas: 20
  metrics:
    - type: External
      external:
        metric:
          name: queue_messages_ready
        target:
          type: AverageValue
          averageValue: "30"
  behavior:
    scaleDown:
      tolerance: 0.05

Attention au point aveugle classique : à zéro réplique, la latence de la première requête inclut le scheduling, le pull d’image et le démarrage applicatif. Le scale-to-zero est une optimisation de coût, pas un mécanisme de disponibilité.

Tolérance configurable pour l’HPA. L’HPA ignore historiquement les écarts inférieurs à 10 % par rapport à la cible, valeur globale au cluster. Le champ behavior.*.tolerance permet de la régler par objet : une tolérance basse côté scaleUp pour réagir vite, plus haute côté scaleDown pour éviter le flapping.

Pod Level Resources. Déclarer requests et limits au niveau du Pod plutôt que par container. Le gain est net pour les Pods multi-containers dont les sidecars consomment de façon irrégulière : au lieu de sur-provisionner chaque container, on définit une enveloppe partagée.

spec:
  resources:
    requests:
      cpu: "1"
      memory: 2Gi
    limits:
      memory: 2Gi
  containers:
    - name: app
      image: registry.example.com/app:2.4
    - name: sidecar
      image: registry.example.com/otel-collector:0.110

Vérifiez l’interaction avec vos LimitRange, ResourceQuota et vos outils de rightsizing : beaucoup de dashboards de cost management agrègent encore uniquement les requests par container.

metrics.k8s.io. La stabilisation de l’API de métriques de ressources (celle servie par metrics-server, consommée par kubectl top et par l’HPA) est une bonne nouvelle de fiabilité : cette API était en v1beta1 depuis très longtemps alors qu’elle est de fait critique. Prévoyez la bascule des clients qui codent en dur le groupe de version.

Fichiers d’environnement côté kubectl. Améliorations sur la création de ConfigMap et de Secret à partir de fichiers KEY=VALUE, utiles pour industrialiser les imports depuis des fichiers .env existants.

Kubelet-in-UserNS : le rootless atteint la bêta

Le KEP-2033 permet d’exécuter l’ensemble du plan de données Kubernetes — kubelet inclus — à l’intérieur d’un user namespace, sans privilèges root sur l’hôte. Il est en alpha depuis plus de cinq ans ; le passage en bêta est le vrai événement de sécurité de ce cycle.

Le modèle de menace visé est précis : réduire l’impact d’une compromission du kubelet ou d’une évasion de container. Dans un cluster rootless, l’UID 0 vu à l’intérieur est mappé sur un UID non privilégié de l’hôte ; un attaquant qui sort du container se retrouve avec les droits d’un utilisateur ordinaire. C’est complémentaire — pas équivalent — des user namespaces par Pod (hostUsers: false), qui isolent les charges de travail sans déprivilégier le kubelet lui-même.

Les prérequis sont exigeants et forment la vraie barrière à l’adoption :

  • cgroup v2 avec délégation configurée pour l’utilisateur cible (via systemd, Delegate=yes) ;
  • des plages /etc/subuid et /etc/subgid suffisantes pour l’utilisateur qui porte le kubelet ;
  • un runtime CRI compatible en mode rootless (containerd ou CRI-O configurés en conséquence) et un runtime OCI supportant le mapping d’ID (crun, ou runc récent) ;
  • un plugin CNI qui fonctionne sans capacités réseau privilégiées sur l’hôte — c’est en pratique le point de blocage le plus fréquent.

Les limites actuelles restent structurelles : pas de hostNetwork, pas de Pods privilégiés, contraintes sur les volumes qui exigent des opérations de mount privilégiées, et un écosystème d’agents (CSI, eBPF, monitoring node-level) largement écrit sous l’hypothèse d’un kubelet root. La cible réaliste en 1.37, c’est le cluster d’edge, le CI éphémère, le développement local et les environnements multi-tenant à faible privilège — pas la migration d’un cluster de production généraliste.

Réseau et scheduling

Côté réseau, l’effort se poursuit sur le chemin nftables, désormais le mode de référence de kube-proxy. Le travail annoncé pour ce cycle concerne un chemin de forwarding L4 dédié au trafic NodePort, avec l’objectif délicat de préserver la sémantique existante : affinité de session ClientIP et externalTrafficPolicy: Local (conservation de l’IP source, absence de second saut inter-node). Ce sont exactement les deux comportements que les migrations iptables → nftables ont historiquement fait régresser en silence. Si vous exposez du NodePort en frontal d’un load balancer externe, testez explicitement : IP source réellement observée par l’application, distribution des sessions, et comportement des health checks quand aucun endpoint local n’est présent sur un node.

Côté scheduling, DRA (Dynamic Resource Allocation, KEP-4381) continue sa montée en maturité pour l’allocation de GPU et d’accélérateurs. L’intérêt par rapport aux device plugins est l’expressivité : partage de device, contraintes topologiques, attributs sélectionnables via CEL, et surtout un couplage propre entre la décision du scheduler et l’allocation réelle. Si votre plateforme fait de l’IA/ML, c’est le sous-système à suivre avec la plus grande attention — mais aussi celui dont les extensions les plus récentes restent en alpha.

Observabilité : histogrammes natifs Prometheus

Les composants Kubernetes exposent des histogrammes classiques, avec des buckets figés à la compilation : trop grossiers pour les latences fines, trop nombreux pour la cardinalité. Les histogrammes natifs de Prometheus remplacent ces buckets statiques par des buckets à résolution exponentielle, ce qui donne des quantiles plus précis pour un coût de stockage inférieur.

Deux points pratiques. D’abord, il faut une chaîne d’ingestion compatible : Prometheus avec le support des native histograms activé, ou un backend qui l’implémente (le protocole d’exposition et le remote write concernés sont spécifiques). Ensuite, les dashboards existants ne cassent pas immédiatement, mais les requêtes histogram_quantile() écrites sur des séries _bucket ne s’appliquent pas telles quelles à un histogramme natif : prévoyez une phase de double exposition et une réécriture progressive des règles d’alerte plutôt qu’un basculement global.

Checklist de montée de version

# 1. Quelles API dépréciées sont encore appelées, et par qui ?
kubectl get --raw /metrics | grep apiserver_requested_deprecated_apis

# 2. Audit statique des manifestes du dépôt GitOps
kubent -f ./manifests --target-version=1.37

# 3. Vérifier la validation côté serveur avant l'upgrade
kubectl apply -f ./manifests --dry-run=server

# 4. Inventorier les feature gates non standards activés
kubectl -n kube-system get pod kube-apiserver-node1 \
  -o jsonpath='{.spec.containers[0].command}' | tr ',' '\n' | grep feature-gates

Ordre de bascule, sans exception : control plane d’abord, nodes ensuite. Le kubelet doit rester dans la fenêtre de skew supportée par rapport à l’API server (deux versions mineures en arrière) et ne doit jamais être plus récent que le control plane. kubectl supporte un skew d’une version mineure dans les deux sens. Points de vigilance récurrents :

  • les webhooks d’admission et de conversion (validating, mutating, CRD conversion), première cause de blocage d’upgrade ;
  • les CRD et opérateurs tiers, qui ont leur propre matrice de compatibilité et sont souvent en retard d’un cycle ;
  • les agents node-level (CSI, CNI, eBPF, sécurité) qui touchent aux interfaces internes du kubelet ;
  • une cordon/drain validée avec de vrais PodDisruptionBudget, testée sur un node pool sacrificiel.

Et un test que l’on oublie systématiquement : restaurer un backup etcd pris avant l’upgrade, sur un cluster de la version précédente. Un chemin de rollback non testé n’est pas un chemin de rollback.

Ce qu’il ne faut pas activer tout de suite

Les alphas de ce cycle sont intellectuellement séduisantes — extensions DRA, nouvelles primitives de scheduling, évolutions d’API en cours de revue. Elles n’ont pas leur place sur un cluster qui porte du trafic, pour des raisons structurelles et non par prudence excessive :

  • une API alpha peut être supprimée à la version suivante, sans chemin de migration des objets déjà persistés dans etcd ;
  • activer un feature gate alpha sur l’API server, c’est activer du code peu exercé sur un composant dont l’indisponibilité est totale ;
  • sur un cluster managé (GKE, EKS, AKS), la plupart de ces gates ne sont de toute façon pas exposés — construire une plateforme dessus vous enferme dans du self-managed ;
  • désactiver un gate alpha n’est pas toujours réversible côté données.

La règle opérationnelle est simple : les alphas se testent sur des clusters jetables (kind, un cluster de recherche), avec un ticket de veille pour le cycle où elles passeront en bêta.

L’intérêt de la 1.37 tient moins à ses nouveautés qu’à ce qu’elle referme. KYAML clôt une classe entière de bugs de sérialisation qu’on traitait depuis dix ans à coups de guillemets défensifs et de conventions de revue. HPA scale-to-zero et Pod Level Resources rapatrient dans le core des besoins pour lesquels on installait des contrôleurs supplémentaires. Le kubelet rootless, lui, reste un chantier : la bêta est une invitation à qualifier son runtime et son CNI, pas encore à migrer sa production. Le bon plan de montée de version, dans les deux semaines qui viennent, consiste à préparer les tests plutôt qu’à préparer l’upgrade — les release notes du 26 août diront lesquels sont réellement pertinents.

Comments (0)

Please log in to leave a comment.

Log In

No comments yet. Be the first to comment!