OBLETHdocs

Helm values

Every value in the obleth Helm chart (deploy/k8s/obleth/values.yaml), its default, and what it sets in the rendered objects.

14 min readUpdated for v2.4.0Edit on GitHub

The chart is published at oci://ghcr.io/thediymaker/charts/obleth; chart version and appVersion are both 2.4.0.

helm install obleth oci://ghcr.io/thediymaker/charts/obleth \
  --version 2.4.0 \
  --namespace obleth --create-namespace \
  --set obleth.adminToken=$(openssl rand -hex 32) \
  --set postgres.password=$(openssl rand -hex 16) \
  --set redis.password=$(openssl rand -hex 16) \
  --set clickhouse.password=$(openssl rand -hex 16) \
  --set controlPlane.dashboardPassword='change-me-now' \
  --set controlPlane.dashboardSessionSecret=$(openssl rand -hex 32) \
  -f my-values.yaml

--set values end up in shell history and the release record. In production, create the Secrets yourself and name them in existingSecret. Upgrading from 1.x changes the Secret keys; see Upgrading from v1.x.

Required values

Rendering fails with a message when one of these is missing.

ValueRequired when
obleth.adminTokenAlways, unless obleth.existingSecret
postgres.passwordpostgres.enabled, unless obleth.existingSecret
redis.passwordredis.enabled, unless obleth.existingSecret
clickhouse.passwordclickhouse.enabled, unless obleth.existingSecret
controlPlane.dashboardPasswordcontrolPlane.enabled, unless controlPlane.existingSecret
controlPlane.dashboardSessionSecretSame as above
postgres.external.urlpostgres.enabled: false, unless obleth.existingSecret
redis.external.urlredis.enabled: false, unless obleth.existingSecret
clickhouse.external.urlclickhouse.enabled: false
obleth.upstreamBaseUrlbenchmarkBackend.enabled: false
redis.maxmemoryredis.enabled (default 400mb)

redis.password goes unescaped into OBLETH_REDIS_URL, so rendering also fails if it contains @, :, /, ?, #, % or whitespace. Use hex (openssl rand -hex 16). The dashboard enforces the lengths itself: dashboardSessionSecret must be at least 32 characters, and a dashboardPassword under 8 characters is not seeded.

Gateway

Values for the gateway Deployment (<release>-obleth) and the objects around it. Fairshare limits are cluster-wide across replicas; see Fairshare engine and Scaling.

