Sari la conținutul principal

Kubernetes

Libre WebUI furnizează un chart Helm în helm/libre-webui.

Work pe Kubernetes

Work rulează nativ pe Kubernetes — fără daemon, CLI sau socket Docker. Activați-l la instalare:

helm install libre-webui ./helm/libre-webui --set work.enabled=true

Aceasta setează WORK_RUNTIME_BACKEND=kubernetes și creează:

  • un namespace sandbox dedicat (work.namespace, implicit libre-webui-work) cu câte un Pod per sandbox activ și un PersistentVolumeClaim per workspace (work.workspaceSize, implicit 5Gi — cotă reală pe task; o policy numită poate seta alta);
  • Role și RoleBinding limitate la namespace, care acordă ServiceAccount exact pods (get/list/create/delete), pods/exec (get/create) și persistentvolumeclaims (get/list/create/delete) — fără secrets sau cluster scope. Înlocuiesc complet socketul Docker: API server impune ca sandboxul să nu monteze căi host;
  • NetworkPolicies default-deny, ingress numai din backend pe preview port și internet egress pentru sandboxuri cu rețea, minus work.networkPolicy.blockedEgressCidrs (range-uri private, CGNAT folosit de unele clustere și cloud metadata link-local). Verificați CIDR-urile Pod/service. DNS sandbox doar către kube-system; node-local DNS cere excepție.

Sandboxurile rulează non-root, rootfs read-only, fără capabilities, seccomp RuntimeDefault și fără token ServiceAccount. Fișierele, comenzile, git și terminalele folosesc exec prin API server; preview este servit din Pod IP prin proxy semnat same-origin, ceea ce cere backend in-cluster. Workspace-urile host-folder nu sunt suportate.

Două note: NetworkPolicy cere un CNI care o impune (Calico, Cilium, kind recent și majoritatea clusterelor administrate). Verificați înainte de a considera izolarea activă; suita CI raportează enforcement. Nu montați niciodată socketul runtime al nodului în Podul WebUI.

Instalare

helm install libre-webui oci://ghcr.io/libre-webui/charts/libre-webui

Chartul implicit deployează Libre cu storage persistent și Ollama inclus. Tranziția 0.14.1 este fixată la digest multi-architecture verificat; charturile ulterioare folosesc image-ul semantic appVersion. Setați image.tag sau image.digest numai deliberat. Un image.tag non-empty are prioritate față de digestul tranziției.

Profilul solo acceptă replicaCount: 0 pentru suspendare sau replicaCount: 1 pentru funcționare. Refuză valori mai mari și HorizontalPodAutoscaler deoarece SQLite, fișierele locale și coordonarea proces-local nu sunt sigure cu mai multe pods. La zero se creează control-plane resources, dar nu se servește trafic.

Pentru mai multe replici folosiți profilul complet team: PostgreSQL/PGVector, blob S3, Redis și worker persistent separat. Chartul refuză amestec parțial shared/local. Porniți de la un fișier values protejat:

replicaCount: 3

env:
LIBRE_PLATFORM_MODE: team
DATABASE_BACKEND: postgres
DATABASE_SSL_MODE: verify-full
POSTGRES_MIGRATION_MODE: apply
POSTGRES_POOL_MAX: 10
POSTGRES_CONNECT_TIMEOUT_MS: 5000
POSTGRES_IDLE_TIMEOUT_MS: 30000
POSTGRES_STATEMENT_TIMEOUT_MS: 30000
POSTGRES_MIGRATION_LOCK_TIMEOUT_MS: 60000
OLLAMA_TIMEOUT: 300000
OLLAMA_LONG_OPERATION_TIMEOUT: 900000
OLLAMA_MAX_CONTEXT: 32768
BLOB_STORE_BACKEND: s3
VECTOR_STORE_BACKEND: pgvector
COORDINATION_BACKEND: redis
JOB_WORKER_MODE: external
STORAGE_ENCRYPTION_ACTIVE_KEY_ID: active
S3_BUCKET: libre-blobs
S3_REGION: us-east-1
S3_BLOB_PREFIX: libre/blobs

worker:
replicaCount: 1

secrets:
databaseUrl: postgresql://libre:replace-me@postgres.example/libre
redisUrl: rediss://redis.example:6379/0
jwtSecret: '<one-stable-high-entropy-secret-for-every-replica>'
encryptionKey: '<legacy-64-character-lowercase-hex-key>'
storageEncryptionKeys: '{"legacy":"<legacy-64-character-lowercase-hex-key>","active":"<active-64-character-lowercase-hex-key>"}'
s3AccessKeyId: replace-me
s3SecretAccessKey: replace-me

secrets.encryptionKey trebuie să corespundă exact intrării legacy, iar map-ul să conțină STORAGE_ENCRYPTION_ACTIVE_KEY_ID. secrets.jwtSecret trebuie să fie o valoare stabilă high-entropy comună tuturor app/worker pods; fără ea chartul refuză team pentru ca sesiunile să nu depindă de material pod-local. Păstrați TLS verificat pentru PostgreSQL administrat și nu adăugați parametri TLS driver în databaseUrl. Limitele pool sunt per pod, deci rezervați cel puțin (replicaCount + worker.replicaCount) * POSTGRES_POOL_MAX conexiuni plus rezervă.

