Stack
Ambito: namespaced · Umbrella facoltativo · Soggetto a licenza (funzionalità managed-deployment + un limite stacks)
Stack è una risorsa umbrella facoltativa che crea e possiede un insieme curato di risorse granulari, collega automaticamente i loro riferimenti e aggrega l'avanzamento — un'esperienza di provisioning in un solo passaggio, nello stile dei deployment ARM.
Non sostituisce le risorse per singolo componente. I CRD granulari restano un modo di prima classe per comporre la piattaforma a mano; Stack si limita a porsi al di sopra per i team che vogliono un unico oggetto con cui gestire un intero ambiente.
Quando usarlo
- Usa
Stackquando vuoi eseguire il provisioning e il monitoraggio di un ambiente completo (secret + datastore + gateway + observability + UI) come un'unica unità, lasciando che l'operatore colleghi i riferimenti incrociati e riunisca lo stato in un solo punto. - Usa le risorse granulari quando vuoi un controllo dettagliato, componi a mano risorse distribuite su più namespace, oppure condividi datastore tra più workload gestiti in modo indipendente.
Cosa fa
- Crea e possiede i componenti inclusi (l'operatore imposta gli owner reference, così l'intero insieme viene rimosso dal garbage collector insieme allo
Stack). - Collega automaticamente i riferimenti tra di essi (Gateway→Postgres, Gateway→Observability, ChatUI→Gateway, workload→datastore) — ciò si basa sulla capacità
auto-wiring. - Aggrega l'avanzamento in
status.components[]estatus.endpoints, così un singolokubectl get stackmostra la readiness e gli URL dell'intero ambiente.
Politica di drift
Per impostazione predefinita lo Stack impone continuamente la spec curata ai propri figli: qualsiasi modifica manuale a un CR di componente generato (ad esempio aumentare la dimensione dello storage di un datastore o il numero di repliche di un workload) viene annullata alla riconciliazione successiva. spec.driftPolicy consente di allentare questo comportamento:
driftPolicy | Comportamento |
|---|---|
Enforce (predefinito) | La spec curata viene riaffermata a ogni riconciliazione — le modifiche manuali ai figli vengono annullate (correzione completa del drift). |
Adopt | La spec curata viene applicata alla creazione e ogni volta che cambia la spec dello Stack stesso (un "redeploy" in stile ARM). Tra una modifica dello Stack e l'altra, le modifiche manuali ai singoli componenti vengono preservate. |
Adopt rispecchia il comportamento di un deployment Azure Resource Manager: lo Stack crea e collega le risorse, ma in seguito puoi regolare ciascun componente direttamente. Modificare lo Stack stesso riafferma ogni figlio e sovrascrive il tuo drift, quindi considera una modifica dello Stack come un redeploy.
L'owner reference viene mantenuto con entrambe le politiche, quindi eliminare lo Stack si propaga sempre a (e smantella) ogni componente che ha creato.
apiVersion: core.navique.com/v1alpha1
kind: Stack
metadata:
name: forge
spec:
driftPolicy: Adopt # let users tune individual components after creation
# ...Dimensionamento dei datastore
Ogni datastore gestito sotto spec.datastores accetta una forma abbreviata resources facoltativa che dimensiona CPU e memoria del container sottostante. È supportata per i datastore Postgres, ClickHouse, Redis e MongoDB (solo in modalità managed) e viene riportata nel figlio emesso PostgresCluster / ClickHouseCluster / RedisInstance / MongoCluster come suo managed.resources.
| Campo | Corrisponde a |
|---|---|
cpu | request di CPU |
memory | request di memoria |
memoryLimit | limit di memoria |
La forma abbreviata volutamente non prevede un limit di CPU (i limit di CPU rallentano anziché proteggere). Se ne hai bisogno, usa direttamente il CRD del datastore autonomo, che accetta un managed.resources completo.
apiVersion: core.navique.com/v1alpha1
kind: Stack
metadata:
name: forge
spec:
datastores:
postgres:
storageSize: 20Gi
resources: { cpu: 500m, memory: 1Gi, memoryLimit: 2Gi }
clickhouse:
storageSize: 50Gi
resources: { cpu: 500m, memory: 2Gi, memoryLimit: 3Gi }
redis:
storageSize: 5Gi
resources: { cpu: 100m, memory: 256Mi, memoryLimit: 512Mi }
mongo:
storageSize: 20Gi
resources: { cpu: 250m, memory: 1Gi, memoryLimit: 2Gi }Quando resources è omesso si applicano i valori predefiniti del chart upstream (ClickHouse mantiene il limit di memoria di 3Gi regolato dall'operatore, per evitare OOM sotto il carico di Langfuse).
Scegliere l'implementazione del gateway
spec.gateway.type seleziona il prodotto gateway: litellm (predefinito) oppure waeg (il gateway Wäg, tramite il waeg-operator). Vedi Gateway → Gateway Wäg per le differenze.
Con type: waeg lo Stack:
- richiede
datastores.clickhouse.enablednella modalità di storage predefinitasplit— altrimenti l'admission rifiuta lo Stack, perché è lì che risiedono i dati analitici di Wäg. Impostagateway.waeg.storageMode: singleper mantenerli invece nel Postgres dello Stack, eliminando del tutto il requisito — vedi Storage analitico di Wäg; - collega automaticamente il ClickHouse dello Stack (e Redis, se abilitato) come secondo piano di storage del gateway — solo in modalità
split; - dichiara il database
waegsu quel ClickHouse, affinché il gateway possa avviarsi: Wäg crea solo le proprie tabelle, mai il proprio database (ClickHouseCluster→databases[]); - assegna al database Postgres logico del gateway il nome
waeganzichélitellm, così le due implementazioni non condividono mai uno schema; - non collega alcun riferimento a Langfuse — Wäg non può esportare le trace in modo dichiarativo, quindi lo Stack non ne collega uno solo per vederlo rifiutato dal Gateway.
spec.gateway.waeg inoltra le opzioni specifiche di Wäg: topology, jobWorkers, worker, storageMode, openfga, autoscaling, bootstrapAdmin, dataEncryptionKeySecretRef, modelAccess, scim e jwt. La licenza Enterprise viene dichiarata una sola volta, in spec.gateway.licenseSecretRef, e l'organization del gateway in spec.gateway.organization — necessaria a un gateway type: waeg prima che una ChatUI possa collegarvisi.
spec:
datastores:
clickhouse: { enabled: true, backup: { enabled: true, provider: s3, s3: { destinationPath: s3://b } } }
redis: { enabled: true }
gateway:
enabled: true
type: waeg
licenseSecretRef: { name: waeg-enterprise-license, key: license }
waeg:
topology: Split
worker: { enabled: true, replicas: 2 }
scim:
enabled: true
tokenSecretRef: { name: waeg-scim-token, key: scim-token }
defaultRole: viewer
jwt:
appClaim: azp
requireRegisteredApplication: trueI campi seguenti specifici di LiteLLM (rolePermissions, healthCheck, storePromptsInLogs, guardrails, i limiti per modello — e la parte di jwtAuth relativa alle mappature dei claim) vengono segnalati nella condizione FeaturesSupported del Gateway figlio quando type: waeg — non vengono mai scartati silenziosamente.
Storage analitico di Wäg
spec.gateway.waeg.storageMode seleziona dove risiedono i dati analitici del gateway (log delle richieste, utilizzo, spesa). È il passthrough a livello di Stack di Gateway.spec.waeg.storageMode.
| Modalità | Dati analitici in | datastores.clickhouse.enabled |
|---|---|---|
split (predefinito) | il ClickHouse dello Stack | obbligatorio |
single | il Postgres dello Stack | non necessario — non viene effettuato il provisioning di alcun ClickHouse |
Il valore predefinito di Wäg upstream è single, ed è il punto di partenza consigliato; questo operatore mantiene split come predefinito per continuità e perché regge i volumi elevati. Con single lo Stack non effettua il provisioning di alcun ClickHouse e la regola di admission che ne richiedeva uno non si applica più. Lasciare il valore predefinito senza un ClickHouse viene rifiutato con:
gateway.type=waeg with the default storageMode 'split' requires
datastores.clickhouse.enabled; set gateway.waeg.storageMode: single to keep
analytics in Postgres insteadCambiare modalità non migra lo storico analitico
I due piani sono store separati. Cambiare storageMode su uno Stack in esecuzione fa puntare il gateway all'altro; i dati analitici già raccolti restano dove erano, e né l'operatore né Wäg li copiano.
apiVersion: core.navique.com/v1alpha1
kind: Stack
metadata:
name: forge
namespace: forge
spec:
datastores:
postgres:
enabled: true
storageSize: 20Gi
backup: { enabled: true, provider: s3, s3: { destinationPath: s3://forge-pg } }
redis: { enabled: true }
# no clickhouse block at all — storageMode: single needs none
gateway:
enabled: true
type: waeg
organization: { name: forge }
waeg:
storageMode: singleNella modalità predefinita split lo Stack dichiara inoltre il database waeg sul proprio ClickHouse gestito, perché Wäg crea solo le proprie tabelle e mai il proprio database — vedi ClickHouseCluster → databases[].
Organization del gateway
spec.gateway.organization crea l'organization di primo livello del gateway — l'oggetto a cui fanno capo budget e limiti di frequenza. Viene passata direttamente al campo spec.organization del Gateway figlio.
| Campo | Descrizione |
|---|---|
name (obbligatorio) | Il nome dell'organization |
maxBudget | Tetto di spesa per l'organization |
budgetDuration | Periodo dopo il quale il tetto si azzera (ad es. 30d). Solo LiteLLM — le policy di budget di Wäg non hanno un campo per il periodo |
rpmLimit | Limite di richieste al minuto |
tpmLimit | Limite di token al minuto |
Su un gateway type: litellm un'organization resta facoltativa — team, chiavi e modelli funzionano tutti anche senza.
Un gateway Wäg ne richiede una prima che una ChatUI possa collegarsi
Con type: waeg questo campo è obbligatorio per collegare automaticamente una ChatUI. Wäg non ha virtual key autonome: una chiave appartiene a un'applicazione, e le applicazioni hanno radice nell'organization — quindi senza organization non c'è nulla sotto cui generare la credenziale della ChatUI. Prima che esistesse questo campo, uno Stack con gateway.type: waeg e chatUI.enabled: true lasciava la ChatUI bloccata su
Gateway "…" is type=waeg and has no spec.organization: a Wäg virtual key belongs
to an application, and applications are org-rootedsenza nulla di impostabile da uno Stack per soddisfarla — il Gateway granulare aveva spec.organization, lo Stack non prevedeva alcun passthrough. Impostalo qui e la ChatUI viene registrata come WaegApplication sotto quella organization, con il suo WaegVirtualKey generato di conseguenza.
L'organization è anche ciò a cui si agganciano i grant di spec.gateway.waeg.modelAccess: l'ACL dei modelli è dichiarata rispetto ad essa, quindi senza organization i grant vengono ignorati.
spec:
datastores:
clickhouse: { enabled: true, backup: { enabled: true, provider: s3, s3: { destinationPath: s3://forge-ch } } }
redis: { enabled: true }
gateway:
enabled: true
type: waeg
licenseSecretRef: { name: waeg-enterprise-license, key: license }
organization:
name: navique-ag
maxBudget: 2000
rpmLimit: 1000
tpmLimit: 500000
waeg:
modelAccess: # org-rooted: needs the organization above
openByDefault: false
fallbackMode: deny
grants:
- models: [premium, economy]
chatUI:
enabled: true # auto-wired as an application under navique-agVedi La ChatUI si connette come applicazione per gli oggetti emessi dall'operatore, e Cosa non viene applicato per i campi dell'organization che Wäg non può rispettare.
Licenza Enterprise del gateway
spec.gateway.licenseSecretRef fornisce la licenza Enterprise del gateway stesso, passata all'instance.licenseSecretRef del Gateway. Per type: litellm è la chiave LiteLLM Enterprise; per type: waeg è la licenza Wäg Enterprise, ed è ciò che distingue un gateway Enterprise funzionante da uno che risponde 402 license_required.
Ogni modulo Wäg Enterprise dipende da essa — SSO, SCIM, audit, CMEK, FIPS e branding della console — e l'applicazione è incondizionata, quindi senza questo campo un gateway Wäg gestito da uno Stack non ha alcuna funzionalità Enterprise raggiungibile.
spec:
gateway:
type: waeg
licenseSecretRef: { name: waeg-enterprise-license, key: license }La chiave del Secret è per impostazione predefinita license. Lascia che il backend SecretsManagement dello Stack materializzi il Secret invece di crearlo a mano.
Il branding segue la licenza
Una volta che un gateway Wäg dispone di licenza, l'operatore applica automaticamente alla sua console il theme pack Navique integrato (una ConfigMap <gateway>-branding di sua proprietà). Lo Stack non prevede un campo di opt-out — per impostare un pack tuo, o per mantenere l'aspetto di Wäg, usa il Gateway granulare con waeg.brandingConfigMapRef / waeg.defaultBranding: false.
Dimensionamento del gateway
spec.gateway.resources dimensiona il container del proxy LiteLLM. A differenza della forma abbreviata dei datastore, è un ResourceRequirements Kubernetes completo (quindi puoi impostare un limit di CPU), passato direttamente all'instance.resources del Gateway emesso → allo spec.resources del LiteLLMInstance. Omettilo per lasciare il valore predefinito del litellm-operator.
spec:
gateway:
resources:
requests: { cpu: "500m", memory: 512Mi }
limits: { cpu: "2", memory: 2Gi }Fissare la build del proxy del gateway
spec.gateway.image fissa l'immagine del proxy LiteLLM, passata all'instance.image del Gateway emesso → allo spec.image del LiteLLMInstance.
spec:
gateway:
image:
repository: ghcr.io/berriai/litellm
tag: v1.94.0-dev.2Lascialo non impostato, a meno che tu non stia qualificando una build specifica. Senza un valore fissato il litellm-operator applica il proprio tag predefinito — quello convalidato con il suo entrypoint di migrazione del database — quindi un tag arbitrario può compromettere la migrazione e lasciare il gateway fuori servizio.
Non provare invece a modificare a mano il Gateway figlio: con la politica di drift predefinita Enforce lo Stack riapplica i propri figli a ogni riconciliazione e la tua modifica viene annullata in pochi secondi. Dichiara qui il valore fissato.
Autenticazione JWT e RBAC del gateway
spec.gateway.jwtAuth e spec.gateway.rolePermissions abilitano l'autenticazione API basata su JWT e l'accesso ai modelli per ruolo sul Gateway dello Stack — passati direttamente a instance.jwtAuth / instance.rolePermissions del Gateway. Vedi Autenticazione API tramite JWT e RBAC per i campi. Richiede una licenza LiteLLM Enterprise.
spec:
gateway:
jwtAuth:
enabled: true
userRolesJWTField: roles
userAllowedRoles: ["basic_user"]
enforceRBAC: true
rolePermissions:
internal_user: { models: ["anthropic-claude"] }Branding della console Wäg
spec.gateway.waeg.brandingConfigMapRef e defaultBranding vengono inoltrati al branding della console del Gateway: il tema Navique per impostazione predefinita, un tuo theme pack con la funzionalità soggetta a licenza custom-branding, oppure l'aspetto di Wäg con defaultBranding: false.
Su un gateway Wäg
spec.gateway.jwtAuth attiva l'autenticazione JWT anche per type: waeg — enabled, publicKeyURL (→ jwksUrl di Wäg), issuer, audience e userIDJWTField (→ subjectClaim) si applicano tutti. Le opzioni specifiche di Wäg si trovano in spec.gateway.waeg.jwt, mentre spec.gateway.rolePermissions e le mappature dei claim (userRolesJWTField, userRoleJWTField, userAllowedRoles, enforceRBAC, userIDUpsert, teamIDsJWTField, adminJWTScope) vengono invece segnalati come non supportati: Wäg autorizza tramite OpenFGA e le applicazioni registrate. Vedi Autenticazione JWT del data plane.
spec:
gateway:
type: waeg
licenseSecretRef: { name: waeg-enterprise-license, key: license }
jwtAuth:
enabled: true
publicKeyURL: https://login.microsoftonline.com/<tenant>/discovery/v2.0/keys
issuer: https://login.microsoftonline.com/<tenant>/v2.0
audience: <client-id>
userIDJWTField: sub
waeg:
jwt:
appClaim: azp
requireRegisteredApplication: trueGli interruttori di hardening possono impedire l'avvio del gateway
waeg.jwt.allowMasterKey: false o allowVirtualKeys: false richiedono jwtAuth.enabled: true, un publicKeyURL, un'audience e insecureSkipVerify: false — altrimenti Wäg si rifiuta di avviarsi. allowVirtualKeys: false blocca inoltre ogni chiave di applicazione, inclusa quella della ChatUI dello Stack.
Provisioning SCIM di Wäg
spec.gateway.waeg.scim attiva gli endpoint SCIM v2 di Wäg sul gateway dello Stack, così il tuo IdP crea e disattiva direttamente gli utenti della console. È indipendente dall'SSO — funziona anche senza alcun login interattivo collegato — e richiede spec.gateway.licenseSecretRef.
spec:
gateway:
type: waeg
licenseSecretRef: { name: waeg-enterprise-license, key: license }
waeg:
scim:
enabled: true # default
tokenSecretRef: { name: waeg-scim-token, key: scim-token } # required
defaultRole: viewer
orgSource: waeg
roleMap: { "AI Platform Admins": admin }Il bearer token viene proiettato sui pod del gateway come WAEG_EE_SCIM_TOKEN, quindi ruotare il Secret è l'intera procedura di rotazione. Gli endpoint si trovano sotto /waeg/admin/v1/ee/scim/v2. Vedi Provisioning SCIM per tutti i campi.
Datastore della ChatUI: MongoDB e Meilisearch
MongoDB (lo store delle conversazioni) e Meilisearch (la ricerca) supportano la ChatUI e si configurano sotto datastores.mongo / datastores.meilisearch — con lo stesso selettore mode: managed | external degli altri datastore. Il loro provisioning avviene solo quando la ChatUI è abilitata, e per impostazione predefinita sono managed.
managed(predefinito): lo Stack effettua il provisioning di unMongoCluster/MeilisearchInstance, ne è proprietario e vi collega la ChatUI. Dimensionali constorageSize(Meilisearch supporta anchestorageClass/resources).external: non viene creato alcun CR di datastore; la ChatUI viene collegata a un'istanza gestita dall'utente. Mongo richiedeconnectionSecretRef(chiave del SecretMONGO_URI, sovrascrivibile con.key). Meilisearch richiedehostpiù unconnectionSecretRefche contenga la master key (chiave del SecretMEILI_MASTER_KEY).
spec:
datastores:
mongo:
mode: managed
storageSize: 10Gi
meilisearch:
mode: external
host: https://search.example.com
connectionSecretRef: { name: meili-master-key } # key MEILI_MASTER_KEYServer MCP (ricerca web e strumenti)
chatUI.mcp collega server MCPServer alla UI LibreChat dello Stack. Due modalità, combinabili:
catalog— server inclusi di cui lo Stack effettua il provisioning e che possiede come figliMCPServer(uno per chiave), collegandoli alla ChatUI. Prima voce:websearch(ricerca web enterprise). Richiede la licenzabundled-mcp-catalog; una voce senza licenza èRefusede viene saltata (la UI si avvia comunque).refs— collega CRMCPServerpreesistenti creati da te (da catalogo o esterni — ad es. un server MCP self-hosted nel cluster), in qualsiasi namespace. Lo Stack vi fa riferimento senza possederne il ciclo di vita.
spec:
chatUI:
enabled: true
mcp:
catalog: [ websearch ] # Stack creates + wires the MCPServer
refs:
- { name: my-internal-mcp } # an MCPServer you manageFare riferimento a un qualsiasi server MCP abilita automaticamente l'endpoint Agents di LibreChat. I figli MCPServer dello Stack compaiono nel suo albero di avanzamento e vengono smantellati insieme allo Stack. Vedi MCPServer per la definizione del server e la allowlist SSRF automatica.
Guardrail (percorso dei dati)
gateway.guardrails collega guardrail del percorso dei dati Guardrail al Gateway dello Stack. Due modalità, combinabili:
catalog— motori inclusi di cui lo Stack effettua il provisioning e che possiede come figliGuardrail(uno per chiave), collegandoli al Gateway. Prima voce:pseudonymizer(pseudonimizzazione dei dati personali). Richiede la licenzaguardrail(Enterprise); una voce senza licenza èRefusede viene saltata (il Gateway si avvia comunque, senza protezione).refs— collega CRGuardrailpreesistenti creati da te (da catalogo o guardrail HTTP esterno), in qualsiasi namespace. Lo Stack vi fa riferimento senza possederne il ciclo di vita.
spec:
gateway:
enabled: true
guardrails:
catalog: [ pseudonymizer ] # Stack creates + wires the Guardrail
refs:
- { name: my-guardrail } # a Guardrail you manageSia i guardrail da catalogo sia quelli esterni sono soggetti a licenza e passano attraverso il proxy license-gate iniettato dall'operatore (che fallisce in modo chiuso se la licenza decade). I figli Guardrail dello Stack compaiono nel suo albero di avanzamento e vengono smantellati insieme allo Stack. Vedi Guardrail per la definizione completa.
Eseguire il debug di un guardrail all'interno di uno Stack
Imposta logLevel (e facoltativamente blockedReason) sullo Stack, non sul figlio:
spec:
gateway:
guardrails:
catalog: [ pseudonymizer ]
logLevel: debug # one proxy log record per request
blockedReason: "blocked by the Navique license gate"Uno Stack riscrive la spec curata di ogni figlio, quindi con la driftPolicy: Enforce predefinita un kubectl patch del logLevel del Guardrail figlio viene annullato — e poiché lo Stack osserva i propri figli Guardrail, la patch innesca proprio la riconciliazione che la annulla. (Con driftPolicy: Adopt una patch manuale sopravvive, ma solo fino alla modifica successiva dello Stack, e disattiva la correzione del drift per ogni figlio.) Questi campi si applicano ai figli catalog posseduti dallo Stack; i guardrail collegati tramite refs sono tuoi, quindi imposta logLevel direttamente su quei CR.
I contatori delle decisioni del proxy non richiedono alcun opt-in — vedi Risoluzione dei problemi di una chiamata guardrail non riuscita.
Backup e protezione dall'eliminazione
Poiché uno Stack è il percorso scelto dagli utenti non tecnici, tratta i dati con stato in modo difensivo.
I backup sono obbligatori per i datastore con stato gestiti. Uno Stackdeve impostare un backup abilitato su ogni datastores.postgres, datastores.clickhouse e datastores.mongo gestito (lo stesso insieme a cui viene applicato automaticamente un Lock) — applicarne uno senza backup viene rifiutato (Postgres in fase di admission tramite CEL; ClickHouse/Mongo in fase di riconciliazione), così nessuno avvia un datastore privo di backup. Redis (cache) e Meilisearch (un indice ricostruibile) sono esenti. Il blocco ha ovunque la stessa forma indipendente dal provider (s3/azure/gcs + pianificazione + retention) e viene riportato nel figlio gestito; Postgres esegue il PITR nativo di CNPG, ClickHouse un CronJob clickhouse-backup, MongoDB un CronJob mongodump+rclone. I datastore esterni non richiedono qui alcun backup — lo gestisci tu. Imposta datastores.requireBackup: false per saltare il requisito (utenti avanzati / CI).
Ai datastore gestiti viene applicato automaticamente un Lock. Quando lo Stack effettua il provisioning di un PostgresCluster, ClickHouseCluster o MongoCluster gestito (quest'ultimo contiene la cronologia delle conversazioni della ChatUI), crea anche un Lock su di esso, così un kubectl delete accidentale viene bloccato. Redis (una cache) e Meilisearch (un indice di ricerca ricostruibile) non vengono mai bloccati.
- Si tratta di una protezione dall'eliminazione a livello di dati: l'eliminazione dello
Stackresta bloccata finché non rimuovi quei Lock — i datastore (e i loro PVC) non vengono mai distrutti per errore. Lo Stack riporta nel proprio status i Lock che lo bloccano. - Lo
Stackcrea ciascun Lock una sola volta e non ricrea mai un Lock che hai rimosso — quindi per eliminare unoStackprotetto basta eseguire primakubectl delete lock <name>e poi eliminare loStack. L'operatore non ti ostacolerà rimettendo il Lock al suo posto. - Imposta
datastores.protectData: falseper non creare i Lock (i Lock esistenti restano invariati).
spec:
datastores:
postgres:
storageSize: 20Gi
backup:
enabled: true
provider: s3
s3:
destinationPath: s3://forge-backups/pg
credentialsSecretRef: { name: pg-backup }
clickhouse: { storageSize: 20Gi }
redis: { storageSize: 5Gi }
# protectData: false # opt out of the auto-Locks (not recommended)Separazione per namespace
Per impostazione predefinita ogni componente finisce nel namespace dello Stack stesso. Ogni blocco di componente accetta facoltativamente un namespace per collocarlo altrove:
spec:
gateway: { namespace: forge-gateway }
chatUI: { namespace: forge-ui }
observability: { type: langfuse } # stays in the Stack's namespaceQuando un componente dichiara un namespace, lo Stack:
- crea il namespace se non esiste (e lo lascia al suo posto in caso di eliminazione);
- colloca un
SecretsManagementin ogni namespace che ospita un workload, così ilsecretsRefnello stesso namespace di ciascun componente viene risolto localmente; - collega automaticamente i riferimenti tra namespace (ad es. un Gateway in un namespace verso il Postgres/Langfuse in un altro) — non devi comunque impostare alcun riferimento a mano.
Poiché gli owner reference di Kubernetes non possono attraversare i namespace, un figlio in un altro namespace viene tracciato tramite l'etichetta core.navique.com/owned-by e rimosso dal finalizer dello Stack all'eliminazione (i figli nello stesso namespace mantengono la propagazione tramite owner reference). I namespace creati automaticamente non vengono eliminati.
Login SSO / OIDC
spec.sso configura il single sign-on per l'intero Stack a partire da un solo identity provider. Issuer/provider/scope condivisi si applicano a ogni componente abilitato, mentre ogni componente riceve il proprio client OAuth (gli URL di callback differiscono) tramite un riferimento al client per componente. Un componente riceve l'SSO solo se è abilitato e il suo riferimento al client è impostato, così puoi introdurre l'SSO in modo selettivo.
| Campo | Descrizione |
|---|---|
issuerURL | Issuer OIDC / URL base di discovery condiviso |
providerName | Etichetta visualizzata condivisa |
scopes | Scope richiesti condivisi |
provider / tenantID / authorizationEndpoint / tokenEndpoint / userinfoEndpoint | Tipo di provider + endpoint, solo per il Gateway (vedi le note SSO del Gateway) |
gateway / chatUI / observability | Riferimenti al client OAuth per componente ({ name, clientIDKey?, clientSecretKey? }) |
spec:
sso:
issuerURL: https://idp.example.com
providerName: "Acme SSO"
provider: generic-oidc
authorizationEndpoint: https://idp.example.com/authorize
tokenEndpoint: https://idp.example.com/token
userinfoEndpoint: https://idp.example.com/userinfo
gateway: { name: gateway-oidc }
chatUI: { name: chatui-oidc }
observability: { name: langfuse-oidc }È ciò che rende possibile l'SSO self-service dalla procedura guidata di deployment della console di gestione. I dettagli per componente (quali variabili d'ambiente riceve ciascuna app, licenze) si trovano nelle pagine Gateway, ChatUI e Observability.
Mesh
spec.mesh.mode fa aderire i namespace dei componenti dello Stack alla ServiceMesh del cluster (mTLS + isolamento). Il valore predefinito è auto (adesione quando esiste una ServiceMesh Ready, nessun effetto altrimenti); enabled ne richiede una; disabled non aderisce mai. Lo Stack si limita ad applicare etichette ai propri namespace — l'iscrizione è compito del singleton ServiceMesh — quindi una mesh abilitata in seguito include gli Stack esistenti senza redeploy.
Licenze
Stack richiede la funzionalità managed-deployment e un limite di istanze stacks nella License. In loro assenza, componi la piattaforma con le risorse granulari, sempre disponibili (nel rispetto dei rispettivi limiti nell'edizione Community).
Vedi Edizioni e licenze.