ValueDefaultWhat it sets
obleth.replicas1Gateway pods; ignored when hpa.enabled
obleth.globalMaxInFlight4096Ceiling across all model pools, cluster-wide
obleth.defaultModelMaxInFlight32Pool size for a model with no max_in_flight
obleth.fairshareSharedSlotstrueLimits held as Redis slots shared by all replicas
obleth.fairshareReplicaAwaretrueEach replica takes ceil(limit / replicas) when shared slots are off or Redis is down
obleth.fairshareReplicaHeartbeatSecs5Replica heartbeat and slot re-assert interval
obleth.fairshareReplicaTtlSecs15How long a heartbeat counts; raised to at least 2× the interval
obleth.fairshareHistorySecs3600Fairshare activity history kept in memory; 0 off
obleth.fairshareSessionAffinity.enabledfalseFavour warm agent sessions in each pool; see Session affinity
obleth.fairshareSessionAffinity.warmSecs120How long after its last step a session counts as warm
obleth.fairshareSessionAffinity.holdMs3000How long a looping session's slot is held for its next step; 0 holds nothing
obleth.fairshareSessionAffinity.maxJumps8Times a queued request may be passed by later requests of its key
obleth.fairshareSessionAffinity.maxBypassSecs30Wait after which nothing passes a request
obleth.fairshareSessionAffinity.maxHeldPercent25Most of a pool's slots held at once
obleth.failOpentrueAdmit a request when its Redis budget check fails; false rejects it
obleth.adminToken""Management API token (Secret); required
obleth.encryptionKey""Base64 of 32 bytes; encrypts model and MCP credentials at rest. Empty stores them in plain text
obleth.apiKeyPepper""Pepper mixed into API key hashes; changing it invalidates every secret key
obleth.jwtIssuers""JSON array of trusted identity token issuers; empty turns the path off
obleth.existingSecret""Pre-created Secret used instead of the chart's
obleth.allowedPrivateCidrs""CIDRs allowed when strict outbound-URL mode is on
obleth.upstreamBaseUrl""Default upstream; empty uses the benchmark backend
obleth.otelEndpoint""OTLP trace endpoint; empty turns tracing off
obleth.slackWebhookUrl""Slack webhook seeded into alert settings on first boot (Secret)
obleth.slackAlertMinIntervalSecs300Minimum gap between repeats of one alert
obleth.modelHealthEnabledtrueBackground model health checks
obleth.modelHealthIntervalSecs900Health check interval
obleth.modelHealthTimeoutSecs30Health check timeout
obleth.modelHealthRetentionDays30Days of health check history kept
obleth.usageRetentionDays180Days of per-request usage rows kept in ClickHouse
obleth.telemetryFlushIntervalMs5000How long each gateway pod buffers usage rows and spans before inserting them, 100–60000 ms. Fewer, larger inserts cost ClickHouse much less merge I/O; rows reach the dashboard up to this long after a request ends
obleth.shutdownGraceSecs300Drain time on SIGTERM; keep below 310 (see below)
obleth.redisRewarmSecs300Postgres-to-Redis re-push interval; 0 off
obleth.upstreamTimeoutSecs300Wait for upstream response headers
obleth.upstreamReadTimeoutSecs""Longest upstream silence; empty is the upstream timeout, at least 120 s; 0 off
obleth.redisResponseTimeoutMs250Redis command timeout
obleth.redisConnectTimeoutMs2000Redis connect timeout
obleth.admissionTimeoutSecs60Queue wait before 503 with Retry-After: 5
obleth.videoJobRetentionHours24How long a video job record is kept
obleth.videoJobScopekeyWho sees a video job: key or tenant (video generation)
obleth.resourcesrequests 250m / 256Mi, limits 2 / 1GiGateway container resources
obleth.capacityDiscovery.enabledfalsePool sizes from the backend for discovered models (pool sizes)
obleth.capacityDiscovery.intervalSecs15How often each replica re-reads capacity
obleth.capacityDiscovery.namespaces[]Namespaces the kubernetes source reads; also where RBAC is rendered
obleth.capacityDiscovery.defaultService""Service name template ({upstream_model}, {model_name}) for models without capacity_service
image.oblethghcr.io/thediymaker/obleth-gateway/oblethGateway image
image.controlPlaneghcr.io/thediymaker/obleth-gateway/control-planeDashboard image
image.provisionerghcr.io/thediymaker/obleth-gateway/obleth-provisionerProvisioner image
image.benchmarkBackendghcr.io/thediymaker/obleth-gateway/benchmark-backendBenchmark backend image
image.tag""Tag for the four images above and the compressor; empty is v2.4.0
image.pullPolicyIfNotPresentPull policy for those images
hpa.enabledfalseCPU HorizontalPodAutoscaler for the gateway
hpa.minReplicas1HPA minimum
hpa.maxReplicas20HPA maximum
hpa.targetCPUUtilizationPercentage70HPA CPU target
affinity.antiAffinitysoftSpread gateway pods over nodes: soft, hard, or "" off
podDisruptionBudget.enabledtruePDB, rendered only when the minimum replica count is above 1
podDisruptionBudget.minAvailable1PDB minAvailable
nodeResolution.hostAliases[]/etc/hosts entries on gateway and provisioner pods
nodeResolution.dnsConfig{}Resolver for gateway and provisioner pods
nodeResolution.dnsPolicy""dnsPolicy override, such as None
serviceMonitor.enabledfalseServiceMonitor scraping metrics every 5 s; needs the Prometheus Operator CRDs

shutdownGraceSecs plus the 5 s preStop delay, 20 s telemetry drain and 10 s OTLP flush must fit in the fixed terminationGracePeriodSeconds: 345. The minimum replica count for the PDB is hpa.minReplicas with the HPA on, else obleth.replicas. Capacity discovery RBAC (a ServiceAccount, plus a Role and RoleBinding per namespace granting only get, list, watch on endpointslices) is rendered only when enabled is true and namespaces is not empty. nodeResolution helps the pods reach Slurm compute nodes.

Gateway environment mapping

What the gateway container gets. Any other variable takes its default from Environment variables; to set one, add it as a key in the obleth.existingSecret Secret, which reaches the container through envFrom.

