Skip to content

Reference Architecture

This page sketches a recommended reference architecture for running real workloads with KSail: a thin local cluster for development and a full production cluster, driven from one repository with one workflow. It’s a generic blueprint — adapt the pieces to your needs. Everything here is built from KSail-native features introduced elsewhere in these docs.

one Git repository
┌───────────────────────────────────────────────┐
│ ksail.yaml ksail.prod.yaml │
│ (local) (production) │
│ │ │ │
│ k8s/ ── bases/ ─ providers/ ─ clusters/ ─┐ │
└────────┼────────────────────────────────────┼──┘
▼ ▼
┌──────────────────┐ ┌────────────────────────┐
│ Local cluster │ │ Production cluster │
│ Talos + Docker │ │ Talos + Hetzner │
│ thin: core only │ │ full: + autoscaling, │
│ │ │ HA, cloud LB & storage │
└──────────────────┘ └────────────────────────┘

Both clusters run the same distribution (Talos) so local development has high fidelity to production — only the provider and the depth of installed components differ.

# ksail.yaml — local: thin test-bed on Docker
spec:
cluster:
distribution: Talos
provider: Docker
gitOpsEngine: Flux
controlPlanes: 1
workers: 1
distributionConfig: talos-local # modular Talos patches for local
workload:
sourceDirectory: k8s
kustomizationFile: clusters/local
# ksail.prod.yaml — production: full cluster on Hetzner
spec:
cluster:
distribution: Talos
provider: Hetzner
gitOpsEngine: Flux
controlPlanes: 3
workers: 3
distributionConfig: talos # modular Talos patches for prod
autoscaler:
node:
enabled: true
maxNodesTotal: 10
pools:
- { name: autoscale, serverType: cx33, min: 0, max: 4 }
localRegistry:
registry: "user:${GHCR_TOKEN}@ghcr.io/org/platform/manifests"
workload:
sourceDirectory: k8s
kustomizationFile: clusters/prod

Every operation targets an environment by config — there is no separate “prod CLI”:

Terminal window
ksail cluster create # local
ksail --config ksail.prod.yaml cluster create # production
ConcernHow it’s doneLearn more
Repository layoutLayered bases/providers/clusters/Project Structure
Deliveryworkload push (OCI artifact) → workload reconcileDeliver with GitOps
Per-environment targeting--config ksail.prod.yamlMulti-Environment
Node configurationModular Talos patches via distributionConfigTalos
Secrets at restSOPS-encrypted *.enc.yaml, key per environmentSecret Management
Credentials in config${VAR} expansion keeps configs Git-safeConfiguration
Scaling productionautoscaler.node poolsCluster Provisioning
CI gateworkload validate + workload scan, offlineCI/CD Integration

A typical pipeline keeps two concerns separate so an unreachable node can never block application delivery:

  1. On every pull request — validate and security-scan both environments, no cluster required:

    Terminal window
    ksail workload validate
    ksail --config ksail.prod.yaml workload validate
    ksail --config ksail.prod.yaml workload scan --compliance-threshold 85
  2. On merge — deliver manifests first, then reconcile:

    Terminal window
    ksail --config ksail.prod.yaml workload push
    ksail --config ksail.prod.yaml workload reconcile
  3. When node configuration changes — sync it last:

    Terminal window
    ksail --config ksail.prod.yaml cluster update
  • High fidelity — same distribution locally and in production; bugs surface early.
  • One source of truth — every environment is a thin overlay on shared bases.
  • Credential-free Git — secrets are SOPS-encrypted; tokens arrive via ${VAR} expansion.
  • Fail-safe delivery — manifests ship independently of node configuration.
  • Confidence before deploy — validation and security scanning gate every change, offline.