Skip to content

van-sprundel/miniku

Repository files navigation

MiniKu (Mini Kubernetes)

codecov

I wanted to learn a bit more about distributed systems, and after reading more of the 500 lines or less book, I wanted to have a crack at a mini version of K8S.

Architecture

  cmd/apiserver      cmd/scheduler      cmd/controller      cmd/kubelet
  (stores live       (HTTP client)      (HTTP client)       (HTTP client +
   here only)                                                namespace runtime)
       |                  |                   |                   |
       +------ HTTP ------+------- HTTP ------+------- HTTP ------+

All components communicate through the API server over HTTP. cmd/miniku runs everything in a single process for convenience.

Container Runtime

Miniku uses a Linux namespace-based container runtime. This way containers are isolated using kernel namespaces (PID, MNT, UTS) with pivot_root into an Alpine rootfs.

Requires sudo to run (namespace creation needs CAP_SYS_ADMIN).

Note: PodSpec.Image currently maps to Alpine minirootfs regardless of the image name specified.

Starting a ReplicaSet (which in turn starts the desired pods)

> sudo go run ./cmd/miniku/

Then in another terminal

> curl -X POST 127.0.0.1:8080/replicasets -d '{"name":"test","desiredCount":4,"selector":{"app":"test"},"template":{"image":"alpine","command":["/bin/sh","-c","while true; do sleep 1; done"]}}'
{"name":"test","desiredCount":4,"currentCount":0,"selector":{"app":"test"},"template":{"name":"","image":"alpine","command":["/bin/sh","-c","while true; do sleep 1; done"]}}

> curl 127.0.0.1:8080/replicasets
[{"name":"test","desiredCount":4,"currentCount":4,"selector":{"app":"test"},"template":{"name":"","image":"alpine","command":["/bin/sh","-c","while true; do sleep 1; done"]}}]

> curl 127.0.0.1:8080/pods
# pods with status "Running", each with a container ID

Now our binary logs the following:

2026/02/04 15:27:54 scheduler: assigning pod test-d3950207 to node node-2
2026/02/04 15:27:54 scheduler: assigning pod test-3852c037 to node node-2
2026/02/04 15:27:54 scheduler: assigning pod test-50e73e92 to node node-1
2026/02/04 15:27:54 scheduler: assigning pod test-76e8a1ac to node node-1

Very nice!

Core Acceptance

  • API server (expose desired state)
  • kubelet (afaik this is just an agent/worker that lives on a node)
  • controller/manager (reconciliation loops for "uptime guarantees" and all that jazz.)
  • rediscover (on restart, find matching containers and re-assign)
  • scheduler (this will require multiple kubelets)

Core Spec

API

TODO

Kubelet Action

Pod Status Container State Action
Pending doesn't exist Create container, update pod to Running
Pending running Just update pod to Running (recovered?)
Running running Nothing - we're converged
Running exited Update pod to Failed
Running doesn't exist Weird state - maybe re-create or mark Failed
           (heartbeat)
  Kubelet ─────────────>  NodeStore
                              |
                              V
                          NodeController ("is heartbeat stale?")
                              |
                              V
                          NotReady if stale

Disclaimer

This project is purely for my own education. That means no LLM's, which also means it's not going to be production-ready code. The Pod spec is purposefully simple (name, img, state) because I do not need anything else for my goals. Turns out that was a lie

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages