Cloud & Infrastruktur

Kubernetes-Löschmechanik verstehen: Finalizer und Owner References

Ein Leitfaden aus dem Jahr 2021 erklärt, wie Finalizer die Entfernung von Ressourcen blockieren und wie Owner References kaskadierende Löschvorgänge in Kubernetes-Clustern steuern.

Illustration eines Containers mit internen Komponenten und Finalizern
Bild: Kubernetes Blog, lizenziert unter CC BY 4.0

Automatisch aus dem englischen Original übersetzt.

In einem Beitrag im Kubernetes Blog vom Mai 2021 erläuterte Aaron Alpar die internen Mechanismen der Objekt Löschung innerhalb von Kubernetes. Der Artikel klärt auf, warum Ressourcen manchmal nach der Ausführung eines Löschbefehls weiterhin bestehen bleiben, und erklärt die Rolle von Finalizern und Owner References bei der Verwaltung des Cluster-Zustands.

Was passiert ist

Kubernetes stellt Standardbefehle zum Erstellen, Lesen, Aktualisieren und Löschen von Objekten bereit, aber der Löschprozess ist komplexer als eine einfache Entfernung aus dem Speicher. Wenn ein Benutzer einen kubectl delete-Befehl ausführt, entfernt das System das Objekt nicht immer sofort aus seiner Registrierung, etcd. Stattdessen kann der Vorgang in einen ausstehenden Zustand übergehen, wenn bestimmte Bedingungen erfüllt sind, wie etwa das Vorhandensein von Finalizern oder komplexen Eigentümerbeziehungen.

Der Artikel zeigt, dass während grundlegende Löschvorgänge für einfache Ressourcen wie ConfigMaps ohne zusätzliche Metadaten wie erwartet funktionieren, das Hinzufügen von Finalizern das Verhalten erheblich verändert. Ein Finalizer fungiert als Pre-Delete-Hook und signalisiert Controllern, dass Aufräumoperationen durchgeführt werden müssen, bevor die Ressource vollständig entfernt wird. Wenn diese Hooks nicht aufgelöst werden, verbleibt das Objekt im Terminating-Zustand, sichtbar über einen Löschzeitstempel, aber weiterhin im Cluster vorhanden.

Darüber hinaus bestimmt die Beziehung zwischen Ressourcen, definiert durch Owner References, wie Gruppen von Objekten gemeinsam gelöscht werden. Das Löschen eines Elternobjekts kann das Löschen seiner Kinder auslösen, ein Prozess, der als Kaskadierung bezeichnet wird. Dieses Verhalten kann jedoch mithilfe von Propagationsrichtlinien geändert werden, sodass Entwickler Kinder orphanen (verwaist lassen) oder die Reihenfolge des Löschens steuern können. Das Verständnis dieser Mechanismen ist entscheidend für die Fehlerbehebung bei hängenden Namespaces oder verbleibenden Ressourcen.

Wie es funktioniert

Finalizer sind Schlüssel, die an die Metadaten einer Ressource angehängt sind und eine sofortige Garbage Collection verhindern. Sie funktionieren ähnlich wie Annotationen, tragen jedoch semantisches Gewicht für Controller. Wenn eine Löschanfrage für ein Objekt mit Finalizern gestellt wird, aktualisiert Kubernetes das Objekt mit einem deletionTimestamp, blockiert aber seine Entfernung aus etcd. Das Objekt verbleibt in diesem Zustand, bis ein Controller die Finalizer-Schlüssel entfernt und damit signalisiert, dass die Bereinigung abgeschlossen ist. Wenn kein Controller den Finalizer verwaltet, wird er zu einem "toten" Finalizer, der manuelle Eingriffe über einen Patch-Befehl erfordert, um den Schlüssel zu entfernen und das Löschen fortzusetzen.

Figure from the original article: Kubernetes-Löschmechanik verstehen: Finalizer und Owner References
Abbildung aus dem Originalartikel · Kubernetes Blog · CC BY 4.0

Owner References stellen Eltern-Kind-Beziehungen zwischen Ressourcen innerhalb desselben Namespaces her. Jede Referenz enthält den Namen und die eindeutige Kennung (UID) des Elternobjekts. Wenn ein Elternobjekt gelöscht wird, prüft Kubernetes diese Referenzen, um festzustellen, ob auch die Kinder entfernt werden sollen. Diese kaskadierende Löschung wird durch eine Propagationsrichtlinie gesteuert. Die Standardrichtlinie, die sich in kubectl v1.20 auf background geändert hat, erlaubt es, das Elternobjekt zuerst zu löschen, während die Kinder asynchron entfernt werden. Weitere Optionen sind foreground, bei denen die Kinder vor dem Elternobjekt gelöscht werden, und orphan, das Owner References ignoriert und die Kinder intakt lässt.

