Fehlerbehebung
Der Operator ist darauf ausgelegt, selbsterklärend zu sein: Wenn etwas aussteht oder fehlerhaft ist, sagen Ihnen die status.conditions der Resource und die Kubernetes Events genau, worauf gewartet wird. Beginnen Sie dort.
Erste Schritte
# The resource's conditions, events, and phase.
kubectl -n <ns> describe gateway <name>
# Just the conditions.
kubectl -n <ns> get gateway <name> -o jsonpath='{.status.conditions}' | jq
# The operator's own logs.
kubectl -n navique-system logs deploy/navique-ai-core-operator -fJede Resource legt eine Ready-Bedingung plus phasenbezogene Bedingungen offen (SecretsReady, OperatorsReady, DatastoreReady, WorkloadReady, …), jeweils mit einem reason und einer message.
Bedingungen lesen
| Condition reason | Was es bedeutet | Was zu tun ist |
|---|---|---|
SecretsNotReady | Das referenzierte SecretsManagement ist nicht ready | Prüfen Sie die SecretsManagement-Resource und ihr ESO-/Sealed-Secrets-Backend |
WaitingForCRDEstablished | Die CRDs eines Capability-Operators sind noch nicht Established | Normal während der Installation; prüfen Sie die Pods des Operators, falls es andauert |
DependencyNotReady | Ein referenzierter Datenspeicher / ein Gateway / ein Langfuse ist nicht ready | Inspizieren Sie die referenzierte Resource |
AutoWiringUnlicensed | Eine Referenz benötigt Auto-Wiring, das nicht lizenziert ist | Geben Sie die in der Meldung benannten manuellen Felder an oder spielen Sie eine Lizenz ein |
LicenseLimitExceeded | Sie haben ein lizenziertes Instanzlimit überschritten | Reduzieren Sie Instanzen oder erhöhen Sie die limits in der Lizenz |
BackendNotImplemented | Ein nur gerüstetes Backend (zalando / cockroachdb) wurde ausgewählt | Verwenden Sie cnpg oder adopt / external |
InfrastructureBlocked | Ein verwalteter Datastore-Pod kann aus einem Cluster-Infrastrukturgrund nicht starten, den der Operator durch Warten nicht beheben kann | Lesen Sie die Meldung — sie nennt den Pod und die Ursache (nicht planbar, Volume-Anbindung, Image-Pull) — und beheben Sie es auf Cluster-Ebene |
Eine Resource, die wartend requeued, ist normal — der Operator requeued, anstatt für „noch nicht ready" einen Fehler zu werfen. Eine Resource, die mit einem Fehler-reason auf Ready=False festhängt, ist diejenige, die zu untersuchen ist.
Diagnose der Capability-Operator-Installation
Wenn ein Capability-Operator nicht hochkommt, inspiziert der Operator dessen Namespace und legt die Ursache im Status der konsumierenden Resource offen — beispielsweise den Waiting-Reason eines Containers, ein OOM/eine Last-Termination oder das jüngste Warning-Event wie FailedMount: secret "webhook-server-cert" not found. So wird eine festgefahrene Upstream-Installation in der Resource erklärt, die sie benötigt.
# Inspect a capability operator directly.
kubectl -n cnpg-system get pods
kubectl -n cert-manager get pods,events --sort-by=.lastTimestampHäufige Probleme
Der Manager wird per OOM beendet
Die in das Binary integrierte Helm-Engine rendert Charts in-process und benötigt Speicher. Geben Sie dem Manager ~1Gi — die Standard-Kubebuilder-Limits sind zu niedrig und treten nur im Cluster zutage. Siehe Konfiguration.
Ein Capability-Operator wird nicht ready
Meistens ein fehlendes Webhook-Zertifikat (cert-manager nicht ready) oder unzureichendes RBAC. cert-manager wird als universelle Voraussetzung behandelt und zuerst sichergestellt; bestätigen Sie, dass es gesund ist. Prüfen Sie, ob das breite Install-RBAC des Operators vorhanden ist.
Ein Datastore bleibt bei InfrastructureBlocked hängen
Ein verwalteter PostgresCluster, ClickHouseCluster, RedisInstance, MongoCluster oder MeilisearchInstance, dessen Pods nicht starten können, meldet Ready=False mit dem Grund InfrastructureBlocked statt der generischen „warte …“-Meldung (dasselbe Detail erscheint in einer Stack-Komponentenmeldung und einem Warning-Event). Die Meldung nennt den Pod und die zugrunde liegende Ursache, sodass Sie nicht kubectl describe brauchen:
- Unschedulable — der Scheduler konnte einen Pod nicht platzieren (meist
Insufficient cpu/memory). Scheduling erfolgt pro Knoten: eine Anforderung, die die freie Kapazität eines einzelnen Knotens übersteigt, bleibtPending, selbst wenn die gesamte freie Kapazität des Clusters auszureichen scheint. Fügen Sie einen Knoten hinzu, erhöhen Sie das Node-Pool-Maximum bzw. das Cluster-Autoscaler-Limit (prüfen Sie, dass er nicht im Scale-up-Backoff steckt), oder senken Sieresources.requests/instancesdes Datastores. - VolumeAttachFailed — ein Persistent Volume konnte nicht angebunden/gemountet werden (z. B. ein Azure-Managed-Disk-
cannot find Lun, wenn ein Knoten die maximale Anzahl Datenträger seiner VM-Größe erreicht hat, oder ein CSI-Anbindungsfehler). Planen Sie den Pod auf einen Knoten mit freien Disk-Slots um, oder verwenden Sie eine größere VM-SKU. - ImagePullFailed — das Image kann nicht gezogen werden (falsche Registry/falsches Tag, fehlendes Pull-Secret, Registry nicht erreichbar). Prüfen Sie den Registry-Mirror und die Pull-Secret-Konfiguration.
Der Operator führt durchgehend Requeues aus — er meldet keinen Fehler und macht nichts rückgängig — sodass sich die Ressource von selbst erholt, sobald die Ursache auf Cluster-Ebene behoben ist.
Ein Capability-Operator installiert nicht — conflict with "argocd-controller": .spec.versions
Ein Datastore/Workload bleibt Ready=False mit einem Fehler wie install langfuse-operator: failed to install CRD … conflict with "argocd-controller": .spec.versions. Das passiert, wenn eine Upstream-CRD zuvor von einer anderen, inzwischen gelöschten GitOps-App installiert wurde — die App ist weg, aber ihre CRDs wurden nie entfernt (CRDs werden das nie), sodass sie mit der stale Server-Side-Apply- Feldzugehörigkeit jener App zurückbleiben. Helm installiert die CRDs eines Charts aus dessen crds/-Verzeichnis über einen Pfad, der SSA-Konflikte nicht erzwingt, sodass der zurückgebliebene Eigentümer die Installation blockiert.
Der Operator heilt das nun automatisch: vor der Installation eines Capability-Operators erkennt er einen fremden Feldmanager (argocd-controller, flux, …) auf seinen deklarierten CRDs und setzt diese stale Zugehörigkeit zurück (nicht-destruktiv — Spec und Instanzen bleiben unberührt). Falls Sie es auf einem älteren Operator-Build treffen, bereinigen Sie es manuell:
# Bestätigen Sie, dass keine aktive GitOps-App die CRD wirklich verwaltet (nur ein stale Tombstone):
kubectl get crd <crd> -o jsonpath='{range .metadata.managedFields[*]}{.manager}({.operation}){"\n"}{end}'
# Feldzugehörigkeits-Bookkeeping zurücksetzen (berührt weder Spec noch Instanzen):
kubectl patch crd <crd> --type=merge -p '{"metadata":{"managedFields":[{}]}}'
# Dann den Operator erneut versuchen lassen (er requeued automatisch).CRDs eines neu installierten Kinds werden nicht gefunden
Direkt nachdem ein CRD-tragendes Chart installiert wurde, gibt es ein kleines bekanntes Race, bei dem das neue Kind noch nicht im Discovery-Cache ist. Der Operator behandelt einen transienten NoResourceMatchError als Requeue und erholt sich automatisch — es sollte sich innerhalb von ein oder zwei Reconciles klären.
Eine neue CRD fehlt nach einer kustomize-Installation
Bei der Installation aus dem Quellcode muss eine CRD in config/crd/kustomization.yaml aufgeführt sein, sonst lässt kustomize sie stillschweigend weg (envtest besteht weiterhin, was es verbergen kann). Verwenden Sie die bereitgestellten Overlays, die alle CRDs enthalten.
Auto-Wiring findet nicht statt
Auto-Wiring ist lizenziert. Ohne das auto-wiring-Feature verwendet der Operator Ihre manuellen Felder und emittiert eine AutoWiringUnlicensed-Bedingung, die genau benennt, was zu setzen ist. Beim Gateway→Langfuse-Key-Erzeugen denken Sie daran, dass es zusätzlich ein Langfuse-Enterprise-Deployment benötigt — siehe Auto-Wiring.
Das Löschen einer Resource hängt
Ein Finalizer führt die Bereinigung durch (Entfernen emittierter CRs, Deinstallieren von owned Releases). Prüfen Sie die Operator-Logs; wenn eine referenzierte Abhängigkeit selbst festhängt, wartet der Finalizer. Er löscht keine adopted/external Resources.
Wenn eine CRD im Zustand Terminating festhängt (und damit auch jede darüber liegende Owner-Kette — z. B. ein Stack oder ChatUI, dessen Löschung nie abschließt), suchen Sie nach einer übrig gebliebenen Custom Resource dieser CRD, die noch einen Finalizer eines bereits deinstallierten Upstream-Operators trägt. Ein solcher Finalizer ist verwaist — sein Controller existiert nicht mehr, um ihn zu entfernen —, sodass weder das Objekt noch der darüber liegende apiextensions-CRD-Cleanup-Finalizer jemals abgeschlossen werden kann. Der Operator entfernt diese Finalizer nun automatisch bei der Deinstallation eines Capability-Operators, sodass dies nicht erneut auftreten sollte. Um einen bereits blockierten Cluster wiederherzustellen, entfernen Sie den toten Finalizer einmalig:
kubectl patch <kind> <name> -n <ns> --type=merge -p '{"metadata":{"finalizers":null}}'ChatUI-SSO-Anmeldung scheitert hinter einer WAF / TLS-terminierenden Gateway
Wenn einer ChatUI (LibreChat) ein TLS-terminierendes Ingress oder eine externe WAF (z. B. ein Azure Application Gateway) vorgeschaltet ist, kann die OIDC/SSO-Anmeldung auf drei verschiedene, aufeinander gestapelte Arten fehlschlagen — beheben Sie sie von außen nach innen:
Der IdP weist die Weiterleitung ab (
AADSTS900971: No reply address providedoder eine Redirect-Abweichung). LibreChat bildet seinen Callback ausDOMAIN_SERVER, das der Operator aus dem ChatUI-Host ableitet. Setzen Siehostundingress.tls: truean derChatUI(bzw. amchatUIdes Stacks), damitDOMAIN_SERVERzuhttps://<host>wird, und registrieren Siehttps://<host>/oauth/openid/callbackals Web-Redirect-URI im IdP.Die Edge gibt vor der App ihren eigenen
403zurück (z. B. eineMicrosoft-Azure-Application-Gateway/v2-Seite). Eine WAF blockiert den OIDC-Callback: Die base64url-Parametercode/state/id_tokenlösen die OWASP-SQLi-Regeln (942430 / 942440) als Fehlalarme aus. Fügen Sie eine enge, regelspezifische Ausnahme für genau diese Argumentnamen auf dem Pfad/oauth/*hinzu und belassen Sie die übrige WAF im Prevention-Modus. Bestätigen Sie die genaue Regel anhand der WAF-/Firewall-Logs, bevor Sie sie ausschließen.Die App zeigt „Authentication failed“ mit
Unable to verify authorization request statein den LibreChat-Logs. Durch die TLS-Terminierung sieht die App reines HTTP, sodass einSecure-Session-Cookie verworfen und der OAuth-stateverloren geht. Der Operator setzt automatischSESSION_COOKIE_SECURE=false, sobaldspec.ssoaktiviert ist — das ist also ab Werk abgedeckt. Falls es weiter auftritt, prüfen Sie, ob der laufende LibreChat-Pod diese Variable trägt (der Operator verwaltet die*-librechat-configenv-ConfigMap).
Ein anderes Symptom — die Anmeldung erreicht die App, scheitert aber mit auth_failed und registered with "local" provider — bedeutet, dass ein bereits vorhandenes Konto (z. B. zuvor durch das Identitätsmanagement erstellt) diese E-Mail-Adresse bereits unter einem Nicht-OIDC-Provider belegt. Das Löschen der zugehörigen Identity/User-CR baut das LibreChat-Konto nun per Finalizer ab; liegt ein älteres verwaistes Konto vor, entfernen Sie es einmalig mit dem mitgelieferten npm run delete-user <email> und melden sich erneut an.
Das Gesamtbild erhalten
# All Navique resources across the cluster.
kubectl get -A \
licenses.core.navique.com,secretsmanagements.core.navique.com,\
postgresclusters.core.navique.com,clickhouseclusters.core.navique.com,\
redisinstances.core.navique.com,mongoclusters.core.navique.com,\
meilisearchinstances.core.navique.com,gateways.core.navique.com,\
langfuses.core.navique.com,chatuis.core.navique.com
# License status (features + limits in effect).
kubectl get license cluster -o jsonpath='{.status}' | jqWenn die gebündelte Chart-Version oder der Provenance-Zustand einer Resource fraglich ist, wird dies zur Auditierbarkeit im Status offengelegt — siehe Provenance & Lebenszyklus.