Cloud et infrastructure

Comprendre la mécanique de suppression dans Kubernetes grâce aux finalizers et aux owner references

Un guide de 2021 explique comment les finalizers bloquent la suppression des ressources et comment les owner references gèrent les suppressions en cascade dans les clusters Kubernetes.

Illustration d'un conteneur avec des composants internes et un symbole de blocage représentant les finalizers.
Image : Kubernetes Blog, sous licence CC BY 4.0

Traduit automatiquement depuis l'original anglais.

Dans un article publié sur le blog Kubernetes en mai 2021, Aaron Alpar a détaillé la mécanique interne de la suppression d'objets au sein de Kubernetes. L'article clarifie pourquoi certaines ressources persistent parfois après l'émission d'une commande de suppression et explique le rôle des finalizers et des owner references dans la gestion de l'état du cluster.

Ce qui s'est passé

Kubernetes fournit des commandes standard pour créer, lire, mettre à jour et supprimer des objets, mais le processus de suppression est plus complexe qu'une simple retrait du stockage. Lorsqu'un utilisateur émet une commande kubectl delete, le système ne supprime pas toujours immédiatement l'objet de son registre, etcd. Au contraire, l'opération peut entrer dans un état en attente si certaines conditions sont réunies, comme la présence de finalizers ou de relations d'appartenance complexes.

L'article démontre que si les suppressions basiques fonctionnent comme prévu pour des ressources simples telles que les ConfigMaps sans métadonnées supplémentaires, l'ajout de finalizers modifie considérablement le comportement. Un finalizer agit comme un hook pré-suppression, signalant aux contrôleurs que des opérations de nettoyage doivent avoir lieu avant que la ressource ne soit entièrement supprimée. Si ces hooks ne sont pas résolus, l'objet reste dans un état de terminaison, visible via un horodatage de suppression (deletionTimestamp) mais toujours présent dans le cluster.

De plus, la relation entre les ressources, définie par les owner references, dicte la manière dont les groupes d'objets sont supprimés ensemble. La suppression d'un objet parent peut déclencher celle de ses enfants, un processus connu sous le nom de suppression en cascade. Cependant, ce comportement peut être modifié à l'aide de politiques de propagation, permettant aux développeurs d'orphaner les enfants ou de contrôler l'ordre de suppression. Comprendre ces mécanismes est crucial pour déboguer les namespaces bloqués ou les ressources persistantes.

Comment cela fonctionne

Les finalizers sont des clés attachées aux métadonnées d'une ressource qui empêchent sa collecte immédiate par le ramasse-miettes (garbage collection). Ils fonctionnent de manière similaire aux annotations, mais portent une sémantique importante pour les contrôleurs. Lorsqu'une demande de suppression est faite pour un objet possédant des finalizers, Kubernetes met à jour l'objet avec un deletionTimestamp mais bloque sa suppression depuis etcd. L'objet reste dans cet état jusqu'à ce qu'un contrôleur retire les clés de finalizer, signalant ainsi que le nettoyage est terminé. Si aucun contrôleur ne gère le finalizer, celui-ci devient un « dead » finalizer, nécessitant une intervention manuelle via une commande patch pour retirer la clé et permettre à la suppression de se poursuivre.

Figure from the original article: Comprendre la mécanique de suppression dans Kubernetes grâce aux finalizers et aux owner references
Figure de l’article original · Kubernetes Blog · CC BY 4.0

Les owner references établissent des relations parent-enfant entre les ressources au sein du même namespace. Chaque référence inclut le nom et l'identifiant unique (UID) de l'objet parent. Lorsqu'un parent est supprimé, Kubernetes vérifie ces références pour déterminer si les enfants doivent également être retirés. Cette suppression en cascade est contrôlée par une politique de propagation. La politique par défaut, qui est passée à background dans kubectl v1.20, permet de supprimer d'abord le parent tandis que les enfants sont retirés de manière asynchrone. Les autres options incluent foreground, où les enfants sont supprimés avant le parent, et orphan, qui ignore les owner references et laisse les enfants intacts.

Détails clés

  • Les finalizers sont des listes de clés sur les ressources qui signalent aux contrôleurs les opérations pré-suppression.
  • Les objets possédant des finalizers ne sont pas supprimés immédiatement ; ils reçoivent un deletionTimestamp et restent visibles tant que les finalizers ne sont pas effacés.
  • Les owner references lient les ressources via leur nom et leur UID, permettant des suppressions en cascade des objets enfants lorsqu'un parent est retiré.
  • Le comportement de cascade par défaut dans kubectl v1.20 et versions ultérieures est background, alors que les versions précédentes utilisaient true par défaut.
  • Les politiques de propagation (Foreground, Background, Orphan) contrôlent l'ordre de suppression et ne peuvent être définies que via des appels API directs, et non par les flags standards de kubectl.
  • Les namespaces bloqués peuvent être forcés à se finaliser en mettant à jour le subresource finalize via l'API, bien que cela risque de laisser des objets orphelins.

Pourquoi c'est important

Pour les ingénieurs qui construisent et maintiennent des plateformes Kubernetes, comprendre la mécanique de suppression évite la confusion lorsque les ressources ne disparaissent pas comme prévu. Un scénario courant implique un namespace qui reste dans un état Terminating parce qu'une ressource personnalisée ou un contrôleur tiers a ajouté un finalizer qui n'est plus traité. Sans savoir comment inspecter et patcher les finalizers, les opérateurs peuvent avoir du mal à nettoyer les clusters, entraînant des fuites de ressources et des échecs de déploiement.

Figure from the original article: Comprendre la mécanique de suppression dans Kubernetes grâce aux finalizers et aux owner references
Figure de l’article original · Kubernetes Blog · CC BY 4.0

De plus, gérer correctement les owner references garantit que les fermetures d'applications sont propres et prévisibles. Si un développeur supprime un Deployment sans comprendre les règles de cascade, il pourrait involontairement laisser derrière lui des Pods ou des Services qui consomment des ressources. Inversement, savoir utiliser la politique orphan permet des stratégies de migration sûres où les ressources enfants doivent survivre à la suppression de leur parent original. Cette connaissance est essentielle pour écrire des opérateurs robustes et des scripts d'automatisation interagissant avec l'API Kubernetes.

Ce que vous pouvez faire

  • Inspectez les objets bloqués en cours de suppression en vérifiant leur sortie YAML pour les champs finalizers et deletionTimestamp.
  • Supprimez manuellement les dead finalizers en utilisant kubectl patch avec une opération JSON pour retirer la clé de finalizer spécifique des métadonnées.
  • Utilisez kubectl get avec les owner references pour visualiser les dépendances entre les ressources avant d'effectuer des suppressions en masse.
  • Testez le comportement de cascade dans un environnement non-production en créant des ConfigMaps parent-enfant et en observant les effets des différentes commandes de suppression.
  • Utilisez kubectl proxy pour effectuer des appels API directs lorsque vous devez spécifier des politiques de propagation comme Foreground ou Background.
  • Faites preuve de prudence lors de la finalisation forcée des namespaces via l'API, car cela peut laisser des ressources orphelines nécessitant un nettoyage manuel.

Outils de la Boutique Bytechap

Continuer la lecture

Tous les articles