Sprintsail Runtime target
The sprintsail-runtime target deploys to a Kubernetes cluster running the Sprintsail Runtime operator stack: Knative, CloudNativePG, MinIO, RabbitMQ Cluster Operator, sealed-secrets, Contour, and cert-manager. All open source. No vendor lock-in.
You can run this on:
- A local kind cluster (development, free).
- A single-EC2 K3s instance (POC, ~$30–60/mo).
- Production-grade EKS / GKE / AKS with the operator stack installed.
Target string format:
sprintsail-runtime:<kubeconfig-context>
If the locator is omitted, the kubeconfig's current-context is used.
Setup
Sprintsail uses your local kubeconfig (KUBECONFIG env var or ~/.kube/config). Whatever works for kubectl --context <name> get nodes works for sail.
To stand up the operator stack on a fresh cluster, run the bootstrap installer.
Operator bootstrap
A single repeatable script installs everything the provider expects. From the SDK repo:
git clone https://github.com/Oriondigitalplatforms/odp-site.git
cd odp-site/sprintsail/runtime-bootstrap
./install.sh <kubectl-context>
Pinned versions, idempotent. Installs:
- cert-manager + a self-signed
sail-issuerClusterIssuer - sealed-secrets controller
- Contour ingress (with single-node reconciliation — Envoy owns the node's 80/443)
- CloudNativePG operator
- RabbitMQ Cluster Operator
- MinIO (helm, standalone)
- Knative Serving + Kourier
What it provisions
| Primitive | Kubernetes object | Namespace |
|---|---|---|
| Function | serving.knative.dev/v1 Service | sail-<project> |
| Worker | apps/v1 Deployment (1 replica) running runWorkerLoop | sail-<project> |
| CronJob | batch/v1 CronJob | sail-<project> |
| WebApp | Deployment + Service + Ingress (Contour) | sail-<project> |
| API | Deployment + Service + Ingress (Contour) running the API-gateway shim | sail-<project> |
| Database | postgresql.cnpg.io/v1 Cluster | sail-<project> |
| Bucket | namespaced bucket inside MinIO (minio ns) | minio |
| Queue | rabbitmq.com/v1beta1 RabbitmqCluster | sail-<project> |
| Secret | bitnami.com/v1alpha1 SealedSecret → Secret | sail-<project> |
State file: .sail/state.sprintsail-runtime.<context>.json.
Image distribution
The SDK builds container images locally and has to get them onto the cluster's nodes.
| Mode | When | How |
|---|---|---|
kind load | kubeconfig context starts with kind- | kind load docker-image <ref> --name <cluster>. No registry needed. |
| Registry push | SAIL_IMAGE_REGISTRY env var set | docker push <registry>/sprintsail/<project>-<name>:<tag>. Cluster pulls from registry. Works on any cluster. |
For ECR specifically:
SAIL_IMAGE_REGISTRY=<account>.dkr.ecr.us-east-1.amazonaws.com \
sail deploy --target sprintsail-runtime:my-cluster --yes
The K3s node needs ECR pull credentials. See sprintsail/runtime-bootstrap/refresh-ecr-auth.sh — it writes /etc/rancher/k3s/registries.yaml with a fresh token + restarts K3s. ECR tokens expire every 12h; production-quality fix is an IAM instance profile + the kubelet credential provider (v1.1).
Ingress
The WebApp/API Ingress hostname defaults to <project>-<name>.sail.localhost. For real clusters:
SAIL_INGRESS_DOMAIN=runtime.example.com sail deploy --target sprintsail-runtime:prod --yes
# -> Ingress host: orders-web.runtime.example.com
Wildcard DNS + a real cert-manager issuer (Let's Encrypt) finishes the picture. For quick POCs, point the SDK at sslip.io:
SAIL_INGRESS_DOMAIN=<node-ip-with-dashes>.sslip.io sail deploy --target sprintsail-runtime:poc --yes
# e.g. 35-175-205-158.sslip.io -> resolves to the node IP automatically
TLS
cert-manager + the sail-issuer ClusterIssuer (installed by the bootstrap) means every WebApp/API Ingress gets a certificate automatically. The default issuer is self-signed (curl -k for tests); swap it for an ACME issuer on real clusters.
Single-node vs. multi-node
The bootstrap detects single-node mode (SINGLE_NODE=true, the default) and demotes Envoy's LoadBalancer Service to ClusterIP so Envoy owns the node's host-ports 80/443 directly. On multi-node managed K8s with a real cloud load-balancer, run with SINGLE_NODE=false.
Cost (POC sizing on EC2)
Real-cluster numbers from the live POC:
- 1×
t3.largeEC2 (8 GB RAM, enough for the full operator stack + a small workload): ~$0.083/hr, ~$60/mo if 24/7. - ~$3–4/mo stopped (EBS only). Start when needed.
What's stable, what isn't
All 9 primitives are alpha on the Sprintsail Runtime in v1.0 — end-to-end verified on kind during development plus the live AWS→runtime POC on a real K3s/EC2. Path to stable is hardening on real-cluster scenarios (HA Postgres, multi-replica RabbitMQ, multi-node MinIO, KEDA scaling for workers, IAM-based ECR auth).