Skip to main content

Concepts

Runtime profiles

k3d, kind and incluster — and the contract a profile must satisfy.

docs/runtime-profiles.md
On this page

A runtime profile is how SnowOps Labs provisions the Kubernetes cluster a lab runs on. v2 ships three, and only three (cloud runtimes were cut — see ADR-0001):

Profile What it is Use it for
k3d k3s in Docker, multi-node, ports mapped to localhost The default. Fast local laptop cluster; the whole demo loop.
kind Kubernetes in Docker CI and cross-checking; the nightly e2e job runs here.
incluster No cluster of its own — targets the cluster labctl already runs in Team/server mode, where SnowOps Labs is deployed into a cluster.

Select a profile with PROFILE=<name> (env or .env), e.g. make init PROFILE=kind or labctl --project-dir . runtime up after setting PROFILE.


The profile contract

Each profile is a directory runtimes/<name>/ containing exactly:

File Required Contract
up.sh yes Provision the cluster. Idempotent: if the cluster already exists, skip creation and exit 0. Must select the kube-context on success.
down.sh yes Tear the cluster down. Idempotent no-op when the cluster is already absent (exit 0, delete nothing).
runtime.env yes Profile-specific defaults, KEY=value lines, read by labctl and the platform scripts.

internal/runtime discovers a profile by the presence of up.sh; a directory without it is not a runtime. up.sh/down.sh are run through the executor from the project root and receive configuration through the environment (golden rule 3) — they must not source .env themselves.

Script guarantees (verified by test/shell/runtime_lifecycle.bats)

  • up.sh skips creation when the cluster exists (refute cluster-create on a second run) and creates it when absent.
  • down.sh is a clean no-op when the cluster is already gone (refute cluster-delete) — so re-running teardown, or tearing down a lab that never came up, never errors.

runtime.env keys

Every profile defines the same keys so downstream scripts can rely on them:

Key k3d kind incluster Meaning
INGRESS_CLASS traefik nginx traefik Ingress controller the platform installs and routes through.
STORAGE_CLASS local-path standard standard Default StorageClass for PVCs.
DOMAIN_SUFFIX k3d.local kind.local cluster.local Host suffix for ingress routes; content templates read {{.DomainSuffix}}.
REGISTRY_TYPE k3d-import kind-load none How locally-built app images reach the cluster.

A new profile is added by creating runtimes/<name>/ with these three files and honouring the guarantees above — no Go change is needed (golden rule 2).


Teardown ordering & safety

make teardown runs, in order: destroy apps → platform downruntime down. For k3d/kind, runtime down deletes the whole cluster, so it is the real backstop — every platform uninstall.sh bounds its kubectl delete namespace with --timeout so a namespace stuck Terminating can never block teardown before the cluster deletion runs (guarded by test/shell/platform_uninstall.bats). For incluster there is no cluster to delete — runtime down is a deliberate no-op — so platform down is the actual teardown and must remove what it installed.

The incident field notes

One real Kubernetes failure a week — the symptom, the commands that found it, and the fix. Written from actual lab runs, not from memory.

You'll get the Kubernetes Incident Response Field Guide, plus occasional emails about new scenarios, posts and paid offerings such as courses and workshops. Unsubscribe any time.