TrussiumRuntime Custom Resource¶
API Identity¶
Group: runtime.trussium.io
Version: v1alpha1
Kind: TrussiumRuntime
Plural: trussiumruntimes
Scope: Namespaced
TrussiumRuntime declares the desired configuration of one Trussium runtime
instance.
The v1alpha1 API is experimental. Backward compatibility will be considered carefully, but changes may occur before a stable API version is released.
Minimal Example¶
apiVersion: runtime.trussium.io/v1alpha1
kind: TrussiumRuntime
metadata:
name: private-ai
namespace: trussium
spec:
image:
repository: ghcr.io/trussiumhq/trussium
tag: v1.22.0
provider:
type: ollama
model: llama3.2
baseURL: http://ollama.ollama.svc.cluster.local:11434/v1
The Kubernetes API server applies these defaults:
podMetadata¶
Optional additional metadata applied to the runtime Pod template.
Example:
podMetadata:
labels:
team: ai-platform
annotations:
example.com/owner: inference
Supported fields:
| Field | Type | Required | Description |
|---|---|---|---|
labels |
map[string]string | No | Additional Pod labels |
annotations |
map[string]string | No | Additional Pod annotations |
Operator-owned labels cannot be overridden.
These reserved labels maintain workload identity, selectors, and ownership.
scheduling¶
Optional Kubernetes scheduling controls for runtime Pods.
Example:
scheduling:
nodeSelector:
workload: ai
tolerations:
- key: workload
operator: Equal
value: ai
effect: NoSchedule
Supported fields:
| Field | Type | Required | Description |
|---|---|---|---|
nodeSelector |
map[string]string | No | Required node labels |
tolerations |
Kubernetes toleration list | No | Supported taint tolerations |
affinity |
Kubernetes Affinity | No | Node, Pod affinity and anti-affinity |
The operator's default topology-spread configuration remains active regardless of these settings.
Specification¶
spec.image¶
Selects the released Trussium runtime container.
| Field | Required | Description |
|---|---|---|
repository |
Yes | Image repository without tag or digest |
tag |
Conditional | Versioned image tag |
digest |
Conditional | SHA-256 image digest |
pullPolicy |
No | Kubernetes image pull policy |
Exactly one of tag or digest must be supplied.
Tag example:
Digest example:
image:
repository: ghcr.io/trussiumhq/trussium
digest: sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Production deployments should prefer immutable release tags or digests.
spec.replicas¶
Defines the desired runtime pod count.
The default is 1.
A replica count of 0 is valid and represents an intentionally scaled-down
runtime.
spec.imagePullSecrets¶
References image registry Secrets in the same namespace:
The operator never stores registry credentials in the custom resource.
spec.provider¶
Selects the provider and model.
| Field | Required | Description |
|---|---|---|
type |
Yes | openai or ollama |
model |
Yes | Provider model identifier |
baseURL |
No | Provider or compatible API endpoint |
credentialsSecretRef |
No | Secret name and key containing credentials |
OpenAI example:
Ollama example:
Credential values must never be embedded directly:
spec.runtime¶
Defines optional overrides for runtime-owned defaults:
runtime:
providerRequestTimeoutSeconds: 60
streamIdleTimeoutSeconds: 30
shutdownDrainTimeoutSeconds: 45
Omitting a field leaves its value under the control of the selected Trussium runtime release.
spec.service¶
Defines the Kubernetes Service:
Supported Service types are:
ClusterIPNodePortLoadBalancer
ExternalName is not supported because TrussiumRuntime Services select
operator-managed runtime pods.
spec.networkPolicy¶
NetworkPolicy is disabled by default, preserving the runtime's existing
network connectivity. Enable it only on clusters whose CNI enforces the
standard Kubernetes NetworkPolicy API.
When enabled, ingress must contain one or more explicit client sources. The
operator creates an owned networking.k8s.io/v1 NetworkPolicy that selects
only the runtime Pods and permits TCP traffic only to the runtime HTTP target
port (9000). Egress remains unrestricted so the runtime can resolve DNS and
contact its configured provider endpoint.
networkPolicy:
enabled: true
ingress:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: clients
podSelector:
matchLabels:
app.kubernetes.io/component: gateway
namespaceSelector is required. podSelector is optional; when omitted, all
Pods in the selected namespaces may reach the runtime. The immutable
kubernetes.io/metadata.name namespace label is the recommended way to select
a named namespace.
spec.autoscaling¶
Autoscaling is disabled by default. When enabled, the operator creates an
owned autoscaling/v2 HorizontalPodAutoscaler that targets the managed
Deployment and uses average CPU utilization.
maxReplicas must be at least minReplicas. The cluster must have a resource
metrics provider, commonly metrics-server, and the runtime container must have
a CPU request. While autoscaling is enabled, the HPA owns the Deployment's
replica count; the operator preserves HPA scale decisions. Disabling
autoscaling removes the HPA and restores spec.replicas as the desired scale.
spec.resources¶
Uses the Kubernetes resource-requirements contract:
Status¶
The controller will populate status in a later milestone:
status:
observedGeneration: 3
readyReplicas: 2
availableReplicas: 2
currentImage: ghcr.io/trussiumhq/trussium:v1.22.0
endpoint: http://private-ai.trussium.svc.cluster.local:9000
conditions:
- type: Ready
status: "True"
reason: RuntimeAvailable
message: All requested runtime replicas are ready
The v1alpha1 status contract contains:
| Field | Description |
|---|---|
observedGeneration |
Most recent generation processed |
readyReplicas |
Ready runtime replicas |
availableReplicas |
Available runtime replicas |
currentImage |
Complete image observed by the controller |
endpoint |
Runtime Service endpoint |
conditions |
Standard Kubernetes conditions |
status.desiredImage¶
Fully rendered image requested by the current spec.image.
Example:
ghcr.io/trussiumhq/trussium:v1.22.0
status.currentImage¶
Image currently configured on the managed Deployment.
status.lastSuccessfulImage¶
Image whose Deployment rollout most recently completed successfully.
This value remains unchanged while an upgrade is progressing or after an upgrade failure.
Upgrading Condition¶
Upgrade lifecycle is represented through:
type: Upgrading
Reasons:
| Reason | Status | Meaning |
|---|---|---|
NoUpgrade |
False |
No image upgrade is active |
UpgradeInProgress |
True |
A previously successful image is transitioning |
UpgradeComplete |
False |
The desired image completed successfully |
UpgradeFailed |
False |
The requested image rollout failed |
Initial provisioning is not classified as an upgrade.
Printer Columns¶
A future controller-populated resource will be displayed as:
Security¶
- Credential values are never custom-resource fields.
- Secret references are namespaced.
- Secret contents must never be written to status or Kubernetes Events.
- An image tag or digest must be explicitly selected.
- The API does not expose arbitrary Pod or Deployment specifications.
- Cross-namespace Secret references are not supported.
Reconciliation¶
This milestone defines only the API contract.
ConfigMap, ServiceAccount, Service, Deployment, and status reconciliation will be introduced through separate issues.
PodDisruptionBudget Reconciliation¶
Each TrussiumRuntime owns one policy/v1 PodDisruptionBudget with the same
name and namespace as the runtime resource.
The controller manages:
- Stable labels
- Runtime selector
maxUnavailable: 1- Controller owner reference
Drift is corrected through normal create-or-update reconciliation.
Deletion of the PodDisruptionBudget triggers reconciliation through the owned
resource watch and the resource is recreated while the TrussiumRuntime
continues to exist.
The PodDisruptionBudget is deleted through Kubernetes owner-reference garbage
collection when the TrussiumRuntime is deleted.
NetworkPolicy Reconciliation¶
When spec.networkPolicy.enabled is true, each TrussiumRuntime owns one
networking.k8s.io/v1 NetworkPolicy with the same name and namespace. The
policy has an ingress-only policyTypes list, stable runtime selector labels,
and one TCP allow rule to the fixed runtime HTTP target port per
spec.networkPolicy.ingress entry.
The controller corrects drift and recreates a deleted policy. Disabling the feature removes the managed NetworkPolicy. Egress is intentionally not isolated in this initial contract.