Generic Operator
Un moteur d'opérateur Kubernetes générique, piloté par templates Jinja2 — avec Secure Namespace Operator comme implémentation de référence.
Le problème
Construire un opérateur Kubernetes pour du provisioning à la demande — namespaces, quotas, isolation réseau, ingress, egress — demande une base solide (boucle de réconciliation, rendu de templates, suivi de révisions, RBAC) avant même d'écrire la première ligne de logique métier.
Code dupliqué à chaque nouveau besoin
La boucle kopf, le rendu de templates, l'application générique de ressources et le suivi de révisions se réécrivent identiques d'un opérateur à l'autre.
Webhooks fragiles
Un webhook mutant/validant maison implique certificats TLS, cert-manager, disponibilité réseau vers l'API server — de la charge opérationnelle pour une logique souvent simple.
Distribution artisanale
Sans registre OCI natif, publier et versionner un chart Helm pour une équipe plateforme reste manuel et peu reproductible.
Public visé : équipes plateforme / SRE qui opèrent du multi-tenant Kubernetes et doivent exposer du self-service namespace de façon sécurisée.
Un moteur générique, piloté par templates
templates/core/ ne connaît le nom d'aucun CRD, d'aucun champ de spec, d'aucune
ressource Kubernetes précise. Il ne fait que suivre ce pipeline, pour n'importe quel CRD que
vous lui désignez :
Vous définissez un CRD
values.yaml::crd déclare group / version / kind / plural. Le schéma OpenAPI du CRD fournit les valeurs par défaut de chaque champ.
L'opérateur observe ce CRD
Les handlers kopf s'enregistrent sur (CRD_GROUP, CRD_VERSION, CRD_PLURAL) lus depuis l'environnement — jamais un group/kind écrit en dur.
Il charge la liste des templates à traiter
Un ConfigMap dédié énumère, dans l'ordre, les templates à rendre — format configmap/clé, réparti sur plusieurs ConfigMaps thématiques.
Chaque template est rendu en Jinja2
Avec les valeurs du spec de votre instance de CRD — délimiteurs personnalisés pour ne pas entrer en collision avec le rendu Helm du chart lui-même.
Les ressources résultantes sont appliquées
Génériquement, via le client Kubernetes dynamique — n'importe quel apiVersion/kind présent dans le YAML rendu, sans modèle Python figé.
La révision est tracée
Chaque changement de spec incrémente une annotation de révision et journalise un diff dans une ConfigMap d'historique.
La définition du CRD pilote tout
Group, version, kind, plural — un seul endroit à changer pour brancher le moteur sur un autre CRD, sans toucher au code Python.
crd:
group: my-thing.example.com
version: v1
kind: MyThing
plural: mythings
Template-centric : le Python n'est qu'un orchestrateur
Toute la logique métier vit dans les templates Jinja2, pas dans le code. Un changement de comportement passe le plus souvent par l'édition d'un template, jamais par une modification du moteur.
[% if spec.ingress.enabled %]
_action: apply
[% else %]
_action: delete
[% endif %]
Une liste explicite de templates à traiter
L'ordre d'exécution est déclaratif — le Namespace avant le NetworkPolicy, par exemple — et chaque entrée pointe vers un ConfigMap et une clé précis.
templates:
- templates-core/namespace.yaml
- templates-core/resource-quota.yaml
- templates-network/network-policy.yaml
Contrôleurs : le même moteur, à l'échelle d'une instance
L'opérateur surveille le CRD dans son ensemble — toutes les instances, cluster-wide. Un contrôleur applique exactement le même moteur générique — rendu Jinja2, application des ressources — mais dédié à une seule instance de ce CRD, surveillée en continu par son propre processus. Ce que le contrôleur surveille précisément en plus de cette instance (une VIP, un Service, autre chose) est un choix de l'implémentation, pas une limite du mécanisme : lui aussi est piloté entièrement par templates.
templates/core/CODE/
├── 3_operator.yml # boucle principale
└── 2_VIP-controller.yml # contrôleur dédié,
# même pipeline render/apply
Secure Namespace Operator
Une implémentation complète du moteur ci-dessus, livrée avec le projet — la preuve que le concept fonctionne, et un point de départ concret à copier pour la vôtre.
Ce que ça fait
Isolation réseau Cilium
NetworkPolicies générées automatiquement, avec règles d'accès externe configurables (CIDR, FQDN, services, namespaces).
Quotas de ressources
Compute, stockage, nombre d'objets Kubernetes — bornés par namespace provisionné.
Ingress multi-contrôleur
NGINX, HAProxy ou Traefik au choix, un contrôleur dédié par namespace.
Egress VIP Gateway
Placement automatique de VIP avec annonce L2 et politiques Cilium — porté par un contrôleur dédié, spawné par l'opérateur, une instance par namespace.
Comment c'est construit
Rien de tout ça n'est dans le moteur. secure-namespace est un dossier purement déclaratif branché sur templates/core/ :
templates/implementations/secure-namespace/
├── CRD/0_CRD.yml # le CRD SecureNamespace
├── RBAC/ # permissions pour les ressources gérées
├── KYVERNO_rules/ # ClusterPolicy : auto-naming + validation
│ # (remplace un ancien webhook mutant/validant)
└── TEMPLATES/ # templates Jinja2 (namespace, quotas, network,
# ingress, RBAC, + CONTROLER/TEMPLATES pour
# le contrôleur VIP)
Le code Python du contrôleur VIP appelé par ces templates vit dans le moteur (core/CODE/2_VIP-controller.yml), pas ici — voir « Contrôleurs : le même moteur, à l'échelle d'une instance » ci-dessus.
Installation
Depuis ghcr.io (recommandé)
helm install secure-namespace-operator \
oci://ghcr.io/ccoupel/charts/secure-namespace-operator \
--version 0.0.2 \
--namespace namespace-operator \
--create-namespace \
-f values.yaml
Depuis les sources
git clone https://github.com/CCoupel/Generic-Operator.git
cd Generic-Operator
helm install secure-namespace-operator ./CHARTS \
--namespace namespace-operator \
--create-namespace \
-f CHARTS/values.yaml
Prérequis, désinstallation et référence complète des champs du CRD : CHARTS/README.md · construire votre propre implémentation à partir du moteur : HOWTO-NEW-IMPLEMENTATION.md
Roadmap
Livré ✓
- v0.0.2 — Contrôleur VIP unifié dans le moteur générique, CI GitHub Actions, publication ghcr.io vérifiée de bout en bout
- v0.0.1 — Première publication : moteur générique + implémentation de référence secure-namespace
À venir
Pas de roadmap formelle publiée pour le moment — suivez les issues GitHub.
Historique complet : CHANGELOG.md