VariableSet from
OBLETH_PROXY_LISTENFixed 0.0.0.0:8080
OBLETH_ADMIN_LISTENFixed 0.0.0.0:9180
OBLETH_METRICS_LISTENFixed 0.0.0.0:9091
OBLETH_UPSTREAM_BASE_URLobleth.upstreamBaseUrl, else http://<release>-benchmark-backend:8081
OBLETH_GLOBAL_MAX_IN_FLIGHTobleth.globalMaxInFlight
OBLETH_DEFAULT_MODEL_MAX_IN_FLIGHTobleth.defaultModelMaxInFlight
OBLETH_FAIRSHARE_HISTORY_SECSobleth.fairshareHistorySecs
OBLETH_FAIRSHARE_SHARED_SLOTSobleth.fairshareSharedSlots
OBLETH_FAIRSHARE_REPLICA_AWAREobleth.fairshareReplicaAware
OBLETH_FAIRSHARE_REPLICA_HEARTBEAT_SECSobleth.fairshareReplicaHeartbeatSecs
OBLETH_FAIRSHARE_REPLICA_TTL_SECSobleth.fairshareReplicaTtlSecs
OBLETH_FAIRSHARE_SESSION_AFFINITYobleth.fairshareSessionAffinity.enabled
OBLETH_FAIRSHARE_SESSION_AFFINITY_WARM_SECSobleth.fairshareSessionAffinity.warmSecs
OBLETH_FAIRSHARE_SESSION_AFFINITY_HOLD_MSobleth.fairshareSessionAffinity.holdMs
OBLETH_FAIRSHARE_SESSION_AFFINITY_MAX_JUMPSobleth.fairshareSessionAffinity.maxJumps
OBLETH_FAIRSHARE_SESSION_AFFINITY_MAX_BYPASS_SECSobleth.fairshareSessionAffinity.maxBypassSecs
OBLETH_FAIRSHARE_SESSION_AFFINITY_MAX_HELD_PERCENTobleth.fairshareSessionAffinity.maxHeldPercent
OBLETH_CAPACITY_DISCOVERY_ENABLEDobleth.capacityDiscovery.enabled
OBLETH_CAPACITY_DISCOVERY_INTERVAL_SECSobleth.capacityDiscovery.intervalSecs
OBLETH_CAPACITY_DISCOVERY_NAMESPACESobleth.capacityDiscovery.namespaces, de-duplicated, comma-joined
OBLETH_CAPACITY_DEFAULT_SERVICEobleth.capacityDiscovery.defaultService
OBLETH_FAIL_OPENobleth.failOpen
OBLETH_ALLOWED_PRIVATE_CIDRSobleth.allowedPrivateCidrs
OBLETH_MODEL_HEALTH_ENABLEDobleth.modelHealthEnabled
OBLETH_MODEL_HEALTH_INTERVAL_SECSobleth.modelHealthIntervalSecs
OBLETH_MODEL_HEALTH_TIMEOUT_SECSobleth.modelHealthTimeoutSecs
OBLETH_MODEL_HEALTH_RETENTION_DAYSobleth.modelHealthRetentionDays
OBLETH_USAGE_RETENTION_DAYSobleth.usageRetentionDays
OBLETH_TELEMETRY_FLUSH_INTERVAL_MSobleth.telemetryFlushIntervalMs
OBLETH_OTEL_ENDPOINTobleth.otelEndpoint
OBLETH_SLACK_ALERT_MIN_INTERVAL_SECSobleth.slackAlertMinIntervalSecs
OBLETH_SHUTDOWN_GRACE_SECSobleth.shutdownGraceSecs
OBLETH_REDIS_REWARM_SECSobleth.redisRewarmSecs
OBLETH_UPSTREAM_TIMEOUT_SECSobleth.upstreamTimeoutSecs
OBLETH_UPSTREAM_READ_TIMEOUT_SECSobleth.upstreamReadTimeoutSecs
OBLETH_REDIS_RESPONSE_TIMEOUT_MSobleth.redisResponseTimeoutMs
OBLETH_REDIS_CONNECT_TIMEOUT_MSobleth.redisConnectTimeoutMs
OBLETH_ADMISSION_TIMEOUT_SECSobleth.admissionTimeoutSecs
OBLETH_VIDEO_JOB_RETENTION_HOURSobleth.videoJobRetentionHours
OBLETH_VIDEO_JOB_SCOPEobleth.videoJobScope; empty renders key
OBLETH_CLICKHOUSE_URLhttp://<release>-clickhouse:8123, or clickhouse.external.url
OBLETH_CLICKHOUSE_DBclickhouse.db
OBLETH_CLICKHOUSE_USERclickhouse.user
OBLETH_WAL_PATHFixed /var/lib/obleth/telemetry.wal
OBLETH_COMPRESSOR_URLhttp://<release>-compressor:8080 when compressor.enabled
RUST_LOGFixed info,obleth=info
OBLETH_ADMIN_TOKENSecret: obleth.adminToken
OBLETH_DATABASE_URLSecret: postgres://<user>:<password>@<release>-postgres:5432/<db>, or postgres.external.url
OBLETH_REDIS_URLSecret: redis://:<password>@<release>-redis:6379, or redis.external.url
OBLETH_CLICKHOUSE_PASSWORDSecret: clickhouse.password
OBLETH_ENCRYPTION_KEYSecret: obleth.encryptionKey
OBLETH_API_KEY_PEPPERSecret: obleth.apiKeyPepper
OBLETH_SLACK_WEBHOOK_URLSecret: obleth.slackWebhookUrl
OBLETH_JWT_ISSUERSSecret: obleth.jwtIssuers

