Skip to content

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 ​

bash
# 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 -f

Jede Resource legt eine Ready-Bedingung plus phasenbezogene Bedingungen offen (SecretsReady, OperatorsReady, DatastoreReady, WorkloadReady, …), jeweils mit einem reason und einer message.

Bedingungen lesen ​

Condition reasonWas es bedeutetWas zu tun ist
SecretsNotReadyDas referenzierte SecretsManagement ist nicht readyPrüfen Sie die SecretsManagement-Resource und ihr ESO-/Sealed-Secrets-Backend
WaitingForCRDEstablishedDie CRDs eines Capability-Operators sind noch nicht EstablishedNormal während der Installation; prüfen Sie die Pods des Operators, falls es andauert
DependencyNotReadyEin referenzierter Datenspeicher / ein Gateway / ein Langfuse ist nicht readyInspizieren Sie die referenzierte Resource
AutoWiringUnlicensedEine Referenz benötigt Auto-Wiring, das nicht lizenziert istGeben Sie die in der Meldung benannten manuellen Felder an oder spielen Sie eine Lizenz ein
LicenseLimitExceededSie haben ein lizenziertes Instanzlimit überschrittenReduzieren Sie Instanzen oder erhöhen Sie die limits in der Lizenz
BackendNotImplementedEin nur gerüstetes Backend (zalando / cockroachdb) wurde ausgewähltVerwenden Sie cnpg oder adopt / external
InfrastructureBlockedEin verwalteter Datastore-Pod kann aus einem Cluster-Infrastrukturgrund nicht starten, den der Operator durch Warten nicht beheben kannLesen 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.

bash
# Inspect a capability operator directly.
kubectl -n cnpg-system get pods
kubectl -n cert-manager get pods,events --sort-by=.lastTimestamp

Hä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, bleibt Pending, 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 Sie resources.requests / instances des 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:

bash
# 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:

bash
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:

  1. Der IdP weist die Weiterleitung ab (AADSTS900971: No reply address provided oder eine Redirect-Abweichung). LibreChat bildet seinen Callback aus DOMAIN_SERVER, das der Operator aus dem ChatUI-Host ableitet. Setzen Sie hostund ingress.tls: true an der ChatUI (bzw. am chatUI des Stacks), damit DOMAIN_SERVER zu https://<host> wird, und registrieren Sie https://<host>/oauth/openid/callback als Web-Redirect-URI im IdP.

  2. Die Edge gibt vor der App ihren eigenen 403 zurück (z. B. eine Microsoft-Azure-Application-Gateway/v2-Seite). Eine WAF blockiert den OIDC-Callback: Die base64url-Parameter code/state/id_token lö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.

  3. Die App zeigt „Authentication failed“ mit Unable to verify authorization request state in den LibreChat-Logs. Durch die TLS-Terminierung sieht die App reines HTTP, sodass ein Secure-Session-Cookie verworfen und der OAuth-state verloren geht. Der Operator setzt automatisch SESSION_COOKIE_SECURE=false, sobald spec.sso aktiviert 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 ​

bash
# 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}' | jq

Wenn die gebündelte Chart-Version oder der Provenance-Zustand einer Resource fraglich ist, wird dies zur Auditierbarkeit im Status offengelegt — siehe Provenance & Lebenszyklus.

Open Core unter AGPL-3.0. Enterprise-Komponenten sind proprietär und lizenzgebunden.