Was sind Finalizer in Kubernetes? Umgang mit Objektlöschungen

0
241

Das Löschen von Kubernetes-Objekten ist nicht so einfach, wie es auf der Oberfläche. Das Löschen eines Objekts ist ein komplizierter Prozess, der bedingte Prüfungen umfasst, um festzustellen, ob ein sicheres Entfernen möglich ist. Dies wird durch API-Objekte erreicht, die als Finalizer bezeichnet werden.

In diesem Artikel sehen wir uns an, was Finalizer sind, wie sie verwaltet werden und welche Herausforderungen sie beim Löschen einer Datei verursachen können Objekt. Ein besseres Verständnis des Löschvorgangs kann Ihnen helfen, Probleme zu beheben, bei denen Ressourcen nicht rechtzeitig beendet werden.

Was sind Finalizer?

Finalizer sind ein Mechanismus zum Erzwingen bestimmter Bedingungen, die erfüllt werden müssen, bevor ein Objekt gelöscht werden kann. Wenn Sie einen Befehl wie kubectl delete namespace/example ausführen, überprüft Kubernetes die Finalizer, die für das referenzierte Objekt definiert sind. Diese werden im Feld metadata.finalizers aufgelistet. Jeder Finalizer hat die Möglichkeit, das Löschen zu verschieben, bis seine Aktionen abgeschlossen sind.

Der eigentliche Löschvorgang sieht so aus:

  1. Einen Löschbefehl ausgeben. – Kubernetes markiert das Objekt als ausstehendes Löschen. Dadurch bleibt die Ressource im schreibgeschützten “Terminating” Bundesstaat.
  2. Führen Sie alle Aktionen aus, die den Finalizern des Objekts zugeordnet sind. – Jedes Mal, wenn eine Finalizer-Aktion abgeschlossen ist, wird dieser Finalizer vom Objekt getrennt, sodass er nicht mehr im Feld metadata.finalizers angezeigt wird.
  3. Kubernetes überwacht weiterhin die an das Objekt angehängten Finalizer . – Das Objekt wird gelöscht, sobald das Feld metadata.finalizers leer ist, da alle Finalizer nach Abschluss ihrer Aktionen entfernt wurden.

Finalizer werden häufig verwendet, um Bereinigungs- und Garbage-Collection-Prozeduren auszuführen, bevor ein Objekt aus dem Cluster entfernt wird. Sie können Ihre eigenen Finalizer mithilfe der Kubernetes-API hinzufügen. integrierte Finalizer werden auch automatisch auf einige Objekttypen angewendet.

Zum Beispiel werden PersistentVolume-Ressourcen mit einem kubernetes.io/pv-protection Finalizer geliefert, der ein versehentliches Löschen von Volumes verhindert, die von Pods aktiv verwendet werden. Der Finalizer erzwingt, dass das PersistentVolume nicht aus dem Cluster entfernt werden kann, bis keine Pods es verwenden. Wenn ein Löschbefehl ausgegeben wird, während noch ein aktiver Pod vorhanden ist, wird das Volume als Beenden markiert; es bleibt so lange in diesem Zustand, wie der Pod das Volumen benötigt, und wird danach so schnell wie möglich automatisch gelöscht.

Finalizer-Herausforderungen

Finalizer mit langer Ausführungszeit, die auf eine Bedingung warten, die andere Ressourcen einbezieht, können dazu führen, dass Löschvorgänge im Beenden-Zustand hängen bleiben. Sie können auch auf Probleme stoßen, bei denen ein Finalizer das Löschen abhängiger Objekte blockiert, was verhindert, dass das übergeordnete Objekt erfolgreich beendet wird.

Werbung

Diese Probleme verursachen regelmäßig Verwirrung – Entwickler und Betreiber neigen dazu, Löschungen als einfache Prozeduren zu betrachten, wenn der Prozess tatsächlich nuanciert und variabel ist. Die Voraussetzungen für ein erfolgreiches Löschen hängen von den Beziehungen der Ressource und ihren Finalizern sowie vom Zielobjekt selbst ab.

Wenn ein Objekt zu lange beendet wurde, überprüfen Sie seine Finalizer, indem Sie das Metadaten.finalizers-Feld in seiner YAML überprüfen:

kubectl get pod example-pod –namespace example -o json | jq

Sobald Sie wissen, welche Finalizer definiert sind, können Sie damit beginnen, diejenigen zu identifizieren, die eine Löschung wahrscheinlich blockieren. Das Anzeigen der Ereignisse und Zustandsänderungen des Objekts kann das Debuggen unterstützen, indem Aktionen angezeigt werden, die seit der Ausgabe des Löschbefehls aufgetreten sind. Bedingungen werden im YAML-Feld spec.status.conditions angezeigt; Ereignisse sind sichtbar, wenn kubectl describe pod example-pod ausgeführt wird.

Sie können die Finalizer eines Objekts manuell entfernen, indem Sie das Feld spec.finalizers auf null patchen. Diese Technik sollte nicht verwendet werden, es sei denn, es ist unbedingt erforderlich. Finalizer sind Sicherheitsvorkehrungen zum Schutz Ihres Clusters. Sie zu überschreiben könnte zu verwaisten Objekten und unterbrochenen Abhängigkeitsketten führen.

