Provenance & Lebenszyklus
Der Operator folgt einer entscheidenden Regel:
Installieren Sie niemals neu, was der Benutzer installiert hat. Deinstallieren Sie niemals, was uns nicht gehört.
Diese Seite erklärt, wie sich diese Regel bei Installationen von Capability-Operatoren und Datenspeicher-Instanzen auswirkt und wie die Bereinigung bei Löschung und Migration funktioniert.
Zwei Ebenen von Provenance
1. Operator-Install-Provenance
Wenn eine Resource einen Capability-Operator benötigt (z. B. ein managed PostgresCluster benötigt CloudNativePG), erkennt der gemeinsame Installer des Operators den aktuellen Zustand, bevor er irgendetwas tut:
- Gibt es ein Helm-Release mit dem erwarteten Namen im erwarteten Namespace?
- Mit dem Ownership-Label
app.kubernetes.io/managed-by=navique-ai-core-operatorund der Annotationcore.navique.com/provenance=owned→ Owned. - Ohne diese Labels → Adopted (Sie oder ein anderes Tool haben es installiert).
- Mit dem Ownership-Label
- Kein eigenes Release, aber die CRDs des Operators existieren und sein Controller läuft irgendwo im Cluster → Adopted.
- Nichts vorhanden → Absent.
Der Controller wird anhand seiner Identität erkannt — über seine bekannten Labels, ersatzweise über das Repository seines Container-Images — und nicht danach, ob „irgendetwas in dem Namespace läuft, den wir verwendet hätten". Daraus folgen zwei wichtige Punkte:
- Ein Operator, den Sie in einem anderen Namespace installiert haben (CNPG in
postgres-operatorstattcnpg-system) oder über OLM / reine Manifeste / einen anderen Release-Namen, wird adoptiert und nicht dupliziert. Diese Operatoren besitzen cluster-weite CRDs; ein zweiter Controller würde mit dem ersten um dieselben Ressourcen konkurrieren. - Eine unbeteiligte Workload, die nur zufällig im erwarteten Namespace liegt, wird nicht mit dem Operator verwechselt — der Operator wird also weiterhin installiert.
CRDs allein genügen nie: verwaiste CRDs aus einer früheren Deinstallation gelten als Absent und werden neu installiert.
Die Aktion ergibt sich aus dem Zustand:
| Zustand | Aktion |
|---|---|
| Absent | Unser Standalone-Release installieren, gekennzeichnet mit dem Ownership-Label/der -Annotation |
| Adopted | Die Übernahme erfassen; koexistieren; den Lebenszyklus niemals verwalten |
| Owned | Bereits unseres; optional auf die gepinnte Version upgraden |
Da die Erkennung vor jeder Installation läuft, trifft der Operator niemals auf Helms Konflikt „CRD already owned by another release".
2. Datenspeicher-Instanz-Provenance
Dasselbe Prinzip eine Ebene tiefer, über das Feld mode an Datenspeicher-Resources:
| Modus | Ownership |
|---|---|
managed | Der Operator erstellt, besitzt und garbage-collectet die Datenspeicher-CR |
adopt | Referenziert einen vom Benutzer erstellten Datenspeicher; wird nie gelöscht oder umkonfiguriert |
external | Ein vom Benutzer gehosteter Datenspeicher; nur ein Connection Secret wird verdrahtet |
Lazy, ref-counted Installationen
Capability-Operatoren werden lazy installiert — ein Chart wird nur installiert, wenn eine Resource tatsächlich ihren managed-Modus auswählt. Wenn jeder Datenspeicher external oder adopt ist, wird dieser Operator nie installiert.
Installationen sind ref-counted. Der Operator zieht es vor, den Ref-Count neu zu berechnen, anstatt ihn zu persistieren: bei jedem Reconcile listet er die relevanten Resources auf und berechnet, welche eine gegebene Abhängigkeit noch benötigen (jedes Gateway ⇒ litellm-operator; jeder managed PostgresCluster ⇒ cloudnative-pg; …). Dies übersteht Operator-Neustarts ohne externes Bookkeeping.
Bereinigung bei Löschung
Jede Resource hat einen Finalizer. Beim Löschen tut der Controller:
- Löscht die emittierten Upstream-CRs oder deinstalliert das Workload-Helm-Release (für
ChatUI/MeilisearchInstance). - Für jeden Capability-Operator, den die Resource benötigte, dekrementiert er den Ref-Count und deinstalliert ihn — nur wenn der Count null erreicht und das Release Owned ist. Adopted- und External-Releases werden niemals angefasst.
- Für managed Datenspeicher löscht er die vom Operator erstellte Datenspeicher-CR (nicht adoptierte).
- Entfernt den Finalizer.
func Release(name, owner) error {
refcount.Remove(name, owner)
if refcount.Count(name) > 0 { return nil } // still needed
if detect(name) != Owned { return nil } // adopted/external — never touch
return helm.Uninstall(name) // only owned + unused
}Bereinigung bei Migration
Wenn sich mode, type oder Referenzen einer Resource ändern, vergleicht der Operator den alten und neuen status und entfernt nur die nun verwaisten operator-owned Resources. Beispielsweise löscht das Umschalten eines PostgresCluster von managed auf external das vom Operator erstellte CNPG-Cluster und gibt dann cloudnative-pg frei, falls kein anderer Konsument verbleibt. Adopted- und External-Resources werden niemals gelöscht.
Install-Readiness — mehr als CRDs
„Ready" für einen Capability-Operator bedeutet, dass seine CRDs Established sind UND alle Deployments/StatefulSets des Charts tatsächlich Ready sind — nicht nur, dass die CRDs existieren. Ein Operator, dessen Pod an einem fehlenden Webhook-Zertifikat festhängt, hat etablierte CRDs, kann aber nicht funktionieren, daher wartet der Operator auf tatsächliche Readiness.
Einige Charts haben Voraussetzungen. Beispielsweise wird das Webhook-Zertifikat des ClickHouse-Operators von cert-manager ausgestellt, daher wird cert-manager zuerst bis zur vollständigen Readiness sichergestellt. Der Operator behandelt cert-manager als universelle Voraussetzung und hält Webhooks und Leader Election aktiviert (produktionsgetreu), anstatt sie zu deaktivieren.
Auditierbarkeit
Der Resource-Status legt die gebündelten Chart-Versionen und den Provenance-Zustand (owned / adopted) offen, sodass Sie genau auditieren können, was der Operator installiert gegenüber adoptiert hat. Der Operator zeichnet außerdem Events für Übernahmen, lizenzbedingte Skips, Instanzlimit-Ablehnungen, Ablauf-Downgrades und Garbage-Collection-Aktionen auf. Siehe Fehlerbehebung.