Skip to content

Avvio rapido ​

Questa procedura guidata mette in piedi una piattaforma completa — datastore, un Gateway LiteLLM, l'osservabilità Langfuse e la chat app LibreChat — su un cluster in cui l'operatore è già installato. Funziona senza licenza (l'edizione Community); con una licenza, la chat app e il tracing si collegano da soli.

Puoi applicare tutto in una volta: ogni risorsa diventa Ready non appena lo sono quelle che referenzia, e l'operatore rimette in coda la riconciliazione durante l'attesa.

Usa il set di lavoro incluso

Il repository include esattamente questi manifest in config/samples/quickstart/. Sostituisci ogni REPLACE_ME in secrets.yaml, quindi:

bash
kubectl apply -k config/samples/quickstart/

config/samples/*.yaml contiene un esempio di riferimento per ciascun kind di risorsa con più opzioni (Vault, Wäg, guardrail, Stack, …); si tratta di esempi da cui copiare, non di un set da applicare nel suo insieme.

0. Namespace ​

yaml
apiVersion: v1
kind: Namespace
metadata: { name: forge-data }
---
apiVersion: v1
kind: Namespace
metadata: { name: forge-gateway }
---
apiVersion: v1
kind: Namespace
metadata: { name: forge-langfuse }
---
apiVersion: v1
kind: Namespace
metadata: { name: forge-ui }

1. (Opzionale) Applica una licenza ​

Senza licenza la piattaforma funziona come edizione Community (un'istanza per tipo, collegamento manuale). Per abilitare la multi-istanza e il collegamento automatico, scarica la tua licenza (o avvia una prova) dal portale clienti all'indirizzo portal.navique.dev, quindi crea il Secret della licenza e una License:

bash
kubectl -n navique-system create secret generic navique-license \
  --from-file=license=./license.lic
yaml
apiVersion: core.navique.com/v1alpha1
kind: License
metadata:
  name: cluster            # singleton — must be named "cluster"
spec:
  secretRef:
    name: navique-license
    key: license
    namespace: navique-system

Consulta Gestire una licenza.

2. Credenziali ​

I workload leggono semplici Secret Kubernetes — non c'è altro da installare. Sostituisci ogni REPLACE_ME:

yaml
# Plain Kubernetes Secrets: nothing else to install. Replace every REPLACE_ME.
# In production, have a SecretsManagement (Vault, Azure Key Vault, …) produce
# these instead and set the workloads' secretsRef.

# The model provider key(s) the gateway uses (models[].refSecretKey).
apiVersion: v1
kind: Secret
metadata: { name: model-credentials, namespace: forge-gateway }
stringData:
  OPENAI_API_KEY: REPLACE_ME
---
# Credentials for Langfuse's object storage. object-storage.yaml starts a small
# MinIO with these; with your own S3, put its access keys here.
apiVersion: v1
kind: Secret
metadata: { name: langfuse-s3, namespace: forge-langfuse }
stringData:
  access-key-id: forge-langfuse
  secret-access-key: REPLACE_ME_min_8_chars
---
# Only used WITHOUT a licence: the key the chat app sends to the gateway.
# Create a key in the gateway's LiteLLM admin UI and paste it here. With the
# auto-wiring licence the operator mints and injects a key itself and ignores
# this Secret.
apiVersion: v1
kind: Secret
metadata: { name: chat-gateway-key, namespace: forge-ui }
stringData:
  LITELLM_API_KEY: REPLACE_ME

Credenziali da un vault

In produzione, lascia che un SecretsManagement produca questi Secret da HashiCorp Vault, Azure Key Vault o qualsiasi provider External Secrets, e fai puntare a esso il secretsRef opzionale dei workload.

3. Object storage per Langfuse ​

Langfuse v3 richiede un object storage. Per la valutazione, un MinIO a replica singola:

yaml
# EVALUATION ONLY: a single-replica MinIO (no redundancy, ephemeral storage) so
# Langfuse v3 has the object storage it requires. In production, use your own
# S3 / Azure Blob / GCS and drop this file (see observability.yaml).
apiVersion: apps/v1
kind: Deployment
metadata: { name: minio, namespace: forge-langfuse }
spec:
  replicas: 1
  selector: { matchLabels: { app: minio } }
  template:
    metadata: { labels: { app: minio } }
    spec:
      containers:
        - name: minio
          image: quay.io/minio/minio:latest
          args: ["server", "/data"]
          env:
            - { name: MINIO_ROOT_USER, valueFrom: { secretKeyRef: { name: langfuse-s3, key: access-key-id } } }
            - { name: MINIO_ROOT_PASSWORD, valueFrom: { secretKeyRef: { name: langfuse-s3, key: secret-access-key } } }
          ports: [ { containerPort: 9000 } ]
          volumeMounts: [ { name: data, mountPath: /data } ]
      volumes: [ { name: data, emptyDir: {} } ]
---
apiVersion: v1
kind: Service
metadata: { name: minio, namespace: forge-langfuse }
spec:
  selector: { app: minio }
  ports: [ { port: 9000, targetPort: 9000 } ]
---
# Creates the bucket Langfuse writes to.
apiVersion: batch/v1
kind: Job
metadata: { name: minio-bucket, namespace: forge-langfuse }
spec:
  backoffLimit: 20
  template:
    spec:
      restartPolicy: OnFailure
      containers:
        - name: mc
          image: quay.io/minio/mc:latest
          env:
            - { name: AK, valueFrom: { secretKeyRef: { name: langfuse-s3, key: access-key-id } } }
            - { name: SK, valueFrom: { secretKeyRef: { name: langfuse-s3, key: secret-access-key } } }
          command: ["sh", "-c", "mc alias set local http://minio.forge-langfuse.svc:9000 \"$AK\" \"$SK\" && mc mb --ignore-existing local/langfuse"]

In produzione, rimuovi questa parte e fai puntare blob (passo 6) al tuo S3, Azure Blob Storage o Google Cloud Storage — consulta Observability.

4. Datastore ​

yaml
# The shared datastores, sized for evaluation (one replica each). Each consumer
# gets its own logical database. Without the auto-wiring licence the databases
# must be declared here; with it, a datastore also creates the databases its
# referencing workloads ask for.
apiVersion: core.navique.com/v1alpha1
kind: PostgresCluster
metadata: { name: forge-pg, namespace: forge-data }
spec:
  type: cnpg
  mode: managed
  managed: { instances: 1, storageSize: 5Gi }
  databases:
    - { name: litellm }
    - { name: langfuse }
---
apiVersion: core.navique.com/v1alpha1
kind: ClickHouseCluster
metadata: { name: forge-ch, namespace: forge-data }
spec:
  type: clickhouse
  mode: managed
  databases:
    - { name: langfuse }
---
apiVersion: core.navique.com/v1alpha1
kind: RedisInstance
metadata: { name: forge-redis, namespace: forge-data }
spec:
  type: ot-container-kit
  mode: managed
  managed: { topology: standalone, storageSize: 1Gi }
---
# The chat app's conversation store and search index live next to it.
apiVersion: core.navique.com/v1alpha1
kind: MongoCluster
metadata: { name: forge-mongo, namespace: forge-ui }
spec:
  type: mck
  mode: managed
  managed: { members: 1, version: "8.0.4", storageSize: 5Gi }
  databases:
    - { name: LibreChat }
---
apiVersion: core.navique.com/v1alpha1
kind: MeilisearchInstance
metadata: { name: forge-meili, namespace: forge-ui }
spec:
  type: meilisearch
  mode: managed
  managed: { storageSize: 1Gi }

Nessun block storage disponibile, o preferisci usare il tuo?

Imposta mode: external e fornisci un connectionSecretRef, oppure mode: adopt per puntare a un datastore già in esecuzione. Consulta la pagina di riferimento di ciascuna risorsa.

5. Il Gateway ​

yaml
# The LiteLLM gateway. Model keys come from the model-credentials Secret.
apiVersion: core.navique.com/v1alpha1
kind: Gateway
metadata: { name: gateway, namespace: forge-gateway }
spec:
  database:
    mode: postgresCluster
    postgresClusterRef: { name: forge-pg, namespace: forge-data }
    databaseName: litellm
  instance:
    replicas: 1
    masterKey: { autoGenerate: true }
    saltKey: { autoGenerate: true }
  # Traces to Langfuse — wired automatically with the auto-wiring licence.
  observabilityRef: { name: observability, namespace: forge-langfuse }
  models:
    - name: gpt-4o-mini
      modelName: gpt-4o-mini
      model: openai/gpt-4o-mini
      refSecretKey: OPENAI_API_KEY

6. Observability (Langfuse) ​

yaml
# Langfuse v3 on the shared datastores. The first person to sign up becomes its
# administrator (set langfuse.bootstrap to seed an admin, org and API keys).
apiVersion: core.navique.com/v1alpha1
kind: Observability
metadata: { name: observability, namespace: forge-langfuse }
spec:
  type: langfuse
  langfuse:
    postgres: { mode: ref, ref: { name: forge-pg, namespace: forge-data }, databaseName: langfuse }
    clickhouse: { mode: ref, ref: { name: forge-ch, namespace: forge-data }, databaseName: langfuse }
    redis: { mode: ref, ref: { name: forge-redis, namespace: forge-data } }
    blob:
      provider: s3
      s3:
        bucket: langfuse
        region: us-east-1
        endpoint: http://minio.forge-langfuse.svc:9000
        forcePathStyle: true
        credentialsSecretRef: { name: langfuse-s3 }

7. La chat app (LibreChat) ​

yaml
# LibreChat. With the auto-wiring licence, gatewayRef is enough: the operator
# mints a gateway key and fills the model list. Without it, the chat app uses the
# gateway address and key below (secrets.yaml: chat-gateway-key).
apiVersion: core.navique.com/v1alpha1
kind: ChatUI
metadata: { name: forge-ui, namespace: forge-ui }
spec:
  gatewayRef: { name: gateway, namespace: forge-gateway }
  gateway:
    url: http://gateway.forge-gateway.svc.cluster.local:4000/v1
    apiKeySecretRef: { name: chat-gateway-key, key: LITELLM_API_KEY }
  models: [ gpt-4o-mini ]
  mongo: { mode: ref, ref: { name: forge-mongo }, databaseName: LibreChat }
  meilisearch: { mode: ref, ref: { name: forge-meili } }

Con una licenza e gatewayRef, l'operatore genera una chiave del gateway per la chat app e inietta automaticamente l'indirizzo del gateway. Senza licenza, la chat app usa gateway.{url, apiKeySecretRef} — consulta Collegamento automatico.

8. Osserva la convergenza ​

bash
# Datastores
kubectl -n forge-data get postgrescluster,clickhousecluster.core.navique.com,redisinstance
kubectl -n forge-ui   get mongocluster,meilisearchinstance

# Workloads
kubectl -n forge-gateway  get gateway
kubectl -n forge-langfuse get observability
kubectl -n forge-ui       get chatui

# Drill into a resource's conditions if something is pending
kubectl -n forge-gateway describe gateway gateway

Ogni risorsa riporta Ready non appena le sue dipendenze sono attive; le sue condition indicano esattamente cosa sta attendendo.

9. Accedi alla piattaforma ​

In questo set nulla è esposto all'esterno del cluster; per provarla, inoltra una porta:

bash
kubectl -n forge-ui port-forward svc/forge-ui-librechat 3080:3080         # chat app → http://localhost:3080
kubectl -n forge-langfuse port-forward svc/observability-web 3000:3000   # Langfuse → http://localhost:3000

Seleziona il modello nella chat app e avvia una conversazione — le richieste passano attraverso il gateway e (con una licenza) le trace compaiono in Langfuse. Per pubblicarle, imposta ingress sulle risorse — consulta la pagina di riferimento di ciascuna risorsa.

Pulizia ​

L'eliminazione di una risorsa attiva il suo finalizer: le CR upstream emesse e le release Helm possedute vengono rimosse, e ogni operatore di capacità installato dall'operatore viene disinstallato non appena nient'altro ne ha bisogno. Le risorse adottate ed esterne non vengono mai toccate. Consulta Provenienza e ciclo di vita.

bash
kubectl delete -k config/samples/quickstart/

Nucleo open source sotto AGPL-3.0. I componenti Enterprise sono proprietari e soggetti a licenza.