kubectl patch pod example-pod -p '{“metadata: {“finalizers”: null}}'

Besitzer- und Weitergaberichtlinien

Ein verwandtes Thema ist Objektbesitzer und Richtlinien zur Weitergabe von Löschungen. Besitzerreferenzen definieren die Beziehungen zwischen Objekten. Sie werden verwendet, um ganze Objektbäume zu entfernen, wenn ein übergeordnetes Objekt gelöscht wird. Wenn Sie beispielsweise ein Deployment löschen, muss Kubernetes auch die darin enthaltenen Pods zerstören diese Bereitstellung.

Besitzerreferenzen werden über das Feld metadata.ownerReferences auf Objekten definiert. Jede Referenz enthält die Art und den Namen des Objekts, dem die aktuelle Ressource übergeordnet werden soll.

Werbung

Wenn Besitzerreferenzen verwendet werden, entfernt das Löschen eines übergeordneten Objekts automatisch alle seine untergeordneten Elemente. Dies wird als kaskadierendes Löschen bezeichnet. Es ist möglich, die Kaskade zu deaktivieren, indem Sie das Flag –cascade=orphan zu kubectl delete hinzufügen. Kubernetes lässt zu, dass die untergeordneten Objekte des Objekts im Cluster verbleiben, sodass sie verfügbar, aber verwaist bleiben.

Kubernetes unterstützt auch verschiedene “Verbreitungsrichtlinien” Diese legen fest, ob zuerst das übergeordnete Element oder seine untergeordneten Elemente gelöscht werden. Die standardmäßige Foreground-Richtlinie löscht die untergeordneten Elemente und dann die übergeordneten Elemente, um sicherzustellen, dass keine Verwaisung auftritt. Der Hintergrund kehrt die Reihenfolge um, sodass das übergeordnete Element zuerst entfernt wird. Die dritte Richtlinie, Orphan, weist Kubernetes an, Besitzerverweise ganz zu ignorieren.

Der Befehl kubectl delete unterstützt keine Weitergaberichtlinien. Sie müssen eine direkte API-Anfrage stellen, wenn Sie die Richtlinie für einen Löschvorgang ändern möchten:

curl -X DELETE localhost/api/v1/namespaces/default/deployments/example -d '{“apiVersion”: “v1”, “kind”: “DeleteOptions”, “propagationPolicy”: “Background”}' -H “Content-Type: application/json”

Finalizer werden berücksichtigt, wenn eine Löschung an verwandte Objekte weitergegeben oder kaskadiert wird. Im Fall der Foreground-Richtlinie bedeutet dies, dass alle Finalizer für alle untergeordneten Elemente abgeschlossen werden müssen, bevor der Elternteil beenden kann. Bei der Hintergrundrichtlinie bleiben Kinder live, bis die Finalizer ihrer Eltern fertig sind.

Implementieren von Finalizern

Sie können Ihre eigenen Finalizer mithilfe von . implementieren die Kubernetes-API und das Go-SDK. Finalizer werden erstellt, indem Hooks in der Reconcile-Methode eines Controllers registriert werden.

Die Methode sollte prüfen, ob das abzugleichende Objekt einen Wert in seinem DeletionTimestamp-Feld hat. Dies bedeutet, dass das Löschen aussteht und sich im Status Beendend befindet. Wählen Sie einen Bezeichner für Ihren Finalizer aus und prüfen Sie, ob das Objekt den Wert in seinem Metadaten.finalizers-Feld enthält. Wenn dies der Fall ist, sollten Sie alle erforderlichen Aktionen ausführen und dann den Finalizer vom Objekt trennen. Eine Beispielimplementierung ist im Kubebuilder-Leitfaden zum Schreiben eigener Kubernetes-Objekttypen mithilfe von CRDs (benutzerdefinierten Ressourcendefinitionen) enthalten.

Finalizer werden immer als Code in einer Controller-Methode implementiert. Das Feld metadata.finalizers verhält sich ähnlich wie Annotationen und Labels und listet die Finalizer auf, die auf dieses Objekt angewendet werden sollen, ohne den auszuführenden Code direkt zu definieren.

Schlussfolgerung

Finalizer steuern den Lebenszyklus eines Kubernetes-Objekts, nachdem das Löschen initiiert wurde. Sie werden verwendet, um die Garbage Collection zu implementieren, Controller über bevorstehende Entfernungen zu benachrichtigen und das versehentliche Löschen von Objekten zu verhindern, auf die noch von anderen Ressourcen verwiesen wird.

Werbung

Weil Finalizer das Löschen von Objekten blockieren können für beliebig lange Zeiträume, sie sind eine häufige Quelle der Frustration, wenn Einsatzteams nicht verstehen, warum ein Objekt “festsitzt” beendend. In dieser Situation ist es am besten, die betroffenen Ressourcen zu untersuchen, festzustellen, welche Finalizer aktiv sind, und die Beziehungen zwischen Objekten zu untersuchen, die möglicherweise als blockierende Abhängigkeiten fungieren. Das Entfernen eines Finalizers erzwingen sollte Ihr letzter Ausweg sein, wenn Sie ein Terminating-Objekt sofort löschen müssen oder alle anderen Optionen ausgeschöpft sind.