02

From Laptop Hardware to a Local Kind Platform

Turn one laptop into a disposable Kubernetes analogue and prove both healthy scheduling and bounded recovery.

Run it in the public monorepo

This course is built around the public Zheta Kubernetes Lab monorepo. The excerpt below is runnable source, not pseudocode.

Source: compose.yaml

control-plane:
    build: { context: ., dockerfile: services/Dockerfile, args: { SERVICE: control_plane } }
    environment: { ENVIRONMENT: local, GENERATOR_URL: "http://generator:8080", RUNTIME_URL: "http://runtime:8080", EVIDENCE_URL: "http://evidence:8080", SERVICE_TOKEN: "local-service-token-32-characters-minimum", JWT_SECRET: "local-jwt-secret-32-characters-minimum", CONTROL_DATABASE_URL: "sqlite:////data/control.db", ARTIFACT_DATABASE_URL: "sqlite:////data/artifacts.db", BROKER_TOPIC: "http://broker:8080" }
    volumes: ["control-data:/data"]
    ports: ["8080:8080"]
    depends_on: [generator, runtime, evidence, broker]

Code to reality

Declared intent
Run six explicit local responsibilities: web, control plane, generator, runtime, broker, and evidence.
Interpreter
Docker Compose resolves the service graph, builds images, creates networks and volumes, and starts containers.
Software effect
The control plane calls generator and runtime, then its outbox publishes to the broker for the independently progressing evidence subscriber.
Hardware effect
Six containers and four persistent volumes consume laptop CPU, memory, storage, and network namespaces.
Observable evidence
docker compose ps proves web, control-plane, generator, runtime, broker, and evidence processes; restart queries prove four durable volumes.

Start with the people and the result they need

The source tables below remain the detailed contract. Begin with these customer paths:

  • D02-UC-01
    • Person: Platform developer
    • Job: Run the Zheta Forge control-plane shell locally before paying for cloud capacity
    • Observable result: A pod is scheduled, becomes Ready, and answers a customer probe
  • D02-UC-02
    • Person: Platform reviewer
    • Job: Distinguish a multi-node simulation from physical failure-domain isolation
    • Observable result: Layer map identifies shared laptop CPU, RAM, disk, and network

Turn each customer job into a testable story

Now turn each customer job into a story with a result that an engineer can check:

  • D02-US-01
    • Story: As a platform developer, I want a disposable local cluster, so that I can observe scheduling and reconciliation before AWS
    • Observable acceptance: Node, pod, event, replacement UID, and HTTP evidence share one run ID
  • D02-US-02
    • Story: As a platform reviewer, I want the simulation limits stated beside its AWS mapping, so that local success is not mistaken for production resilience
    • Observable acceptance: Every local layer names its EKS counterpart and the shared laptop is recorded as one failure domain

Add real state and observable proof

Finally trace each story through the system that owns its state and the evidence that proves the outcome:

  • D02-FLOW-01
    • Trigger: Developer starts the local Zheta Forge environment
    • Responsible systems: Docker, Kind, Kubernetes API, Deployment controller, kubelet, Zheta Forge shell
    • Authoritative state: Kubernetes API desired/status state
    • Owned record: LocalCluster
    • Observable evidence: Docker container IDs, Node UIDs, Pod UID, readiness, HTTP body, local environment, timestamp, run ID
    • Failure signal: Pending pod, readiness failure, event, or failed HTTP probe
  • D02-FLOW-02
    • Trigger: Developer deletes the labelled shell pod
    • Responsible systems: Host OS and Docker runtime inspection
    • Authoritative state: Host and Docker runtime inventory
    • Owned record: LocalRecoveryRun
    • Observable evidence: Deleted UID, ReplicaSet event, replacement UID, recovery duration, HTTP result, shared-substrate warning
    • Failure signal: All nodes share one Docker host and physical resource pool

The enterprise problem and today’s slice

Enterprise problem: Teams copy cloud manifests into production without seeing which processes consume CPU, memory, disk, and network, so capacity and failure assumptions remain hidden until customers are affected.

Whole-course context: The incoming platform charter defines three planes and a create-to-retire lifecycle; today supplies a local hosted-runtime boundary for the first implementation slices.

Today’s slice: Create a multi-node Kind cluster, where Kind means Kubernetes nodes running as Docker containers, and map each local layer to its later EKS equivalent.

End-of-day evidence: Cluster, node, namespace, pod, failure, reconciliation, and HTTP probe observations are joined to one immutable lab run.

Still unsolved: Kind nodes share one physical laptop and therefore do not prove infrastructure high availability, cloud identity, managed storage, or production isolation.

Customer use cases

A local cluster is valuable only if it demonstrates the same control relationship as production. These use cases prove scheduling and recovery while refusing a false high-availability claim.

Use case IDActorCustomer jobSuccess outcomeDenial or recovery evidence
D02-UC-01Platform developerRun the Zheta Forge control-plane shell locally before paying for cloud capacityA pod is scheduled, becomes Ready, and answers a customer probeDeleted pod is replaced and the recovered endpoint answers again
D02-UC-02Platform reviewerDistinguish a multi-node simulation from physical failure-domain isolationLayer map identifies shared laptop CPU, RAM, disk, and networkHA claim is denied with the shared-substrate observation while the runtime remains usable

