64 docs indexed
Full reference for deploy/k8s/obleth/values.yaml with defaults and descriptions.
The Helm chart lives in deploy/k8s/obleth/. Install with:
helm install obleth ./deploy/k8s/obleth \
--namespace obleth \
--create-namespace \
-f my-values.yaml
image:
obleth: obleth/obleth:latest
benchmarkBackend: obleth/benchmark-backend:latest
controlPlane: obleth/control-plane:latest
obleth:
replicas: 3
globalMaxInFlight: 256
failOpen: true
adminToken: "" # REQUIRED — chart errors if empty (openssl rand -hex 32)
encryptionKey: "" # recommended — base64 of 32 bytes (openssl rand -base64 32)
apiKeyPepper: "" # optional — openssl rand -hex 32
existingSecret: "" # PRODUCTION — name of a pre-created Secret (see below)
allowedPrivateCidrs: "" # only needed with OBLETH_BLOCK_PRIVATE_NETWORKS=1 (strict SSRF)
upstreamBaseUrl: "" # empty -> defaults to the in-chart benchmark fixture backend
otelEndpoint: "" # set to enable tracing, e.g. "http://jaeger:4317"
slackWebhookUrl: "" # optional Slack incoming-webhook alerts (keep in a Secret)
slackAlertMinIntervalSecs: 300
modelHealthEnabled: true
modelHealthIntervalSecs: 900
modelHealthTimeoutSecs: 30
modelHealthRetentionDays: 30
usageRetentionDays: 180
adminToken, the datastore passwords, and the dashboard secrets have no
default values. The chart uses Helm's required function, so helm install/
template fails fast with a clear message if any are missing. Supply them via
--set, a local untracked values file, or a secrets manager — do not commit
production credentials to git.
existingSecret)For production, point the chart at a Secret you created out-of-band so real
credentials never enter values files or --set/CLI history. When
obleth.existingSecret is set, the chart does not render its own Secret and
references the named one instead — it must carry every key the chart would have
generated:
OBLETH_ADMIN_TOKEN, OBLETH_DATABASE_URL, OBLETH_CLICKHOUSE_PASSWORD,
OBLETH_ENCRYPTION_KEY, OBLETH_API_KEY_PEPPER, OBLETH_SLACK_WEBHOOK_URL
controlPlane.existingSecret works the same way and must carry
DASHBOARD_PASSWORD, DASHBOARD_SESSION_SECRET, DATABASE_URL,
DASHBOARD_ADMIN_EMAIL, BETTER_AUTH_URL, and OIDC_PROVIDERS. See
the Production scenario and
values-production.yaml.
The default SSRF policy permits private/LAN addresses, so api_base values
pointing at in-cluster Services (e.g. *.svc.cluster.local) usually work
without setting allowedPrivateCidrs. If you enable strict mode
(OBLETH_BLOCK_PRIVATE_NETWORKS=1), list trusted CIDRs here (e.g.
10.0.0.0/8). See Security.
Helm does not register models or create tenant API keys. After install, follow Installation — post-install steps.
hpa:
enabled: true
minReplicas: 3
maxReplicas: 20
targetCPUUtilizationPercentage: 70
Pod- and container-level hardening applied to the stateless workloads the chart builds (obleth data plane, control-plane, benchmark-backend). The defaults satisfy the Kubernetes restricted Pod Security Standard and are on out of the box.
podSecurityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
runAsNonRoot: true
# readOnlyRootFilesystem: true # opt-in; confirm nothing writes the rootfs first
UID is intentionally not pinned — the images already ship distinct non-root
users (obleth 10001, control-plane 1000), and runAsNonRoot enforces
non-root without hardcoding a UID. The bundled datastores are excluded on
purpose: their official images manage their own users (the Postgres entrypoint,
for example, must start as root).
# Spread obleth replicas across nodes. "soft" prefers distinct nodes but still
# schedules on a single-node cluster; "hard" requires distinct nodes (won't
# schedule more replicas than nodes); "" disables.
affinity:
antiAffinity: soft
# Keep a minimum number of obleth pods available during voluntary disruptions
# (node drains, rolling upgrades). Rendered only when replicas > 1.
podDisruptionBudget:
enabled: true
minAvailable: 1
# Restrict the BUNDLED datastore ports (Postgres 5432, Redis 6379, ClickHouse
# 8123/9000) to the obleth data plane only. Off by default. Requires a CNI that
# enforces NetworkPolicy (Calico, Cilium, …); inert otherwise. No effect on
# external datastores, which run outside the chart.
networkPolicy:
enabled: false
A NetworkPolicy object is rendered per bundled datastore (only for the ones with
enabled: true).
serviceMonitor:
enabled: false # set to true if using Prometheus Operator
interval: 15s
path: /metrics
port: metrics
ingress:
enabled: false
className: nginx
host: obleth.example.com
servicePort: 80
annotations: {}
tls: []
postgres:
enabled: true # set false to use an external Postgres
image: postgres:16
user: obleth
password: "" # REQUIRED — chart errors if empty
db: obleth
persistence:
enabled: true # PVC-backed storage; false = emptyDir (data lost on restart)
size: 10Gi
storageClass: "" # "" = cluster default StorageClass
accessMode: ReadWriteOnce
external:
url: "" # set when enabled=false
redis:
enabled: true # set false to use an external Redis
image: redis:7
persistence:
enabled: true # AOF on a PVC; false = emptyDir (rebuildable cache)
size: 1Gi
storageClass: ""
accessMode: ReadWriteOnce
external:
url: "" # e.g. "redis://my-redis:6379"
clickhouse:
enabled: true # set false to use an external ClickHouse
image: clickhouse/clickhouse-server:24
db: obleth
user: obleth
password: "" # REQUIRED — chart errors if empty
persistence:
enabled: true # PVC-backed usage ledger; false = emptyDir (history lost)
size: 20Gi
storageClass: ""
accessMode: ReadWriteOnce
external:
url: "" # e.g. "http://my-clickhouse:8123"
The bundled datastores support three storage models. See
Self-Hosting for the full walkthrough and ready-made
values files in deploy/k8s/obleth/examples/.
| Scenario | Setting | Data on restart |
|---|---|---|
| Persistent (PVC) | persistence.enabled: true (default) | survives |
| Ephemeral (test) | persistence.enabled: false | lost |
| External | enabled: false + external.url | managed by you |
| Production | External datastores + existingSecret, PDB, anti-affinity, NetworkPolicy | managed by you |
Datastore Deployments use the Recreate rollout strategy so a new pod never
attaches a ReadWriteOnce PVC still held by the old pod.
benchmarkBackend:
enabled: true # disable in production
ttftMs: 20
tokenMs: 3
concurrency: 256
controlPlane:
enabled: true
replicas: 1
dashboardAdminEmail: admin@example.com # break-glass admin login (email-based)
dashboardPassword: "" # REQUIRED — >= 8 chars; chart errors if empty
dashboardSessionSecret: "" # REQUIRED — >= 32 chars (openssl rand -hex 32)
betterAuthUrl: "" # external dashboard URL; used for OIDC redirect URIs
oidcProviders: "" # JSON array to enable SSO; empty = break-glass only
existingSecret: "" # PRODUCTION — pre-created Secret with all control-plane keys
resources:
requests: { cpu: "100m", memory: "256Mi" }
limits: { cpu: "1", memory: "512Mi" }
The dashboard credentials and auth settings are rendered into a
dedicated Kubernetes Secret and injected via envFrom, not as plaintext
Deployment env values. Set existingSecret to skip that rendered Secret and
reference your own (see Pre-created Secrets).
The control-plane Deployment also carries /login readiness/liveness probes and
the resource requests/limits above.
Note:
This inlines secrets for brevity. For a fully hardened install — pre-created
Secrets (existingSecret), anti-affinity, a PodDisruptionBudget, and the
restricted security contexts — start from
values-production.yaml
and the Production scenario.
obleth:
adminToken: "my-random-32-char-token"
encryptionKey: "base64-of-32-random-bytes"
upstreamBaseUrl: "http://aibrix-gateway.aibrix.svc.cluster.local:8080/v1"
globalMaxInFlight: 64
hpa:
enabled: true
maxReplicas: 10
postgres:
enabled: false
external:
url: "postgres://obleth:strongpassword@my-rds-endpoint/obleth"
redis:
enabled: false
external:
url: "redis://my-redis-sentinel:6379"
clickhouse:
enabled: false
external:
url: "http://my-clickhouse-cloud:8123"
benchmarkBackend:
enabled: false
controlPlane:
dashboardAdminEmail: "admin@example.com"
dashboardPassword: "my-dashboard-password"
dashboardSessionSecret: "my-random-session-secret-64-chars"
serviceMonitor:
enabled: true
ingress:
enabled: true
className: nginx
host: obleth.my-company.com
tls:
- secretName: obleth-tls
hosts:
- obleth.my-company.com