Wichtige Details

  • Finalizer sind Listen von Schlüsseln auf Ressourcen, die Pre-Delete-Operationen an Controller signalisieren.
  • Objekte mit Finalizern werden nicht sofort entfernt; sie erhalten einen deletionTimestamp und bleiben sichtbar, bis die Finalizer gelöscht sind.
  • Owner References verknüpfen Ressourcen über Name und UID und ermöglichen so kaskadierende Löschungen von Kindobjekten, wenn ein Elternobjekt entfernt wird.
  • Das Standard-Kaskadierungsverhalten in kubectl v1.20 und neuer ist background, während frühere Versionen standardmäßig true waren.
  • Propagationsrichtlinien (Foreground, Background, Orphan) steuern die Reihenfolge des Löschens und können nur über direkte API-Aufrufe festgelegt werden, nicht über Standard-kubectl-Flags.
  • Hängende Namespaces können gezwungen werden, finalisiert zu werden, indem das finalize-Subresource über die API aktualisiert wird, wobei das Risiko besteht, verwaiste Objekte zurückzulassen.

Warum das wichtig ist

Für Ingenieure, die Kubernetes-Plattformen erstellen und warten, verhindert das Verständnis der Löschmechanik Verwirrung, wenn Ressourcen nicht wie erwartet verschwinden. Ein häufiges Szenario betrifft einen Namespace, der im Zustand Terminating verbleibt, weil eine benutzerdefinierte Ressource oder ein Drittanbieter-Controller einen Finalizer hinzugefügt hat, der nicht mehr verarbeitet wird. Ohne Kenntnis darüber, wie man Finalizer inspiziert und patcht, könnten Operatoren Schwierigkeiten haben, Cluster zu bereinigen, was zu Ressourcenlecks und Deployment-Fehlern führt.

Figure from the original article: Kubernetes-Löschmechanik verstehen: Finalizer und Owner References
Abbildung aus dem Originalartikel · Kubernetes Blog · CC BY 4.0

Zusätzlich stellt die korrekte Verwaltung von Owner References sicher, dass Anwendungsabbau sauber und vorhersehbar erfolgt. Wenn ein Entwickler ein Deployment löscht, ohne die Kaskadierungsregeln zu verstehen, könnte er unbeabsichtigt Pods oder Services zurücklassen, die Ressourcen verbrauchen. Umgekehrt ermöglicht das Wissen um die Verwendung der orphan-Richtlinie sichere Migrationsstrategien, bei denen Kindressourcen die Löschung ihres ursprünglichen Elternobjekts überleben müssen. Dieses Wissen ist unerlässlich für das Schreiben robuster Operatoren und Automatisierungsskripte, die mit der Kubernetes-API interagieren.

Was Sie tun können

  • Untersuchen Sie Objekte, die beim Löschen hängen bleiben, indem Sie ihre YAML-Ausgabe auf die Felder finalizers und deletionTimestamp prüfen.
  • Entfernen Sie tote Finalizer manuell mit kubectl patch unter Verwendung einer JSON-Operation, um den spezifischen Finalizer-Schlüssel aus den Metadaten zu entfernen.
  • Verwenden Sie kubectl get mit Owner References, um Abhängigkeiten zwischen Ressourcen zu visualisieren, bevor Sie Bulk-Löschungen durchführen.
  • Testen Sie das Kaskadierungsverhalten in einer Nicht-Produktionsumgebung, indem Sie Eltern-Kind-ConfigMaps erstellen und die Auswirkungen verschiedener Löschbefehle beobachten.
  • Nutzen Sie kubectl proxy, um direkte API-Aufrufe durchzuführen, wenn Sie Propagationsrichtlinien wie Foreground oder Background angeben müssen.
  • Seien Sie vorsichtig, wenn Sie die Namespace-Finalisierung über die API erzwingen, da dies verwaiste Ressourcen hinterlassen kann, die eine manuelle Bereinigung erfordern.

Tools aus dem Bytechap-Shop

Weiterlesen

Alle Artikel