- Persistent Storage – configuring the metrics-collector PV and, optionally, an external TimescaleDB.
- Credentials – how to supply and rotate the credentials Thoras uses.
- Private Container Registry – pulling images from your own registry, including air-gapped installs.
Installing the Thoras license
Thoras will provide you a license key which should be made available to your installation. You have two options for managing this value:- Pass the value into the Helm release via
$.Values.imageCredentials.password, or - Reference an existing secret
Option 1: Pass license in as Helm chart value
Pass the content of your license key file to$.Values.imageCredentials.password in your helm release
Reference an existing secret
If you’d prefer to reference a pre-existing secret object instead of passing values into your helm release, this option is for you! Ensure a secret of typedocker-registry exists in the thoras namespace and
that it’s structured correctly:
- An example of how to create the secret manually:
- In the helm values file, reference this secret by setting
.Values.imageCredentials.secretRef: "thoras-license".
Confirm license installed successfully
You can confirm the license has been installed successfully if the pods in thethoras namespace come up into Running status after one or two minutes. Pod
error statuses such as ImagePullBackOff might indicate an issue.
Forecast worker capacity
Thoras runs a pool of forecast workers that produce predictions for your enrolled workloads. By default the chart runs a built-in scaler that grows the pool automatically as you enroll moreAIScaleTargets, so most installs need no
configuration here.
How the built-in scaler works
- Scaler settings live under
thorasForecast.worker.scaler:minReplicas: 1: the floor.maxReplicas: 100: the ceiling.astsPerReplica: 67: the target ratio. The scaler adds a worker replica for roughly every 67AIScaleTargets.interval: "1m": how often the scaler reconciles.
thorasForecast.worker.replicasis intentionally unset by default so the scaler is in charge.
thorasForecast.worker.replicas to an explicit number disables the
built-in scaler and pins the pool at that size. Use this only if you
specifically want a static count (for example, to match a capacity plan or work
around a scaler issue):
Configuring Webhook Namespace Exclusions
By default, Thoras webhooks exclude thekube-system and kube-node-lease
namespaces. You can customize which namespaces are excluded, or disable
exclusions entirely, using the thorasOperator.webhooks.namespaceSelector Helm
value.
Default Behavior
Out of the box, Thoras excludes system namespaces from webhook enforcement:Customizing Excluded Namespaces
To exclude additional namespaces (e.g. a monitoring namespace), extend thevalues list:
Disabling Namespace Exclusions
If you use an admission enforcer such as OPA Gatekeeper that manages namespace selection independently, you can disable the default exclusions by setting the selector tonull so the chart omits it entirely:
Webhook TLS with cert-manager
By default the chart provisions its own webhook TLS material via a bundled cert-generator Job. If you already run cert-manager in your cluster, you can hand that job off to cert-manager instead:thoras-tls-certs Secret and
injects the CA bundle into the webhook configurations. The bundled
kube-webhook-certgen Jobs, along with their RBAC and network policy, are
skipped. This is the recommended setting for GitOps tools such as Argo CD and
Flux, and for any helm template based workflow, since Helm hook Jobs are
handled poorly outside of helm install.
The chart uses a long-lived CA (10 years by default) that signs the webhook leaf
cert, so routine leaf renewals don’t rotate the injected CA bundle. Adjust the
CA lifetime via thorasOperator.webhookCertGen.certManager.ca.duration if your
policy requires it.
Scheduling
The chart exposes standard Kubernetes scheduling primitives at both a global level and per-component. Component-specific settings take precedence over global ones. Global (applied to every component and to the chart’s hook Jobs):thorasOperator,
thorasApiServerV2, thorasWorker, thorasForecast, metricsCollector,
thorasDashboard, thorasConfigController) as affinity, priorityClassName,
and topologySpreadConstraints. Each component also has a useGlobalAffinity
switch (default true) that controls whether the global affinity block is
merged in on top of the component’s own.
NetworkPolicy
The chart can emit a least-privilege network policy for every Thoras component, in one of two flavors:NetworkPolicy is evaluated after
kube-proxy translates the kubernetes Service address to a real endpoint, so
the kubernetes flavor needs to know the port the API server actually listens
on (networkPolicy.apiServerPorts, default [443, 6443]). Check with
kubectl get endpoints kubernetes -n default and add the port if it’s
non-standard. Minikube, for example, uses 8443. The cilium flavor targets
the API server by identity and ignores this list.
Extending the policies. Each component block accepts extraIngressRules and
extraEgressRules, appended verbatim to the generated policy in either flavor.
OIDC egress. When dashboard OIDC auth is enabled,
the chart opens egress on port 443 from the dashboard pod so the sidecar can
reach your identity provider. Tighten with a layered policy scoped to your IdP’s
hostnames if required.
Egress proxy
If Thoras components must dial an outbound HTTP/HTTPS proxy, for example to reachconsole.thoras.ai for cloud sync, set the standard proxy environment
variables globally:
HTTP_PROXY,
HTTPS_PROXY, and NO_PROXY.
Prometheus scraping
Every Thoras component that emits Prometheus metrics has aprometheus.enabled
toggle (default true) and a fixed prometheus.port. The chart can also emit a
ServiceMonitor for the Prometheus Operator via the serviceMonitor values.
See Monitoring Thoras for the full scraping configuration and
the list of metrics.
