Couches pluggables (pattern Lego)¶
AKKO est une plateforme de contrats par couche, pas un stack d'outils précis. Chaque couche que le reste de la plateforme consomme via une ressource Kubernetes canonique (Secret, ConfigMap, Service) est pluggable : AKKO livre une implémentation par défaut, et l'opérateur peut la remplacer par l'infrastructure existante du client avec un seul flip Helm — jamais une migration de plusieurs semaines.
Cette page explique le pattern, liste les couches pluggables livrées aujourd'hui, et montre comment basculer une couche en mode BYOS (Bring Your Own Storage / Identity / Observability).
Engine slot par couche (vue d'ensemble)¶
AKKO déclare un engine slot par couche fonctionnelle dans
global.layers (voir helm/akko/values.yaml). Le nom de l'engine est
de la donnée, pas du code : changer l'engine d'une couche est une
modification de valeurs avec une fenêtre de dépréciation, pas une
cascade de renames de chart. Référence : ADR-061 — Engine-slot Helm
pattern.
| Couche (capacité) | Clé Helm | Engine par défaut |
|---|---|---|
| Storage | global.layers.storage.engine |
SeaweedFS |
| Catalog | global.layers.catalog.engine |
Polaris |
| Compute | global.layers.compute.engine |
Spark |
| Query | global.layers.query.engine |
Trino |
| Orchestration | global.layers.orchestration.engine |
Airflow |
| BI | global.layers.bi.engine |
Superset |
| Lab | global.layers.lab.engine |
JupyterHub |
| Passerelle IA | global.layers.ai_gateway.engine |
LiteLLM |
| Runtime IA | global.layers.ai_runtime.engine |
Ollama |
| RAG | global.layers.rag.engine |
pgvector |
| Vector store | global.layers.vector_store.engine |
Milvus (off par défaut) |
| Identity | global.layers.identity.engine |
Keycloak |
| Annuaire | global.layers.directory.engine |
LLDAP |
| Governance | global.layers.governance.engine |
OPA |
| Observability — métriques | global.layers.observability.metrics.engine |
Prometheus |
| Observability — logs | global.layers.observability.logs.engine |
VictoriaLogs |
| Observability — dashboards | global.layers.observability.dashboards.engine |
Perses |
| Observability — tracing | global.layers.observability.tracing.engine |
Tempo |
La phase 1 (déclarative) a livré ce bloc via ADR-061. La phase 2
(Sprint 80) introduit les deux premiers slots moteurs fonctionnels —
Query et Compute (ADR-064 + ADR-065). Flipper <couche>.engine avec
le flag .enabled correspondant fait basculer le moteur sous-jacent que
les consommateurs routent via le helper akko.engine.<couche>.
La phase 3+ migrera les consommateurs restants des noms de moteur codés en dur vers le helper, puis fusionnera l'interrupteur deux-boutons en un seul. Cibles opportunistes suivantes : Orchestration (Airflow ↔ Dagster), BI (Superset ↔ Metabase ↔ Lightdash), RAG (pgvector ↔ OpenSearch knn), Runtime IA (Ollama ↔ vLLM).
Couche Query — valeurs supportées du slot moteur¶
query.engine |
Service retourné par le helper | Port | Statut |
|---|---|---|---|
trino (défaut) |
<release>-trino |
8080 | livré |
spark-sql |
<release>-akko-spark-connect |
15002 | placeholder (Sprint 81) |
clickhouse |
<release>-akko-clickhouse |
8123 | pas encore livré |
duckdb |
<release>-akko-duckdb |
8080 | pas encore livré |
Référence : ADR-064 — Engine-slot Helm pattern, couche Query.
Helper : akko.engine.query / .port / .endpoint / .enabled dans
helm/akko/templates/_helpers.tpl.
Couche Compute — valeurs supportées du slot moteur¶
compute.engine |
Service retourné par le helper | Port | URI client | Statut |
|---|---|---|---|---|
spark (défaut) |
<release>-spark-master |
7077 | spark://... |
livré |
spark-connect |
<release>-spark-connect |
15002 | sc://... |
livré |
ray |
<release>-akko-ray-head |
10001 | ray://... |
placeholder (Sprint 82) |
flink |
<release>-akko-flink-jobmanager |
6123 | akka.tcp://... |
placeholder (Sprint 82) |
Référence : ADR-065 — Engine-slot Helm pattern, couche Compute.
Helper : akko.engine.compute / .port / .endpoint / .enabled.
Les moteurs inconnus déclenchent un fail immédiat dans le helper
(préférable à un manifest qui pointe sur un Service inexistant). Le
contrat est appliqué par scripts/lint-engine-slot-contracts.sh
(pre-commit + CI) et exercé par
tests/integration/test_helm_template_engine_swap.py (12 tests).
Le principe¶
Pour chaque couche dotée d'un contrat industriel stable (S3, OIDC, Prometheus remote-write, OTLP, OCI…), AKKO :
| Mode | Ce que cela signifie | Quand le choisir |
|---|---|---|
| default | L'implémentation unique qu'AKKO livre et teste. Licence Apache 2.0 / MIT / BSD, footprint demo-friendly. | La plupart des installs. Plus rapide à démontrer, plus simple à valider. |
| external (BYOS) | Aucun pod de la couche n'est instancié. AKKO consomme l'endpoint que l'opérateur câble via le Secret canonique. | Le client a déjà AWS S3 / Datadog / Grafana / Auth0 — on garde son infrastructure existante, AKKO se contente de lui parler. |
AKKO ne livre pas plusieurs implémentations parallèles du même
contrat. Il n'y a pas de « second sub-chart packagé pour Ceph » ou
« second sub-chart packagé pour Loki » — ils arrivent à AKKO via le
slot external pointant sur l'endpoint du client, et AKKO ne prétend
jamais les maintenir.
Couches pluggables livrées aujourd'hui¶
| Couche | Contrat | Default packagé | Licence | Foundation | Cibles BYOS |
|---|---|---|---|---|---|
| Object storage | S3 v4 | SeaweedFS | Apache 2.0 | Single-vendor (actif) | AWS S3 / GCS / Azure Blob / object storage Enterprise / Ceph RGW |
| Agrégation logs | API Loki / OTLP | VictoriaLogs | Apache 2.0 | Single-vendor (actif) | Grafana Cloud Loki / Datadog / Splunk / Elastic / OpenSearch |
| Dashboards | PromQL + JSON dashboards | Perses | Apache 2.0 | CNCF Sandbox | Grafana / Grafana Cloud / Datadog / Dynatrace |
| Log shipper | OTLP / API Loki | Fluent Bit | Apache 2.0 | CNCF Graduated | OTel Collector / Vector / managé par l'opérateur |
Les quatre sont packagés dans deux sub-charts Lego :
akko-storage— expose le contrat S3 via Secretakko-s3+ ConfigMapakko-s3-config.akko-observability— expose les contrats logs + dashboards via Secretsakko-logs,akko-dashboards, ConfigMapsakko-logs-config,akko-dashboards-config.
Tous les autres charts AKKO qui ont besoin de storage ou
d'observability lisent depuis ces ressources canoniques, jamais une
référence hardcodée akko-storage:9000 ou akko-perses.
Comment les consommateurs voient ça¶
Secret/akko-s3 → endpoint, region, bucket, accessKey, secretKey
ConfigMap/akko-s3-config → endpoint, region, bucket, backend (informatif)
Secret/akko-logs → endpoint, token, backend
ConfigMap/akko-logs-config → endpoint, backend, shipper (informatif)
ConfigMap/akko-dashboards-config → url, backend, label
Ces noms sont stables d'une release à l'autre. Polaris, Trino, Spark,
MLflow, akko-rag, Airflow, akko-aden, le nginx du cockpit lisent tous
le même Secret akko-s3. Aucun service n'écrit jamais une référence
hardcodée vers « storage » ou « perses ».
Trois scénarios de swap¶
Scénario A — Install par défaut¶
helm install akko helm/akko/ -n akko --create-namespace \
-f helm/examples/values-dev.yaml \
-f helm/examples/values-netcup.yaml
Vous obtenez SeaweedFS + VictoriaLogs + Perses + Fluent Bit, le tout câblé, le tout fonctionnel, ~100 Mo RAM en plus par rapport au stack legacy object storage/Loki/Grafana.
Scénario B — Bring your own AWS S3 (couche Storage)¶
helm upgrade akko helm/akko/ -n akko \
--set akko-storage.backend=external \
--set akko-storage.external.endpoint=https://s3.eu-west-3.amazonaws.com \
--set akko-storage.external.region=eu-west-3 \
--set akko-storage.external.bucket=acme-prod-akko \
--set akko-storage.external.accessKey=$AKKO_AWS_KEY \
--set akko-storage.external.secretKey=$AKKO_AWS_SECRET
AKKO arrête de déployer les pods SeaweedFS. Polaris/Trino/Spark/MLflow écrivent maintenant leurs fichiers Iceberg, artefacts MLflow et données de démo directement dans votre bucket AWS. Aucun script de migration de données — on pointe juste l'endpoint vers le S3 que vous utilisez déjà.
Le même pattern fonctionne pour GCS (https://storage.googleapis.com),
Azure Blob (façade S3), object storage Enterprise, Ceph RGW, ou tout autre
endpoint S3 v4.
Scénario C — Bring your own Grafana (couche Dashboards)¶
helm upgrade akko helm/akko/ -n akko \
--set akko-observability.dashboards.backend=external \
--set akko-observability.dashboards.external.url=https://grafana.acme.internal \
--set akko-observability.dashboards.external.label="Grafana Acme"
AKKO arrête de déployer Perses. La page Dashboards du cockpit devient
une carte deep-link vers votre Grafana (pas d'iframe — la CSP ferait
de la résistance). AKKO livre des définitions JSON de dashboards que
vous pouvez importer dans votre Grafana existant via
helm/akko/charts/akko-observability/dashboards/.
Scénario D — Expédier les logs vers Datadog (couche Logs)¶
helm upgrade akko helm/akko/ -n akko \
--set akko-observability.logs.backend=external \
--set akko-observability.logs.external.endpoint=https://http-intake.logs.datadoghq.eu/v1/input \
--set akko-observability.logs.external.token=$DD_API_KEY
VictoriaLogs disparaît. Le DaemonSet Fluent Bit reste — il expédie maintenant vers Datadog. La page Logs du cockpit tente le même chemin de requête (VictoriaLogs est compatible API Loki et Datadog Logs Search l'est aussi), avec un fallback gracieux si une feature de syntaxe n'est pas supportée.
Vous pouvez mixer librement : garder SeaweedFS pour le storage mais expédier les logs à Datadog. Garder VictoriaLogs pour les logs mais utiliser votre propre Grafana pour les dashboards. Chaque slot est indépendant.
Pourquoi pas livrer Ceph / Grafana / Loki en options packagées ?¶
Parce que ce serait deux stacks à maintenir au lieu d'un. Le coût de « AKKO supporte Ceph nativement » c'est :
- un second sub-chart avec ses propres values, templates, NetworkPolicies
- une seconde matrice de tests à garder verte
- un second chemin de migration à chaque bump du chart upstream
- une seconde page de doc à garder en sync avec le code
- deux fois plus de surface de bugs dans les release notes AKKO.
Le coût de « AKKO supporte votre Ceph existant via external », c'est :
- vous écrivez
external.endpoint=https://votre-ceph-rgw.acme.internal - AKKO lui parle comme il parle à AWS S3.
Le pattern Lego, c'est la seconde réponse appliquée uniformément. AKKO mise sur un default par couche, le valide en profondeur, et laisse la couche de modularité porter le polymorphisme pour le reste.
Et après¶
Le même pattern est en cours d'application à d'autres contrats pluggables :
| Couche | Statut | Default | BYOS |
|---|---|---|---|
| Identity / SSO | Sprint 44 | Keycloak | Auth0 / Okta / Entra ID / AWS Cognito |
| Annuaire | Sprint 45 | LLDAP | Active Directory existant / OpenLDAP |
| Container registry | Déjà livré | Harbor | ECR / GAR / ACR / Quay |
| CI/CD | Sprint 46 | Woodpecker | GitHub Actions / GitLab CI |
| Passerelle LLM | Sprint 47 | LiteLLM | Bedrock / Vertex AI / Azure OpenAI |
| Catalog | Sprint 48 | OpenMetadata | DataHub / Apache Atlas |
Voir feedback_akko_layers_not_tools.md dans la mémoire de l'agent
pour la règle durable, et project_storage_replacement.md /
project_observability_replacement.md pour les décisions storage et
observability respectivement.