helm upgrade --install libre-webui \
oci://ghcr.io/libre-webui/charts/libre-webui \
--values /absolute/path/to/libre-team-values.yaml

Nu commitați fișierul și nu treceți secrets prin --set. Folosiți workflow encrypted. Scalați furnizorii și Pods Work independent. Cu work.enabled=true, workerul extern primește același image, StorageClass, work.env, endpoint Ollama, timeouts și context ca app, fiindcă embeddings, chat-uri și Work calls rulează acolo.

O app team activă (replicaCount pozitiv sau autoscaling) cere cel puțin un worker; chartul refuză zero. Pentru suspendare totală setați replicaCount și worker.replicaCount zero. Numai app zero este drain/recovery worker-only: fără web, dar coada continuă.

Upgrade team și compatibilitate schema

Libre cere exact schema version, nu mixed sau zero-downtime DB upgrade. App și worker folosesc Recreate, fără overlap în fiecare Deployment, dar Kubernetes nu le coordonează ca o singură limită. Înainte: opriți ingress, terminați/anulați jobs, scalați ambele la zero, backup verificat și confirmați terminarea pods. Apoi upgrade cu POSTGRES_MIGRATION_MODE=apply; un proces ține advisory leader lock, celelalte așteaptă și validează ledger-ul. Pentru rollback restaurați backupul într-o țintă PostgreSQL/S3 curată; niciodată binary vechi pe schema incompatibilă. Va exista întrerupere deliberată.

Acces local

kubectl port-forward svc/libre-webui 8080:8080

Deschideți http://localhost:8080.

Ollama extern

Folosiți un endpoint Ollama existent:

helm install libre-webui oci://ghcr.io/libre-webui/charts/libre-webui \
--set ollama.bundled.enabled=false \
--set ollama.external.enabled=true \
--set ollama.external.url=http://my-ollama:11434

Secrete

Setați un JWT secret stabil și o cheie de criptare. Implicit chartul creează <release>-libre-webui-secrets din valori non-empty secrets.*:

helm upgrade --install libre-webui \
oci://ghcr.io/libre-webui/charts/libre-webui \
--set-string secrets.jwtSecret="$(openssl rand -hex 64)" \
--set-string secrets.encryptionKey="$(openssl rand -hex 32)"

Pentru Secret administrat de operator setați secrets.existingSecret; chartul nu mai creează și app/worker referă obiectul numit:

secrets:
existingSecret: libre-webui-runtime

Creați înainte de release. Trebuie jwt-secret, encryption-key, iar team și database-url, redis-url, storage-encryption-keys. Opțional session-secret, s3-access-key-id, s3-secret-access-key, s3-session-token. OAuth GitHub/Hugging Face citește *-client-id/*-client-secret când secrets.githubClientId sau secrets.huggingfaceClientId non-empty activează integrarea. Chartul nu validează/copiază valorile; cheia lipsă împiedică Podul să pornească.

Pentru automatizare preferați secrets.existingSecret cu external-secrets sau values criptate. --set poate fi vizibil în procese și metadata Helm. Credentialele provider prin extensie deliberată sau per utilizator în WebUI.

NetworkPolicies pentru aplicație și worker

Setați networkPolicy.enabled=true pentru ingress policies app și worker team:

networkPolicy:
enabled: true

App acceptă ingress numai pe portul HTTP, workerul niciunul. Policies nu limitează egress: procesele trebuie să atingă PostgreSQL, Redis, S3, Ollama, tools și furnizori, iar operatorul decide locația.

Este separat de work.networkPolicy.enabled, default-deny în namespace Work, activat implicit cu Work. Ambele cer CNI enforcement; randarea obiectelor nu dovedește izolarea.

Persistență

Păstrați PVC data și Ollama pe storage persistent. Salvați volumul și cheia împreună.

Workspace-urile Work au PVC proprii în sandbox, nu data PVC. Recovery complet cere baza (ownership, nume, runs) și PVC; salvați împreună.

Ingress

Pentru acces public configurați HTTPS și origin exact:

helm upgrade libre-webui \
oci://ghcr.io/libre-webui/charts/libre-webui \
--reuse-values \
--set env.TRUST_PROXY=1 \
--set-string env.CORS_ORIGIN=https://your-domain.example

TRUST_PROXY este count exact de hops, nu boolean. Default sigur 0 ignoră forwarded addresses. 1 numai cu un ingress direct; numărați fiecare load balancer în lanț fix și păstrați Service inaccesibil în afara lui. Prea mic grupează clienți și epuizează login limits; prea mare crede adresă client. Chartul acceptă 016, niciodată true, și îl trimite numai pods HTTP.

Chartul nu expune BASE_URL sau callbacks OAuth. Instalațiile OAuth trebuie să extindă chartul/patch Deployment, iar URL-urile să corespundă domeniului public.

Planificarea resurselor

Pentru Ollama local, programați Podul pe nodes cu memorie/GPU suficient. Dacă există un serviciu dedicat Ollama/inference, varianta externă este mai simplă.

Documentație asociată