Actor-centred user stories

Cluster status alone cannot establish the customer outcome. These stories require both Kubernetes evidence and an application response.

Story IDUse case IDsUser storyObservable acceptance conditions
D02-US-01D02-UC-01As a platform developer, I want a disposable local cluster, so that I can observe scheduling and reconciliation before AWSNode, pod, event, replacement UID, and HTTP evidence share one run ID
D02-US-02D02-UC-02As a platform reviewer, I want the simulation limits stated beside its AWS mapping, so that local success is not mistaken for production resilienceEvery local layer names its EKS counterpart and the shared laptop is recorded as one failure domain

End-to-end product flows

The local customer action is opening the platform shell, not merely running kubectl. A recovery path deletes only one named disposable pod and watches the Deployment controller replace it.

Flow IDUse case IDsPathTriggerNumbered stepsTerminal evidence
D02-FLOW-01D02-UC-01, D02-UC-02HappyDeveloper starts the local Zheta Forge environment1. Docker supplies node containers.; 2. Kind creates the API and workers.; 3. Kubernetes schedules the shell pod.; 4. Readiness passes.; 5. HTTP probe returns the expected platform identity.Docker container IDs, Node UIDs, Pod UID, readiness, HTTP body, local environment, timestamp, run ID
D02-FLOW-02D02-UC-01, D02-UC-02RecoveryDeveloper deletes the labelled shell pod1. Validate the namespace and label target.; 2. Delete one pod.; 3. Observe desired and actual replicas diverge.; 4. Watch replacement become Ready.; 5. Repeat HTTP probe.Deleted UID, ReplicaSet event, replacement UID, recovery duration, HTTP result, shared-substrate warning

The developer asks for a usable product endpoint. Kubernetes mechanics matter because they must eventually produce this observable action.

System design derived from the flows

Kind can teach orchestration while still misleading learners about hardware. The design therefore keeps the laptop, Docker node containers, Kubernetes controllers, and workload process visible.

Use case IDEntry pointResponsible servicesAuthoritative storeFailure evidence
D02-UC-01Local platform URLDocker, Kind, Kubernetes API, Deployment controller, kubelet, Zheta Forge shellKubernetes API desired/status statePending pod, readiness failure, event, or failed HTTP probe
D02-UC-02Substrate review commandHost OS and Docker runtime inspectionHost and Docker runtime inventoryAll nodes share one Docker host and physical resource pool

The same laptop backs every simulated node. Docker runs node containers, Kubernetes reconciles the shell pod, and the process consumes the laptop's real resources.

Data model and ownership

Deleting a pod must not delete business data because today creates no business database. Kubernetes stores only disposable runtime state and lab evidence records what was observed.

Generated-application database: Not created in this slice — the shell is stateless and Kubernetes plus lab evidence are sufficient to prove scheduling and recovery.

Record or entityStore and ownerPrimary keyForeign key or opaque referenceTenant keyMaterial constraintLifecycle and deletionUse case IDs
LocalClusterKind configuration and Kubernetes API, owned by platform developmentcluster nameDocker container and Node UIDsenvironment=localCluster name and network are disposable and must not reuse cloud credentialsCreated per lab; deleted after evidence captureD02-UC-01, D02-UC-02
LocalRecoveryRun.lab/evidence, owned by the learnerrun_idCluster, deleted Pod, and replacement Pod UIDsenvironment=localExactly one validated target; before and after probes requiredImmutable lab artifact; removable with the disposable labD02-UC-01, D02-UC-02

Kubernetes state explains why a replacement appeared; the probe proves that reconciliation restored a customer-visible outcome.

Run the local evidence loop

An unvalidated delete can target the wrong environment, so the lab creates its isolated kubeconfig through Terraform and uses the repository's validated failure script for mutation. Kind runs Kubernetes nodes as local container processes, so this proves orchestration behavior rather than independent-machine availability (Kind quick start). Read the exact cluster declaration in terraform/main.tf.

resource "kind_cluster" "zheta" {
  name            = var.cluster_name
  wait_for_ready  = true
  kubeconfig_path = local.kubeconfig_path

  kind_config {
    kind        = "Cluster"
    api_version = "kind.x-k8s.io/v1alpha4"

    node {
      role = "control-plane"
    }

    dynamic "node" {
      for_each = range(var.worker_count)

      content {
        role = "worker"
      }
    }
  }
}
Declared intentInterpreterSoftware effectHardware effectEvidence
One Terraform-managed local Kind cluster and repository-local kubeconfigTerraform and the tehcyx/kind provider call Kind, which calls the local container runtimeRecords kind_cluster.zheta, starts node containers, and writes .kube/config; make product-deploy separately applies the local Forge overlayConsumes one laptop's CPU, RAM, disk, power, and container networking; all simulated nodes share those failure domainsterraform state show kind_cluster.zheta, kubectl get nodes, kubectl -n zheta-forge get pods, and the product HTTP smoke run

Decision rules

Use Kind to learn APIs, scheduling, and reconciliation cheaply. Do not use it to claim rack, availability-zone, IAM, load-balancer, or managed-control-plane resilience; those claims require later evidence from isolated AWS accounts and EKS clusters.