Pre-created Secrets (existingSecret)

When obleth.existingSecret names a Secret, the chart renders none of its own and every pod reads that one. It must carry these keys:

KeyNeededRead by
OBLETH_ADMIN_TOKENAlwaysGateway, dashboard, provisioner
OBLETH_DATABASE_URLAlwaysGateway
OBLETH_REDIS_URLAlways; with bundled Redis, redis://:<REDIS_PASSWORD>@<release>-redis:6379Gateway
OBLETH_CLICKHOUSE_PASSWORDAlways (may be empty for an external ClickHouse without one)Gateway; bundled ClickHouse
OBLETH_ENCRYPTION_KEYAlways (may be empty)Gateway
OBLETH_API_KEY_PEPPERAlways (may be empty)Gateway
OBLETH_SLACK_WEBHOOK_URLAlways (may be empty)Gateway
OBLETH_JWT_ISSUERSOptionalGateway
POSTGRES_PASSWORDpostgres.enabledBundled Postgres
REDIS_PASSWORDredis.enabledBundled Redis

controlPlane.existingSecret works the same way for the dashboard and must carry DASHBOARD_PASSWORD, DASHBOARD_SESSION_SECRET, DATABASE_URL, BETTER_AUTH_SECRET (falls back to DASHBOARD_SESSION_SECRET when absent), BETTER_AUTH_URL, TRUSTED_ORIGINS, DASHBOARD_ADMIN_EMAIL and OIDC_PROVIDERS.

The gateway, Redis and ClickHouse pods carry a checksum/secret annotation, so a change to the chart's Secret rolls them. With existingSecret the checksum never changes: restart the Deployments yourself after editing the Secret. The gateway reads OBLETH_JWT_ISSUERS only at start. Start from values-production.yaml.

Datastores

Each bundled datastore is a single-replica Deployment with the Recreate strategy and a readiness probe (every 5 s, 3 s timeout). Set persistence.enabled: false for an emptyDir that loses data on restart, or enabled: false plus external.url to use your own. Overlays for each case are in deploy/k8s/obleth/examples/.

ValueDefaultWhat it sets
datastores.nodeSelector{}Node selector for the bundled Postgres, Redis and ClickHouse, e.g. nodes whose storage can attach their volumes
datastores.tolerations[]Tolerations for the same three
postgres.enabledtrueBundled Postgres
postgres.imagepostgres:16Image
postgres.useroblethPOSTGRES_USER and the database URL user
postgres.password""POSTGRES_PASSWORD (Secret); required when bundled
postgres.dboblethPOSTGRES_DB
postgres.resourcesrequests 250m / 512Mi, limits 500m / 1GiContainer resources
postgres.persistence.enabledtruePVC; false uses emptyDir
postgres.persistence.size10GiPVC size
postgres.persistence.storageClass""StorageClass; empty is the cluster default
postgres.persistence.accessModeReadWriteOncePVC access mode
postgres.external.url""Database URL when enabled: false
redis.enabledtrueBundled Redis
redis.imageredis:7Image
redis.password""--requirepass and the URL password (Secret); required when bundled
redis.resourcesrequests 100m / 128Mi, limits 200m / 512MiContainer resources
redis.maxmemory400mb--maxmemory; keep near 80% of the memory limit
redis.persistence.enabledtruePVC for the append-only file
redis.persistence.size1GiPVC size
redis.persistence.storageClass""StorageClass
redis.persistence.accessModeReadWriteOncePVC access mode
redis.external.url""redis://:PASSWORD@host:6379 when enabled: false (Secret)
clickhouse.enabledtrueBundled ClickHouse
clickhouse.imageclickhouse/clickhouse-server:24.8Image
clickhouse.dboblethCLICKHOUSE_DB and OBLETH_CLICKHOUSE_DB
clickhouse.useroblethCLICKHOUSE_USER and OBLETH_CLICKHOUSE_USER
clickhouse.password""OBLETH_CLICKHOUSE_PASSWORD (Secret); required when bundled
clickhouse.resourcesrequests 500m / 2Gi, limits 1 / 4GiContainer resources
clickhouse.systemLogRetentionDays7Days of the bundled ClickHouse's own system log tables kept (query_log, part_log, metric_log, text_log and the rest); at least 1
clickhouse.logLevelinformationClickHouse server log level; text_log keeps warnings and errors only
clickhouse.persistence.enabledtruePVC
clickhouse.persistence.size20GiPVC size
clickhouse.persistence.storageClass""StorageClass
clickhouse.persistence.accessModeReadWriteOncePVC access mode
clickhouse.external.url""http://host:8123 when enabled: false

