Comment ça fonctionne
L'opérateur est un binaire Go unique exécutant un manager controller-runtime. Il surveille ses ressources personnalisées et fait converger le cluster pour qu'il y corresponde. Cette page explique l'architecture ; Concepts fondamentaux définit le vocabulaire, et les internes des reconcilers couvrent la mécanique du cycle de vie.
Deux couches : opérateurs de capacités et workloads
La plateforme est construite à partir de deux types de choses, et l'opérateur les maintient proprement séparés :
- Les opérateurs de capacités (les « moteurs ») — LiteLLM, Langfuse, External Secrets, Sealed Secrets, CloudNativePG, cert-manager, l'opérateur Redis, l'opérateur ClickHouse et les contrôleurs MongoDB. Ils sont installés en pilotant leurs Helm charts officiels, embarqués dans le binaire, via le Helm v4 Go SDK.
- Les workloads (les « instances ») — la gateway, l'interface, la stack d'observabilité, les datastores et les magasins de secrets effectifs. Ils sont exprimés sous forme de ressources personnalisées en amont que ces opérateurs réconcilient (
LiteLLMInstance, CNPGCluster, ESOExternalSecret, …), ou sous forme de release Helm de workload (LibreChat).
Vos CRD décrivent des workloads ; l'opérateur installe tous les opérateurs de capacités que ces workloads requièrent, puis émet les CR en amont.
La surface de l'API
Tout réside dans le groupe d'API core.navique.com/v1alpha1.
Cluster-scoped
└── License ............ singleton; the signed offline license
Namespaced
├── SecretsManagement .. required; ESO or Sealed Secrets credential backend
├── PostgresCluster .... shared PostgreSQL, multi-database
├── ClickHouseCluster .. ClickHouse
├── RedisInstance ...... Redis
├── MongoCluster ....... shared MongoDB, multi-database
├── MeilisearchInstance Meilisearch search backend
├── Gateway ............ LiteLLM gateway + models / teams / orgs
├── Langfuse ........... Langfuse v3 observability
├── ChatUI ............. LibreChat UI, wired to a Gateway
├── ManagementPlane .... configures the admin console (deployed by default)
├── Stack .............. optional umbrella; a curated, auto-wired bundle (licensed)
└── Organization/Team/User managed identities (licensed)Toutes les ressources de workload et de datastore sont namespacées et multi-instance : de nombreuses Gateway / Observability / ChatUI peuvent coexister, et plusieurs peuvent partager un seul Observability ou un seul PostgresCluster — chaque consommateur obtient sa propre base de données au sein du cluster partagé, possiblement à travers les namespaces.
Modèle d'embarquement — des releases autonomes, pas des subcharts
L'opérateur n'utilise pas les dépendances subchart de Helm. Chaque chart en amont est vendorisé sous forme de .tgz autonome (embarqué via go:embed) et installé comme sa propre release Helm avec un nom fixe et un namespace système fixe. Les opérateurs de capacités sont des singletons cluster-scoped, donc chacun est installé une seule fois et référencé par les workloads dans n'importe quel namespace.
Pourquoi l'autonomie l'emporte sur les subcharts : un opérateur singleton (par ex. CloudNativePG) installé comme subchart à la fois de Gateway et de Observability produirait deux releases se disputant les mêmes CRD, ce que Helm rejette. En tant que releases autonomes, les deux workloads référencent l'installation unique.
Les installations sont paresseuses — un chart n'est installé que lorsqu'une ressource en a réellement besoin. Si tous les datastores sont external ou adopt, seuls les opérateurs dont ces workloads ont véritablement besoin sont installés. Voir Charts embarqués.
Le modèle de réconciliation
Chaque contrôleur modélise son travail sous forme de phases ordonnées persistées dans status.conditions. Une réconciliation progresse aussi loin que la disponibilité le permet, puis re-met en file d'attente :
- Résoudre et verrouiller les dépendances — la
SecretsManagementréférencée est-elle prête ? Les ressources datastore/gateway/langfuse référencées sont-elles prêtes ? - Garantir les opérateurs de capacités — installer (de manière consciente de la Provenance) uniquement les opérateurs dont cette ressource a besoin, puis attendre que leurs CRD soient
Established. - Appliquer les ressources détenues — émettre les CR en amont ou installer/mettre à jour la release Helm de workload. Chaque application est idempotente (create-or-update).
- Sonder la disponibilité — positionner les conditions et re-mettre en file d'attente jusqu'à
Ready.
Deux règles rendent cela robuste :
- Re-mettre en file d'attente, ne pas renvoyer d'erreur, pendant l'attente. « Pas encore prêt » renvoie une re-mise en file d'attente, pas une erreur. Les erreurs sont réservées aux véritables échecs et subissent un backoff exponentiel.
- Tout est idempotent. Chaque application peut être exécutée sans risque à chaque re-mise en file d'attente.
Il n'y a pas de sync waves globales à la mode Argo — les verrous de disponibilité les remplacent. Après avoir installé un chart qui livre des CRD, l'opérateur attend que les CRD soient Established et rafraîchit son REST mapper avant de créer des ressources des nouveaux kinds.
La Provenance, sur deux niveaux
L'opérateur est attentif à ce qu'il détient. Cela se manifeste sur deux niveaux :
- Installation de l'opérateur — il n'installe sa release autonome que si l'opérateur est absent. Si vous l'avez déjà installé, l'opérateur l'adopte (coexiste, ne gère jamais son cycle de vie). Les installations sont ref-comptées à travers les ressources, et l'opérateur ne désinstalle que les releases qu'il détient lorsque plus rien n'en a besoin.
- Instance de datastore — chaque ressource datastore a un
mode:managed(l'opérateur la crée, la détient et la garbage-collecte),adopt(référencer un datastore existant dans le cluster ; ne jamais le supprimer), ouexternal(un datastore hébergé par l'utilisateur ; câbler uniquement un secret de connexion).
Lisez les détails sur la page Provenance et cycle de vie.
Références croisées et câblage automatique
Les ressources se référencent mutuellement par {name, namespace}. Pour chaque référence, le contrôleur :
- Résout et verrouille — re-met en file d'attente jusqu'à ce que la ressource référencée soit prête.
- Câble automatiquement si sous licence — avec la fonctionnalité
auto-wiring, il provisionne et injecte les identifiants afin que vous ne configuriez aucun secret à la main (par ex. en émettant une clé virtuelle LiteLLM pour uneChatUI, ou en câblant le callback Langfuse d'uneGateway). - Retombe sur le mode manuel — sans la fonctionnalité, il utilise les champs explicites que vous fournissez et émet une condition nommant exactement ce qu'il faut renseigner.
Voir Câblage automatique entre composants.
Modèle de processus
- Un binaire unique, manager controller-runtime, leader election activée.
MaxConcurrentReconciles = 1par contrôleur (l'action.Configurationde Helm n'est pas thread-safe).- Surveille tous les namespaces par défaut, restreignable via
--watch-namespaces. - Un ClusterRole étendu — l'opérateur installe des CRD, du RBAC, des webhooks et des workloads à travers les namespaces.
- Livré sous forme d'image plus trois méthodes d'installation : kustomize, un bundle OLM et un Helm chart.
Posture de sécurité
Tous les identifiants fournis par un humain proviennent d'External Secrets (Azure Key Vault via Workload Identity par défaut, mais tout fournisseur ESO est pris en charge) ou de Sealed Secrets — jamais inline dans une CR, une valeur de chart ou un template. Les identifiants générés par l'opérateur (clés virtuelles, clés de callback, mots de passe de datastore) sont stockés comme Secrets détenus en clair avec des owner references pour le garbage collection. Voir Gestion des secrets.