Whole orchestrator, 5 nginx pods
PSS, 1 GiB arm64 VM
24.6MiB
litek8s serves the real Kubernetes API, so kubectl, Helm and Argo CD work unchanged. The control plane, scheduler, controllers, DNS, service proxy and node agent are one Rust process. For local development, home labs and the edge.
brew install jairoFernandez/tap/litek8sdev up to node Ready: 1.28 s on macOS, 0.17 s on Linux. bench/RESULTS.md
Works with the tools you already use
One process does what a Kubernetes distribution splits across etcd, the API server, the controller manager, the scheduler, CoreDNS, kube-proxy, the kubelet and containerd, plus a Docker-compatible API and a metrics, logs and alerts stack.
Against k3s, kind and k3d. Every row links to the file with the setup, raw data and caveats. Shorter is better.
PSS, 1 GiB arm64 VM
24.6MiB
orchestrator memory
90MiB
dev up to node Ready, Linuxlocal dev cluster
0.17s
dev up to node Ready, macOSlocal dev cluster
1.28s
local dev cluster
47MiB
vs kube-prometheus-stack + Loki
+1.8MiB
kubectl, CRDs, workloads, networking, 47 Helm charts
119/ 119
k3s: 119/119 · compat/RESULTS.md
The 6 conformance failures: 5 are macOS-only (TCP DNS on port 53, a hostPort binding) and pass on Linux; 1 was a watch fixed since. A 3-server HA control plane stays linearizable under leader kills and partitions, and a 3-node cluster ran 21 h under churn with no leak. bench/HA.md, bench/SOAK.md.
kind, k3d or minikube without Docker. As many clusters as you like, each with as many nodes, in one rootless sandbox on Linux or one small Virtualization.framework VM on macOS that grows its memory on demand. NodePorts on localhost, your home directory mounted at the same path.
Read more: Dev clusters$ litek8s dev up --name ci --nodes 3 $ litek8s dev load myapp:dev # a local image $ litek8s dev list # state, API port, nodes, memory $ litek8s dev down # objects and images are kept
docker, docker compose, docker build, Dev Containers and Testcontainers run on the dev cluster, next to (not instead of) Docker or OrbStack. Compose projects can get CPU and memory budgets.
Read more: Docker Engine API$ export DOCKER_HOST=unix://$HOME/.litek8s/docker.sock $ docker compose up -d --build $ docker run --rm -it alpine sh # the same cluster, the same images $ kubectl get pods -A
litek8s ui: cluster state, a k9s-style Kubernetes view, containers by compose project with logs and shells, images, volumes, disk cleanup. Keyboard-driven, works over SSH.
Read more: Terminal UIAn embedded time-series store with a Prometheus-compatible API (Grafana works), log search across every pod and node, alert rules to a webhook, ntfy or Telegram, and kubectl top without metrics-server.
Read more: Built-in observability$ litek8s logs -l app=web --since 1h --grep ERROR $ litek8s query 'topk(5, sum by (pod) (rate(container_cpu_usage_seconds_total[5m])))' $ litek8s alerts $ kubectl top pods -A --containers
litek8s apiserver on a box; more machines join with a k3s-style token that pins the CA. Pods talk across nodes over a WireGuard mesh litek8s sets up itself, and run on crun directly: no containerd, no pause containers.
Read more: Real servers and nodes# the server; prints the join command $ curl -fsSL https://raw.githubusercontent.com/jairoFernandez/litek8s/main/install.sh | sh -s -- server # every other machine $ curl -fsSL …/install.sh | sh -s -- agent --join https://192.168.1.10:6443 --token K10<hash>::<secret>
3 or 5 API servers share the store through Raft, no etcd. Any one server can die without losing writes; litek8s lb gives kubectl one address in front of all three.
Read more: HA control plane$ install.sh | sh -s -- server --cluster-init $ install.sh | sh -s -- server --server https://<first>:6443 --token <token> $ litek8s lb --listen 127.0.0.1:6443 --server http://192.168.1.10:6443
litek8s mcp is an MCP server (dev clusters, objects, pod diagnosis, logs, PromQL, alerts) with guardrails: destructive tools need confirmation, a read-only mode, output limits. litek8s skill installs an agent skill.
Read more: For LLM agents$ claude mcp add litek8s -- litek8s mcp $ claude mcp add litek8s-ro -- litek8s mcp --read-only $ litek8s skill --install ~/.claude/skills
OpenAPI schema validation, CEL rules type-checked and cost-estimated at CRD create, ratcheting, and server-side apply with managedFields, conflicts and pruning, like a Kubernetes 1.33 API server.
Read more: CRDs done properlyx-kubernetes-validations: - rule: "self.replicas <= self.maxReplicas" message: "replicas must not exceed maxReplicas" # a typo is rejected when the CRD is created: ERROR: <input>:1:5: undefined field 'replica'
kubectl, Helm and Argo CD reach the Kubernetes API server on :6443; docker and compose reach the Docker Engine API on docker.sock. Both sit in one process with the object store, the controllers and scheduler, DNS and the service proxy, metrics, logs and alerts, and the node agent, and both run containers on crun.
Read the docsEvery cluster, and every node of a multi-node cluster, runs in one small VM on macOS or one rootless sandbox on Linux, started with the first cluster and stopped with the last. Each cluster gets its own API port, kubectl context and Docker socket.
Read the docsA server runs the whole control plane and its own pods; any Linux machine (a Raspberry Pi, an old laptop, a cheap cloud VM) joins it as a node with the token the server prints. Every node gets a /24 of 10.42.0.0/16; Services and DNS work cluster-wide.
Read the docsThree servers make the control plane highly available: the object store is replicated with Raft, no etcd. Any one server can die without losing writes; nodes fail over to another server, and litek8s lb gives kubectl one address.
Read the docsmacOS (Apple silicon) and Linux (x86_64, aarch64). macOS needs nothing else: no Docker Desktop, no Lima, no sudo.
brew install jairoFernandez/tap/litek8scurl -fsSL https://raw.githubusercontent.com/jairoFernandez/litek8s/main/install.sh | shcargo install litek8slitek8s dev setup checks everything and says what is missing.$ litek8s dev up $ kubectl create deployment web --image=nginx $ kubectl expose deployment web --type=NodePort --port 80 $ curl localhost:$(kubectl get svc web -o jsonpath='{.spec.ports[0].nodePort}') $ litek8s ui # browse it all $ export DOCKER_HOST=unix://$HOME/.litek8s/docker.sock $ docker run --rm hello-world # the same cluster speaks the Docker API $ litek8s dev up --name ci --nodes 3 # another cluster, three nodes $ litek8s dev down # stop; objects and images are kept
On Linux servers. One command per machine, like k3s’s installer: a systemd unit, the token in /etc/litek8s, pods that keep running across restarts and upgrades.
Multi-node and HA| dev clusters | server / node | release binary | |
|---|---|---|---|
| macOS, Apple silicon (13+) | yes, in a VM (Virtualization.framework) | for development only (Docker runtime) | darwin-arm64, VM guest included |
| Linux x86_64 / aarch64, rootless | yes, user-namespace sandbox (kernel ≥ 5.11, cgroup v2) | – | linux-x86_64, linux-aarch64 (static) |
| Linux, root with crun | yes | yes: the intended server and node setup | same |
| macOS Intel, Windows | no (WSL2 untested) | no | – |
Tested on Ubuntu 24.04 (arm64 and x86_64) and recent macOS on Apple silicon. Ubuntu ≥ 23.10 needs sudo litek8s dev setup once.
Early preview, built and tested by one person: expect rough edges.
Every API client is admin. Dev clusters listen on 127.0.0.1 only; on a server, keep port 6443 (and the Raft port, 6444) behind a firewall or VPN. Node join and HA peers are authenticated by the join token.
APIs, flags and on-disk formats may change between 0.x releases without migration.
No Unhealthy/BackOff events; a memory emptyDir is one tmpfs per container mount; ValidatingAdmissionPolicy and webhook matchConditions are accepted but not enforced.
Containers, nodes and cluster state are covered; application /metrics endpoints are not scraped.
A Virtualization.framework limit; litek8s keeps the guest small instead.
They use Docker for pods; run real servers and nodes on Linux.
Free and open source, Apache-2.0. Feedback and issues are very welcome.
brew install jairoFernandez/tap/litek8s