Kubernetes Operator

Spice.ai Kubernetes Operator for automated deployment and lifecycle management.

The Spice.ai Kubernetes Operator automates the deployment, scaling, and lifecycle management of Spice.ai workloads on Kubernetes. It provides two Custom Resource Definitions (CRDs), unified under the spice.ai/v2 API version:

  • SpicepodSet (spice.ai/v2) — Deploys and manages Spicepod replicas as one or more suffixed StatefulSets.
  • SpicepodCluster (spice.ai/v2) — Deploys a distributed query cluster with scheduler and executor nodes, secured with auto-provisioned mTLS certificates.

For a step-by-step walkthrough, see the User Guide. For exhaustive field references, see SpicepodSet and SpicepodCluster.

Installation

Prerequisites

  • Kubernetes 1.33+
  • Helm 3.x
  • AWS CLI (aws) installed and configured with credentials for the account subscribed to the AWS Marketplace listing

The Spice Kubernetes Operator is distributed through the AWS Marketplace Spice.ai Enterprise listing. Subscribe to the listing, then authenticate Helm against the Marketplace ECR registry — the chart is pulled over OCI from that private registry. The chart renders and keeps the CRDs by default (crds.enabled: true, crds.keep: true).

Helm

aws ecr get-login-password --region us-east-1 \
  | helm registry login --username AWS --password-stdin 709825985650.dkr.ecr.us-east-1.amazonaws.com

The login is valid for 12 hours; re-run it when the token expires.

Install the operator:

helm install spiceai-operator \
  oci://709825985650.dkr.ecr.us-east-1.amazonaws.com/spice-ai/spiceai-enterprise-plan \
  --version 1.0.0-operator-helm \
  --namespace spiceai-operator-system --create-namespace

The chart is published to the same Marketplace repository as the operator image, so it is addressed by that repository name and selected by chart version: the chart version is the operator version with an -operator-helm suffix, and the image tag is the operator version with an -operator suffix. Pass the chart version with --version, not as a tag on the oci:// reference.

Docker

docker pull 709825985650.dkr.ecr.us-east-1.amazonaws.com/spice-ai/spiceai-enterprise-plan:1.0.0-operator

Helm Values

ParameterDescriptionDefault
image.repositoryOperator image path (registry + name)…/spice-ai/spiceai-enterprise-plan
image.tagOperator image tag (operator-suffixed chart appVersion)1.0.0-operator
image.pullPolicyOperator image pull policyIfNotPresent
image.pullSecretsImage pull secrets—
crds.enabledRender the bundled CRDs with the charttrue
crds.keepAnnotate CRDs with helm.sh/resource-policy: keep so helm uninstall leaves them (and their custom resources) in placetrue
installCRDsDeprecated — prefer crds.enabled / crds.keep. A boolean here overrides both (true ≡ {enabled: true, keep: true}, false disables CRD rendering). Leave unset to use the crds block.unset
serviceAccount.create / .name / .annotationsOperator ServiceAccount (annotations for IRSA)true / chart name / {}
resourcesCPU/memory requests and limits for the operator—
nodeSelector / tolerations / affinityOperator pod scheduling—
serviceMonitor.enabled / .intervalPrometheus ServiceMonitor for the operatorfalse / 15s
clusterDomainKubernetes cluster domain for internal DNScluster.local
pauseCrashloopingPodsThresholdCrashloop threshold before pausing a SpicepodSet (0 disables)0
admissionPolicyAdmission validation strictness: err | warn | offerr
sidecarInjector.enabledEnable annotation-based sidecar injectiontrue
sidecarInjector.defaultImage / .defaultImagePullPolicyDefaults for injected sidecars(operator default)
namespaces / denyNamespacesScope the operator to / away from specific namespaces (mutually exclusive)(all namespaces)
telemetry.otlp.*Push operator metrics to an OTLP collector (see Operator Metrics)disabled
telemetryPropertiesKey/value pairs forwarded to the Spice runtime as telemetry properties{}

Managed Resources

For each SpicepodSet, the operator creates and manages:

  1. StatefulSet(s) — One per replica (each with an ordinal suffix), managing the pods.
  2. ConfigMap — Stores the spicepod YAML, mounted into the pod.
  3. Service — ClusterIP service exposing fixed ports HTTP (8080), Flight (50051), and metrics (9090), mapped via targetPort to the configured Spiced ports. Disable with service.enabled: false.
  4. NetworkPolicy — Only when network.ingress / network.egress is supplied; rules are written verbatim.
  5. ServiceAccount, Role, RoleBinding — Only when serviceAccount.enabled and serviceAccount.create are both true.

Workload Deployment

Every SpicepodSet is deployed as one or more StatefulSets — one per replica, each with an ordinal suffix — so even single-replica workloads get a stable identity, ordered startup, and predictable DNS, with zero-downtime rollouts. Rolling updates, BlueGreen cutovers, and standby retention are expressed as parallel suffixed StatefulSets. Pre-existing v0.x Deployment-based workloads are reliably grandfathered and continue to reconcile.

Features

FeatureSpicepodSetSpicepodCluster
Workload deployment (suffixed StatefulSets)✓✓
Update strategies (RollingOrdered, RollingParallel, BlueGreen)✓✓
Standby versions & instant rollback (SHA)✓—
Persistent volume with auto-resize✓✓
Zero-replica pausing✓✓
Crashloop protection✓✓
Forced rollouts via annotations/labels✓✓
Network policy management (opt-in)✓✓
Service account configuration (incl. IRSA)✓✓
Health probe customization✓✓
Pod scheduling (affinity, tolerations)✓✓
Admission validation✓✓
Status conditions (Ready, Paused)✓✓
Automatic mTLS certificates—✓
Distributed scheduler/executor topology—✓
Prometheus metrics, ServiceMonitor & OTLP✓✓

