Kubernetes Deployment Guide¶
Trussium includes a Kustomize base and a production overlay for Kubernetes. The production deployment runs between two and ten hardened replicas behind a ClusterIP Service on port 9000 and uses the release image pinned in the overlay.
The independently versioned official
trussium Helm chart packages
the same production contract. Use Helm when values-driven configuration and
Helm-managed install, upgrade, rollback, and uninstall lifecycles are desired.
Use the maintained Kustomize overlay when direct rendered-manifest ownership or
overlay composition is preferred. The chart deploys the runtime only and does
not install the future Trussium Operator.
Resources¶
The maintained production overlay renders:
- A dedicated
trussium-systemNamespace. - A ServiceAccount without API token automounting and with a private-registry pull-secret reference.
- A ConfigMap for non-secret runtime settings.
- A Deployment with rolling updates and topology spreading.
- A ClusterIP Service on port 9000.
- A PodDisruptionBudget allowing at most one unavailable replica.
- An
autoscaling/v2HorizontalPodAutoscaler maintaining two to ten replicas against the named runtime container's CPU utilization.
Provider credentials are deliberately excluded. The Deployment optionally
loads a trussium-provider Secret when one exists.
Prerequisites¶
- A Kubernetes cluster with
policy/v1PodDisruptionBudget andautoscaling/v2HorizontalPodAutoscaler support. - A working Kubernetes Metrics API, commonly provided by Metrics Server.
kubectlwith integrated Kustomize support.- Permission to create Namespace, workload, Service, ConfigMap, Secret, PodDisruptionBudget, and HorizontalPodAutoscaler resources.
- Access to
ghcr.io/trussiumhq/trussium.
The Trussium GHCR package is private. Create a classic GitHub personal access
token with read:packages, then create the referenced registry Secret. Do not
place the token in the repository or shell history.
kubectl apply -f deploy/kubernetes/base/namespace.yaml
kubectl create secret docker-registry ghcr-credentials \
--namespace trussium-system \
--docker-server ghcr.io \
--docker-username YOUR_GITHUB_USERNAME \
--docker-password YOUR_GITHUB_TOKEN
If the package becomes public, remove imagePullSecrets from the
ServiceAccount or keep the Secret for authenticated pulls.
Provider configuration¶
The ConfigMap contains safe production defaults:
- Production environment selection.
- Port 9000 and all-interface binding.
- A 30-second graceful-shutdown drain deadline.
- Provider-request and stream-idle deadlines.
- Dependency-aware readiness disabled by default with one-second refresh and ten-second cache settings available for explicit enablement.
- Prometheus-compatible runtime metrics enabled at
/metrics. - OpenTelemetry tracing disabled until a collector endpoint is configured.
Create provider configuration through Kubernetes Secret management. For OpenAI:
kubectl create secret generic trussium-provider \
--namespace trussium-system \
--from-literal=TRUSSIUM_PROVIDER__NAME=openai \
--from-literal=TRUSSIUM_PROVIDER__API_KEY=YOUR_PROVIDER_CREDENTIAL
For Ollama or another reachable compatible endpoint:
kubectl create secret generic trussium-provider \
--namespace trussium-system \
--from-literal=TRUSSIUM_PROVIDER__NAME=ollama \
--from-literal=TRUSSIUM_PROVIDER__BASE_URL=http://ollama.ollama.svc:11434/v1
The checked-in deploy/kubernetes/secret.example.yaml documents the expected
keys, but must not be applied until its placeholder is replaced. External
Secrets, Sealed Secrets, or a cloud secret-store CSI driver can create the same
trussium-provider Secret without changing the Deployment.
Health endpoints remain available when the optional provider Secret is absent.
Pods then emit the bounded provider.configuration.unavailable warning while
continuing to serve health and metrics endpoints. Collect standard output as
JSON; the Structured Operational Logging Guide
documents stable events and privacy boundaries.
To gate pod readiness on provider metadata access, patch the non-secret ConfigMap after ensuring the provider Secret and network path are available:
data:
TRUSSIUM_READINESS__DEPENDENCY_CHECKS_ENABLED: "true"
TRUSSIUM_READINESS__DEPENDENCY_TIMEOUT_SECONDS: "1"
TRUSSIUM_READINESS__DEPENDENCY_CACHE_SECONDS: "10"
TRUSSIUM_READINESS__REQUIRED_MODEL: "deployment-required-model"
The required model is optional. Keep the runtime deadline below the readiness-probe timeout. Enabling dependency checks while the optional Secret is absent intentionally returns HTTP 503; liveness remains HTTP 200. See the Runtime Health and Dependency Readiness Guide before rollout.
To export traces, patch the non-secret ConfigMap values in a deployment-owned overlay. The endpoint must be reachable from the pod and normally targets an OpenTelemetry Collector Service:
data:
TRUSSIUM_OBSERVABILITY__TRACING_ENABLED: "true"
TRUSSIUM_OBSERVABILITY__TRACING_SERVICE_NAME: "trussium"
TRUSSIUM_OBSERVABILITY__TRACING_SAMPLE_RATIO: "0.1"
TRUSSIUM_OBSERVABILITY__OTLP_TRACES_ENDPOINT: "http://otel-collector.observability.svc:4318/v1/traces"
Trussium does not install a collector. See the OpenTelemetry Tracing Guide for sampling, privacy, lifecycle, outbound provider propagation, and downstream receiver boundaries.
The repository also provides portable Grafana dashboard JSON for an existing
Prometheus, Loki, and Tempo stack. Neither Kustomize nor Helm installs Grafana,
those backends, dashboard custom resources, a ServiceMonitor, or log and
trace collectors. See the Runtime Dashboards Guide for
collection contracts and operator-owned import or provisioning.
Portable Prometheus starter rules are also maintained outside Kustomize and
Helm. Trussium installs no PrometheusRule, Alertmanager configuration,
notification route, or receiver. Operators may adapt the standard rule groups
to their monitoring stack after reviewing reference thresholds and runbooks in
the Runtime Alerting and Runbook Guide.
Deploy with Helm¶
After creating the namespace, image-pull Secret, and any provider Secret above, authenticate to GHCR and install chart v1.2.0:
helm registry login ghcr.io --username YOUR_GITHUB_USERNAME
helm install trussium \
oci://ghcr.io/trussiumhq/charts/trussium \
--version 1.2.0 \
--namespace trussium-system \
--wait
Chart v1.2.0 defaults to runtime v1.22.0. Chart and runtime versions are
independent; the chart's appVersion records its default compatible runtime.
The chart enables the same two-to-ten-replica CPU HPA and runtime metrics
contract by default, so a working Kubernetes Metrics API is required. It also
renders the runtime's tracing enablement, service identity, sampling ratio,
OTLP HTTP/protobuf endpoint, and export timeout while leaving tracing disabled
by default. The chart does not install a collector or tracing backend. Use fixed
replicas when the Metrics API is intentionally unavailable:
helm install trussium \
oci://ghcr.io/trussiumhq/charts/trussium \
--version 1.2.0 \
--namespace trussium-system \
--set autoscaling.enabled=false \
--set replicaCount=2 \
--wait
The chart repository documents every value, existing Secret integration, customization, upgrades, rollbacks, removal, and release compatibility.
The runtime's application-scoped capability registry and read-only
GET /v1/capabilities discovery endpoint require no Kubernetes resource,
value, environment variable, port, probe, permission, or lifecycle change.
Discovery uses the existing runtime Service and exposes no provider, model,
implementation, health, availability, or configuration data.
The informational GET /v1/capabilities/availability endpoint also uses the
existing Service. It adds no probe, resource, port, permission, or operator and
does not affect pod readiness. Its per-check deadline can be configured with
TRUSSIUM_RUNTIME__CAPABILITY_AVAILABILITY_TIMEOUT_SECONDS; the official Helm
chart exposes the corresponding typed value.
The application-owned capability execution pipeline uses the same in-process
sealed registry and requires no Kubernetes resource, value, environment
variable, port, probe, permission, or lifecycle change. The Kind smoke test
invokes the installed pipeline with public ordered middleware inside the
runtime pod. Middleware composition is application-owned and adds no chart or
Kustomize setting.
The remaining sections describe the maintained Kustomize path. Do not manage the same runtime release with both Helm and Kustomize.
Validate and deploy¶
With a reachable cluster selected in the current context, render and perform Kubernetes client-side schema validation before applying:
scripts/kubernetes-validate.sh
kubectl diff -k deploy/kubernetes/overlays/production
kubectl apply -k deploy/kubernetes/overlays/production
Wait for the zero-unavailable rollout:
Inspect the deployed resources:
kubectl get all,poddisruptionbudget,horizontalpodautoscaler \
--namespace trussium-system \
--selector app.kubernetes.io/name=trussium
Test the internal Service from a local workstation:
In another terminal:
curl http://127.0.0.1:9000/health/live
curl http://127.0.0.1:9000/health/ready
curl http://127.0.0.1:9000/health/components
curl http://127.0.0.1:9000/metrics
Customize safely¶
Do not edit the maintained base directly for a deployment-specific change.
Create another overlay that references deploy/kubernetes/base or copy the
production overlay into deployment configuration you control.
Common customizations include:
- Updating
images[].newTagto an immutable released version. - Patching the ConfigMap with provider name or base URL settings that are not secret.
- Adjusting resource requests and limits from measured usage.
- Changing autoscaling bounds, CPU target, resource requests, and topology rules to match measured demand and cluster size.
- Referencing an organization-managed registry or provider Secret.
- Enabling OTLP trace export to an organization-managed collector.
Horizontal autoscaling¶
The maintained production overlay uses an autoscaling/v2
HorizontalPodAutoscaler with these conservative defaults:
- Minimum
2and maximum10replicas. - Average CPU utilization target of
70%for the namedtrussiumcontainer. - At most a 100% or four-pod increase per 60 seconds, selecting the larger permitted scale-up.
- A 300-second scale-down stabilization window.
- At most a 25% or one-pod decrease per 60 seconds, selecting the smaller permitted scale-down.
The CPU target is calculated relative to the container's CPU request, so keep that request representative of observed steady-state use. Metrics Server (or another resource Metrics API implementation) supplies this standard metric; Trussium does not install it.
Inspect current status and events:
kubectl get horizontalpodautoscaler/trussium \
--namespace trussium-system
kubectl describe horizontalpodautoscaler/trussium \
--namespace trussium-system
Do not declare spec.replicas in a production Deployment patch managed by the
autoscaler. Reapplying a conflicting replica count can cause unnecessary
scaling churn. Patch the HorizontalPodAutoscaler's bounds or omit it in a
deployment-owned overlay when fixed manual scaling is required.
The /metrics endpoint additionally exposes
trussium_http_requests_active, which remains accurate for active SSE streams.
It is not used by the default HPA. A deployment-owned Prometheus Adapter rule
can publish that gauge to Kubernetes Custom Metrics API without changing the
bounded metric-label contract. See the Runtime Metrics Guide.
Health, security, and shutdown¶
The startup probe gates liveness and readiness until the runtime starts. The readiness probe removes unavailable pods from Service endpoints, while the liveness probe restarts unhealthy processes.
Pods use the image's numeric user and group 10001:10001, RuntimeDefault
seccomp, a read-only root filesystem, no privilege escalation, and no Linux
capabilities. The Deployment does not mount a service-account token.
Kubernetes allows 36 seconds for termination: the default 30-second active-work
drain, Trussium's one-second cancellation cleanup allowance, and the recommended
five-second operational margin. If
TRUSSIUM_RUNTIME__GRACEFUL_SHUTDOWN_SECONDS changes, update
terminationGracePeriodSeconds to remain at least six seconds longer.
Upgrade and rollback¶
Semantic release updates the maintained production overlay's image tag at each release. For deployment-owned overlays, set the immutable target version, review the diff, and apply it:
kubectl diff -k deploy/kubernetes/overlays/production
kubectl apply -k deploy/kubernetes/overlays/production
kubectl rollout status --namespace trussium-system deployment/trussium
Inspect rollout history and return to the preceding Deployment revision when needed:
kubectl rollout history --namespace trussium-system deployment/trussium
kubectl rollout undo --namespace trussium-system deployment/trussium
kubectl rollout status --namespace trussium-system deployment/trussium
Reconcile the overlay's pinned tag after an emergency rollback so the declared configuration matches the running revision.
Local cluster smoke test¶
The complete smoke test builds the local image, creates or reuses a Kind cluster, loads the image, installs a pinned Metrics Server, applies the rendered production resources, waits for both replicas, verifies that the autoscaler is active against live CPU metrics, checks security and disruption settings, and exercises liveness, readiness, runtime metrics, and request correlation through the Service.
Set TRUSSIUM_KIND_CLUSTER to reuse an existing Kind cluster. A cluster created
by the script is deleted automatically; a reused cluster is preserved.
Remove¶
Delete the managed Namespace and all namespaced Trussium resources:
The operation is destructive for every resource placed in that Namespace.