Provenance et cycle de vie
L'opérateur suit une règle déterminante :
Ne jamais réinstaller ce que l'utilisateur a installé. Ne jamais désinstaller ce que nous ne possédons pas.
Cette page explique comment cette règle s'applique aux installations des opérateurs de capacité et aux instances de datastore, et comment fonctionne le nettoyage lors de la suppression et de la migration.
Deux niveaux de Provenance
1. Provenance d'installation d'opérateur
Lorsqu'une ressource a besoin d'un opérateur de capacité (par exemple un PostgresCluster managed a besoin de CloudNativePG), l'installeur partagé de l'opérateur détecte l'état actuel avant toute action :
- Existe-t-il une release Helm portant le nom attendu dans le namespace attendu ?
- Avec le label de propriété
app.kubernetes.io/managed-by=navique-ai-core-operatoret l'annotationcore.navique.com/provenance=owned→ Owned (possédée). - Sans ces labels → Adopted (vous ou un autre outil l'avez installée).
- Avec le label de propriété
- Pas de release à nous, mais les CRDs de l'opérateur existent et son contrôleur s'exécute quelque part dans le cluster → Adopted.
- Rien de présent → Absent.
Le contrôleur est identifié par son identité — ses labels bien connus, à défaut le dépôt de son image de conteneur — et non par « est-ce que quelque chose tourne dans le namespace que nous aurions utilisé ». Deux conséquences à connaître :
- Un opérateur que vous avez installé dans un autre namespace (CNPG dans
postgres-operatorplutôt quecnpg-system), ou via OLM / des manifestes bruts / un autre nom de release, est adopté et non dupliqué. Ces opérateurs possèdent des CRDs à portée cluster : un second contrôleur entrerait en conflit avec le premier sur les mêmes ressources. - Une charge de travail sans rapport qui partage simplement le namespace attendu n'est pas confondue avec l'opérateur : celui-ci est donc bien installé.
Les CRDs seuls ne suffisent jamais : des CRDs orphelines laissées par une désinstallation précédente comptent comme Absent et sont réinstallées.
L'action découle de l'état :
| État | Action |
|---|---|
| Absent | Installer notre release standalone, estampillée du label/de l'annotation de propriété |
| Adopted | Enregistrer l'adoption ; coexister ; ne jamais gérer son cycle de vie |
| Owned | Déjà la nôtre ; éventuellement mettre à niveau vers la version épinglée |
Parce que la détection s'exécute avant toute installation, l'opérateur ne se heurte jamais au conflit Helm « CRD already owned by another release ».
2. Provenance d'instance de datastore
Le même principe un niveau plus bas, via le champ mode des ressources datastore :
| Mode | Propriété |
|---|---|
managed | L'opérateur crée, possède et collecte par le ramasse-miettes le CR datastore |
adopt | Référence un datastore créé par l'utilisateur ; jamais supprimé ni reconfiguré |
external | Un datastore hébergé par l'utilisateur ; seul un secret de connexion est câblé |
Installations paresseuses à comptage de références
Les opérateurs de capacité sont installés paresseusement — un chart n'est installé que lorsqu'une ressource sélectionne effectivement son mode managed. Si chaque datastore est en external ou adopt, cet opérateur n'est jamais installé.
Les installations sont à comptage de références (ref-counted). L'opérateur préfère recalculer le comptage de références plutôt que de le persister : à chaque réconciliation, il liste les ressources pertinentes et calcule lesquelles ont encore besoin d'une dépendance donnée (tout Gateway ⇒ litellm-operator ; tout PostgresCluster managed ⇒ cloudnative-pg ; …). Cela survit aux redémarrages de l'opérateur sans comptabilité externe.
Nettoyage à la suppression
Chaque ressource possède un finalizer. À la suppression, le contrôleur :
- Supprime les CRs amont émis, ou désinstalle la release Helm du workload (pour
ChatUI/MeilisearchInstance). - Pour chaque opérateur de capacité requis par la ressource, décrémente le comptage de références et — uniquement si le compte atteint zéro et que la release est Owned — le désinstalle. Les releases Adopted et external ne sont jamais touchées.
- Pour les datastores managed, supprime le CR datastore créé par l'opérateur (pas les datastores adoptés).
- Retire le 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
}Nettoyage à la migration
Lorsque le mode, le type ou les références d'une ressource changent, l'opérateur diffère l'ancien et le nouveau status et ne supprime que les ressources désormais orphelines possédées par l'opérateur. Par exemple, faire passer un PostgresCluster de managed à external supprime le Cluster CNPG que l'opérateur avait créé, puis libère cloudnative-pg s'il ne reste aucun autre consommateur. Les ressources Adopted et external ne sont jamais supprimées.
Disponibilité de l'installation — plus que des CRDs
« Ready » pour un opérateur de capacité signifie que ses CRDs sont Established ET que tous les Deployments/StatefulSets du chart sont réellement Ready — pas seulement que les CRDs existent. Un opérateur dont le pod est bloqué sur un certificat de webhook manquant a des CRDs établis mais ne peut pas fonctionner ; l'opérateur attend donc une disponibilité réelle.
Certains charts ont des prérequis. Par exemple, le certificat de webhook de l'opérateur ClickHouse est émis par cert-manager, donc cert-manager est amené à pleine disponibilité en premier. L'opérateur traite cert-manager comme un prérequis universel et garde les webhooks et l'élection de leader activés (fidèle à la production) plutôt que de les désactiver.
Auditabilité
Le status de la ressource expose les versions des charts embarqués et l'état de Provenance (owned / adopted) afin que vous puissiez auditer exactement ce que l'opérateur a installé par rapport à ce qu'il a adopté. L'opérateur enregistre aussi des Events pour les adoptions, les passages ignorés sous condition de licence, les refus de plafonds d'instances, les rétrogradations à l'expiration et les actions de ramasse-miettes. Voir Dépannage.