The bundled Redis runs with the append-only file on, a password, and --maxmemory-policy volatile-lru: only keys with a TTL are evicted. API keys, model routes, MCP servers and committed term-budget usage have none and stay. When nothing is left to evict, Redis refuses writes, which the gateway treats as a Redis failure (see obleth.failOpen). An external Redis must be a single primary; Redis Cluster is not supported. Redis is rebuilt from Postgres after data loss. See Redis layout.

Dashboard, provisioner and sidecars

ValueDefaultWhat it sets
controlPlane.enabledtrueDashboard Deployment and Service (port 3000)
controlPlane.replicas1Dashboard pods
controlPlane.dashboardPassword""DASHBOARD_PASSWORD: break-glass admin password, at least 8 characters
controlPlane.dashboardSessionSecret""DASHBOARD_SESSION_SECRET and BETTER_AUTH_SECRET, at least 32 characters
controlPlane.existingSecret""Pre-created dashboard Secret
controlPlane.databaseUrl""DATABASE_URL; empty is the bundled Postgres URL
controlPlane.betterAuthUrl""BETTER_AUTH_URL: the browser-facing dashboard URL, used for SSO redirects
controlPlane.trustedOrigins""TRUSTED_ORIGINS: extra sign-in origins, comma-separated
controlPlane.dashboardAdminEmailadmin@example.comDASHBOARD_ADMIN_EMAIL: break-glass admin email
controlPlane.oidcProviders""OIDC_PROVIDERS: JSON array of SSO providers (Dashboard SSO)
controlPlane.resourcesrequests 100m / 256Mi, limits 1 / 512MiContainer resources
provisioner.enabledfalseSlurm provisioner Deployment
provisioner.intervalSecs15OBLETH_PROVISIONER_INTERVAL_SECS: reconcile interval
provisioner.restartAfterFailures20OBLETH_PROVISIONER_RESTART_AFTER_FAILURES: net failed probes before a restart; 0 off
provisioner.logLevelinfo,obleth_provisioner=debugRUST_LOG
provisioner.resourcesrequests 50m / 64Mi, limits 500m / 256MiContainer resources
compressor.enabledfalseCompression sidecar and OBLETH_COMPRESSOR_URL on the gateway
compressor.replicas1Sidecar pods; ignored when autoscaling
compressor.numThreads4COMPRESSOR_NUM_THREADS and OMP_NUM_THREADS; keep equal to the CPU limit
compressor.image.repositoryghcr.io/thediymaker/obleth-gateway/obleth-compressorImage
compressor.image.tag""Tag; empty follows image.tag, else v2.4.0
compressor.image.pullPolicy""Pull policy; empty follows image.pullPolicy
compressor.resourcesrequests 4 / 1536Mi, limits 4 / 2GiContainer resources
compressor.autoscaling.enabledfalseCPU HorizontalPodAutoscaler for the sidecar
compressor.autoscaling.minReplicas1HPA minimum
compressor.autoscaling.maxReplicas5HPA maximum
compressor.autoscaling.targetCPUUtilizationPercentage70HPA CPU target
benchmarkBackend.enabledtrueSynthetic backend; turn off in production
benchmarkBackend.ttftMs20BENCHMARK_BACKEND_TTFT_MS
benchmarkBackend.tokenMs3BENCHMARK_BACKEND_TOKEN_MS
benchmarkBackend.concurrency256BENCHMARK_BACKEND_CONCURRENCY