Sidecar Injection

The operator can inject a Spice sidecar into any standard Kubernetes Pod by annotating the Pod template with spice.ai/inject: "true" and pointing spice.ai/inject-config at a ConfigMap in the same namespace that holds your spicepod.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: demo-spice-config
data:
  spicepod.yaml: |
    name: demo-sidecar
    kind: Spicepod
    version: v1
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-with-spice
spec:
  replicas: 1
  selector:
    matchLabels: { app: app-with-spice }
  template:
    metadata:
      labels: { app: app-with-spice }
      annotations:
        spice.ai/inject: "true"
        spice.ai/inject-config: demo-spice-config
    spec:
      containers:
        - name: app
          image: nginx:stable

Supported annotations

AnnotationDefaultDescription
spice.ai/inject—"true" / "false" — enable or disable injection for the Pod.
spice.ai/inject-config—ConfigMap holding the spicepod.
spice.ai/inject-config-keyspicepod.yamlKey inside the ConfigMap data.
spice.ai/imageinstall defaultOverride the injected Spice image.
spice.ai/image-pull-policyinstall defaultOverride the injected image pull policy.
spice.ai/http-port18090Sidecar HTTP port.
spice.ai/flight-port15051Sidecar Arrow Flight port.
spice.ai/metrics-port19090Sidecar Prometheus metrics port.

Cluster operators can set defaults globally via Helm values sidecarInjector.defaultImage and sidecarInjector.defaultImagePullPolicy, with per-workload annotations as overrides. The sidecar injector is enabled by default (sidecarInjector.enabled); disable it with --no-sidecar-injector.

Operator CLI

The released operator image ships only the run subcommand. The crd and json-schema subcommands below are development/tooling helpers compiled into debug builds only — they are not present in the standard release binary, and CRDs are installed via the Helm chart rather than crd --apply.

crd — Output or apply CRD definitions

spiceai-operator crd              # Print CRD YAML to stdout
spiceai-operator crd --apply      # Apply CRDs to the current cluster
spiceai-operator crd --output FILE

run — Start the operator controller

FlagDefaultDescription
--health-probe-bind-address0.0.0.0:8090Operator HTTP API / health probe bind address
--metrics-bind-address0.0.0.0:9090Prometheus metrics bind address
--webhook-bind-address0.0.0.0:8443Admission / conversion webhook bind address
--operator-namespacespiceai-operator-systemNamespace for the operator (used for cluster-shared secrets)
--cluster-domaincluster.localKubernetes cluster domain
--admission-policyerrAdmission validation strictness (err | warn | off)
--watch-namespaces(all)Comma-separated namespaces to watch exclusively
--deny-namespaces—Comma-separated namespaces to exclude from watching
--enable-sidecar-injectortrueEnable sidecar injection (--no-sidecar-injector disables)
--pause-crashlooping-pods-threshold10Dead pod observations before pausing (0 disables)
--telemetry-properties KEY=VALUE—Key/value pairs forwarded to the Spice runtime
--verbosefalseEnable debug-level logging

json-schema — Output the OpenAPI v3 JSON schema for the SpicepodSet CRD

spiceai-operator json-schema              # Print to stdout
spiceai-operator json-schema --output FILE

Operator HTTP API

The operator serves an HTTP API on --health-probe-bind-address (0.0.0.0:8090 by default). The standard build exposes only the health and readiness endpoints:

EndpointMethodDescription
/healthGETHealth check — returns OK
/readyGETReadiness probe — 200 once the operator has bootstrapped, 503 otherwise

Pod-status API (deprecated)

EndpointMethodDescription
/{namespace}/{name}GETPod status for a SpicepodSet
/{namespace}/{name}?kind=SpicepodClusterGETPod status for a SpicepodCluster

The pod-status response includes per-pod details (name, UID, phase, IP, port, start time, Spiced health/readiness, and any error reason/message). For paused SpicepodSets (replicas: 0), the response includes paused: true with a pauseReason.

Upgrading

helm upgrade spiceai-operator \
  oci://709825985650.dkr.ecr.us-east-1.amazonaws.com/spice-ai/spiceai-enterprise-plan \
  --version "<target-version>-operator-helm" \
  --namespace spiceai-operator-system \
  --values my-values.yaml

--namespace must match the namespace the release was installed into — helm upgrade otherwise looks in default and reports that no deployed release exists.

v2 is served with automatic conversion of legacy v1 / v1alpha1 resources, so existing manifests continue to apply after the upgrade. See the User Guide for rollout guidance and the per-CRD field changes in SpicepodSet and SpicepodCluster.

Roadmap

Capabilities in active development and planned for the operator include:

  • Leader election for multi-replica operator high availability.
  • Custom API-server TLS with a user-supplied certificate and CA bundle.
  • Log drains to forward Spicepod logs to external sinks (Datadog, Splunk, CloudWatch, …).
  • Audit logging of operator and workload lifecycle events.
  • Cedar policy enforcement distributed to Spicepod pods.
  • Auto-scaling via HorizontalPodAutoscaler and Spiced-specific metrics.
  • Backup & restore of stateful volumes via VolumeSnapshot.
  • Secret rotation with automatic rolling restarts.
  • Spice Cloud Platform integration for centralized fleet management and observability.