Comment Kubernetes gère-t-il les conteneurs du cluster ?

Kubernetes orchestre les conteneurs d’un cluster en s’appuyant sur une boucle de réconciliation permanente : chaque composant compare l’état souhaité (déclaré dans un manifeste YAML) à l’état réel des charges de travail, puis corrige les écarts. Comprendre comment cette mécanique se décompose entre le plan de contrôle et les nœuds de travail permet d’anticiper les décisions de placement, de dimensionnement et de tolérance aux pannes qui conditionnent la stabilité d’un cluster en production.

Redimensionnement de conteneurs sans redémarrage : ce que change la sous-ressource /resize

La plupart des guides décrivent la gestion des conteneurs Kubernetes comme un cycle créer-détruire-recréer. Cette vision est désormais incomplète.

A lire aussi : Est-il illégal d'utiliser le chat gpt pour écrire un livre ?

Depuis Kubernetes 1.35, la sous-ressource /resize est passée au statut stable. Les demandes et limites CPU/mémoire d’un conteneur peuvent être modifiées en place, sans recréer le pod. En pratique, un pod dont la consommation mémoire augmente peut recevoir davantage de ressources à chaud, ce qui réduit les interruptions liées aux ajustements de capacité.

Cette évolution modifie la façon dont le kubelet gère les conteneurs sur chaque nœud. Au lieu de demander au scheduler de replacer un nouveau pod, le kubelet applique directement les nouvelles limites au conteneur existant via le runtime. Le pod conserve son adresse IP, ses volumes montés et son état réseau.

A découvrir également : Qu'est-ce que la classe 10 des logiciels libres ?

Architecte cloud expliquant l'organisation des conteneurs Kubernetes devant un tableau blanc avec des schémas de cluster

Le tableau ci-dessous résume l’écart entre l’ancien et le nouveau mode de gestion des ressources conteneurs.

Critère Avant /resize (recréation du pod) Avec /resize (modification en place)
Interruption de service Oui, le pod est supprimé puis recréé Non, le conteneur reste actif
Conservation de l’adresse IP Non (nouveau pod = nouvelle IP) Oui
Passage par le scheduler Oui, re-scheduling complet Non, le kubelet applique la modification
Cas d’usage principal Tout changement de ressources Ajustement CPU/mémoire sans migration

Pour les applications stateful (bases de données, caches), cette différence est significative : un redémarrage pouvait impliquer un temps de réchauffement du cache ou une bascule de réplica. Le redimensionnement en place supprime ce coût opérationnel.

Gestion des ressources au niveau du pod : l’évolution vers Kubernetes 1.37

Jusqu’à récemment, les décisions de placement et d’allocation se prenaient conteneur par conteneur à l’intérieur d’un pod. Kubernetes 1.37 fait progresser les gestionnaires de ressources au niveau du pod vers le statut bêta. Le scheduler et le kubelet peuvent désormais raisonner sur l’ensemble du pod plutôt que sur chaque conteneur isolément.

Concrètement, un pod multi-conteneurs (un conteneur applicatif et un sidecar de monitoring, par exemple) voit ses besoins agrégés. Le scheduler évalue la somme des demandes du pod pour choisir le nœud le mieux adapté, au lieu de traiter chaque conteneur comme une unité indépendante.

Ce changement a un impact direct sur le déploiement de charges de travail gourmandes en ressources GPU. Au lieu de répartir les demandes GPU entre conteneurs, le pod déclare un budget GPU global. Le kubelet alloue ensuite les périphériques au pod, qui les distribue en interne.

Containerd 2.x et cgroup v2 : contraintes d’exécution sur les nœuds du cluster

La couche basse qui lance réellement les conteneurs sur un nœud traverse deux transitions simultanées.

  • Kubernetes 1.35 est la dernière version à prendre en charge containerd 1.x. Les versions suivantes exigent une branche containerd 2.x, ce qui affecte la compatibilité des nœuds existants non mis à jour.
  • Le paramètre kubelet failCgroupV1 est activé par défaut à partir de Kubernetes 1.35. Un nœud Linux encore fondé sur cgroup v1 peut refuser de démarrer ses pods, car le kubelet considère cet environnement comme obsolète.
  • La combinaison de ces deux changements signifie qu’un cluster dont les nœuds n’ont pas été mis à jour (OS, runtime, configuration cgroup) peut perdre la capacité de planifier de nouveaux pods après une montée de version du plan de contrôle.

En revanche, les clusters déjà migrés vers containerd 2.x et cgroup v2 ne subissent aucune régression. L’écart se creuse donc entre les environnements maintenus à jour et ceux qui accumulent de la dette technique sur la couche nœud.

Couloir de salle de serveurs avec des racks étiquetés nœuds de cluster Kubernetes dans un datacenter moderne

Boucle de réconciliation du cluster : du scheduler au kubelet

Le mécanisme central qui relie tous ces éléments reste la boucle de réconciliation. Voici comment Kubernetes gère concrètement le cycle de vie d’un conteneur à travers les composants du cluster.

Lorsqu’un utilisateur soumet un manifeste (Deployment, StatefulSet), l’API server enregistre l’état souhaité dans etcd. Le controller manager détecte l’écart entre l’état souhaité et l’état courant, puis crée les objets pods manquants.

Le scheduler examine les pods non assignés, évalue les ressources disponibles sur chaque nœud (CPU, mémoire, GPU, ports réseau) et affecte chaque pod à un nœud. Le kubelet du nœud cible détecte l’assignation, demande au runtime (containerd) de créer le conteneur, puis surveille son état en continu.

Si un conteneur tombe, le kubelet tente un redémarrage selon la politique définie (Always, OnFailure, Never). Si le nœud entier devient injoignable, le controller manager marque ses pods comme défaillants et le scheduler les replace sur d’autres nœuds. Chaque composant ne gère qu’un maillon de la chaîne, ce qui rend le système résilient à la panne d’un élément isolé.

Le kube-proxy, présent sur chaque nœud, maintient les règles réseau qui permettent aux services d’acheminer le trafic vers les bons pods. Sans cette couche, un pod redémarré sur un nouveau nœud serait injoignable malgré un déploiement réussi.

La gestion des conteneurs dans un cluster Kubernetes repose donc moins sur un orchestrateur central que sur une série de boucles autonomes qui convergent vers l’état déclaré. Les évolutions récentes (redimensionnement en place, gestion des ressources par pod, abandon de containerd 1.x et cgroup v1) ne modifient pas ce principe. Elles affinent la granularité des décisions prises à chaque étape, du scheduler jusqu’au runtime, et augmentent les prérequis côté infrastructure nœud.