The dashboard and provisioner get OBLETH_ADMIN_BASE_URL (http://<release>-obleth:9180) and read OBLETH_ADMIN_TOKEN from the gateway Secret; the dashboard also gets OBLETH_PROXY_BASE_URL (:8080). The provisioner only deploys the reconciler; its Slurm connection is set in the dashboard (Slurm provisioning). The compressor holds about 900 MB of model per pod and one inference saturates near four cores, so scale it with replicas, not bigger pods. The gateway works without it.

Ingress

ValueDefaultWhat it sets
ingress.enabledfalseIngress to the gateway Service
ingress.className""ingressClassName
ingress.hostobleth.example.comRule host, path /
ingress.servicePort8080Backend port; keep the data plane, never 9180
ingress.annotations{}Ingress annotations
ingress.tls[]TLS blocks, such as [{ secretName: obleth-tls, hosts: [obleth.example.com] }]

The chart does not deploy HAProxy.

Security contexts (Pod Security Standard)

ValueDefaultWhat it sets
podSecurityContextrunAsNonRoot: true, seccompProfile: RuntimeDefaultPod security context
securityContextallowPrivilegeEscalation: false, drop ALL, runAsNonRoot: trueContainer security context; readOnlyRootFilesystem is opt-in
networkPolicy.enabledfalseNetworkPolicies below; needs a CNI that enforces them

Both contexts apply to the gateway, dashboard, provisioner, compressor and benchmark backend, and meet the Kubernetes restricted standard. No UID is pinned (gateway runs as 10001, dashboard as 1000). The bundled datastores are left out because their images manage their own users.

With networkPolicy.enabled, ingress is limited to:

TargetAllowed from
Bundled Postgres 5432Gateway; dashboard when controlPlane.enabled
Bundled Redis 6379Gateway
Bundled ClickHouse 8123, 9000Gateway
Gateway 8080 (data plane)Any source
Gateway 9091 (metrics)Any source
Gateway 9180 (Management API)Dashboard and provisioner, when enabled

Minimal production values

obleth:
  existingSecret: obleth-secrets        # keys listed above
  upstreamBaseUrl: "http://inference.inference.svc.cluster.local:8000/v1"
  replicas: 2

postgres:
  enabled: false
redis:
  enabled: false
clickhouse:
  enabled: false
  external:
    url: "http://clickhouse.example.internal:8123"

benchmarkBackend:
  enabled: false

controlPlane:
  existingSecret: obleth-control-plane  # dashboard keys listed above

serviceMonitor:
  enabled: true

ingress:
  enabled: true
  className: nginx
  host: obleth.example.com
  tls:
    - secretName: obleth-tls
      hosts: [obleth.example.com]

With external datastores, the Postgres and Redis URLs come from the Secret, so postgres.external.url and redis.external.url can stay empty.

Fixed pod settings

These are set in the templates, not by values.

PodSetting
GatewayterminationGracePeriodSeconds: 345; preStop sleep 5
GatewayStartup probe GET /health on proxy, every 5 s, 30 failures (about 150 s)
GatewayReadiness GET /health, delay 5 s, every 5 s; liveness delay 10 s, every 10 s
GatewayemptyDir volume wal at /var/lib/obleth for spilled telemetry; survives container restarts, not pod deletion
GatewayService ports proxy 8080, admin 9180, metrics 9091
GatewayUses the chart's ServiceAccount only when capacity discovery RBAC is rendered
DashboardReadiness GET /login, delay 5 s, every 10 s; liveness delay 15 s, every 20 s
DashboardHOSTNAME=0.0.0.0, so it listens on all interfaces and kubectl port-forward reaches it
ProvisionerOne replica, Recreate, terminationGracePeriodSeconds: 60, no probes, no Service
CompressorReadiness GET /health, delay 30 s, every 10 s; liveness delay 60 s, every 30 s
PostgresReadiness pg_isready; PGDATA in a subdirectory of the volume
RedisReadiness redis-cli -a "$REDIS_PASSWORD" ping
ClickHouseReadiness GET /ping on 8123; CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1
ClickHouseConfigMap <release>-clickhouse-config in config.d: system log tables partitioned by day, with the retention above; the pod rolls when it changes