ZZettarack
KBXKubernetes cluster · in testing · beta

Every pod on one screen.

A Kubernetes cluster in one box. Install it on a machine and it builds the cluster on its own hypervisor: three control planes and three workers, each a virtual machine of its own, from images it carries, with nothing downloaded.

Every pod, its containers and its logs on the box's own screen, and the traffic between them: Cilium is the network, Hubble shows each flow, Tetragon watches each process, and every volume is a ZFS dataset.

And it is the same appliance as the other two: a signed, read-only system that updates as a whole and goes back by itself if an update fails.

Where it stands
A pod as a card in the fly-through: metallb-frr-k8s-v69mq, running on lab-w-3, its five containers stacked on it (controller, frr, reloader, frr-metrics and frr-status), 5 of 5 ready, with its neighbours' stacks either side
capture · every pod a card, its containers stacked on it
01 · one boxA cluster, built by itself

Answer the installer's cluster page. The first boot clones the nodes from a node image the appliance carries, joins them, and reads every step back before the next.

02 · offlineNothing to download

Kubernetes and every add-on come inside the appliance, each image by its digest, counted on every node. On the bench, the nodes sent no packet past the box while the cluster was built.

03 · upgradesYou can't brick it with an upgrade

Each release is a signed image, booted as a new environment beside the old one. If the box or its cluster doesn't come up healthy, it goes back by itself.

The lock screen: the Constellation scene, stars joined by faint lines over a nebula, with the machine's name, kbx, and the password field
the lock, Constellation
stop 1 · the ideaone box, one cluster

A cluster in one box

Kubernetes runs programs in containers spread over several computers, its nodes, and keeps them running: when a container stops, it starts it again, and when a node goes, it moves the work to the others. Control planes decide what runs where; workers run it.

kbx makes those computers for you, as virtual machines on the box's own hypervisor: three control planes and three workers to start, and more of either with one click. Each node is a Zettarack system of its own, cloned from one sealed image.

Your workloads
in containers
Kubernetes
six machines
The box
vmx, on ZFS
kbx tui on its Cluster tab: the cluster lab, 3 control planes and 6 workers, ready, and each node's role, address, mesh address and state, with what Kubernetes says of it: Ready, every one
capture · kbx tui, the cluster: nine nodes and what Kubernetes says of each
stop 2 · first bootbuilt by itself

From the installer to a cluster

The installer has a page for the cluster: how many control planes and workers, how big each is, and its addresses, with a 3x3 starter that fills them in. At the first boot kbx builds it as one job you can follow in the Jobs window, each phase read back before the next starts.

  1. PreflightRefuses before anything is touched: the hypervisor answers, the box has the memory, the node image and the stack are what they claim.
  2. The goldenThe node network, then the node image the appliance carries, installed once into a machine and sealed as a template.
  3. The nodesEach a clone of the golden with its seed, started and found ready: its agent, cloud-init done, containerd running.
  4. The meshWireGuard between every pair of nodes, every handshake read back.
  5. The first control planeIts API at the cluster's own address, read back through it.
  6. The joinsEvery worker, then every other control plane, through that address.
  7. The add-onsCilium until every node is Ready, kube-vip, MetalLB and its pool, metrics-server, the ZFS volume driver, Tetragon and its policies.
  8. ReadyCoreDNS up and the API answering at its address: then, and only then, the record says ready.

A node that does not come up fails the job, and the job removes what it made. The record is written as the build goes, so a build that stopped says what it left.

See it firstkbx cluster build --dry-runEvery step and why, and nothing touched.
More, at oncekbx cluster scale --workers 4Workers any number; control planes to the next odd count, so etcd keeps a majority.
kbx tui following a job: the demo pack rolled out in twelve steps, its image imported on each of the nine nodes and its manifests applied, then read back: every deployment available, an address given from the pool, and the page answering at http://10.250.0.200:80/
capture · a job and its log: a pack rolled out, then read back
stop 3 · flythe pods

Fly through your pods

Tap Super and every pod in the cluster is a card, its containers stacked on it like sheets of paper, the frontmost with its image and whether it is ready. Super+Tab lays the namespaces out as a wall, each with its pods stacked, the ones that are not well on top. Enter goes into a namespace, and into a pod; Escape comes back out.

Superevery podSuper+Tabthe namespacesEntergo inTabwhat a card holdsEscback
The namespaces wall: demo, healthy, 3 pods and 3 containers, and kube-system, healthy, 76 pods and 132 containers, each with its pods stacked on it
capture · the namespaces wall, each namespace's pods stacked

The cards are asked of kbxd every five seconds while the view is open. A read that fails says so over the last good one, and never empties the wall.

stop 4 · readlogs

A pod's log, and why it ended

The Pods window and the console list every pod with its node, its state, its containers ready, its restarts and what it uses, and what is wrong with it in a few words. In the console, open one for each container's state and how its last run ended, with the reason and the exit code, then the last lines of its log, and what it wrote before its last restart.

Deleting a pod is how a pod is restarted: what owns it makes it again, and the job says which it was.

What is not wholekbx pods --unhealthyA container not running, or fewer ready than there are.
Why it restartedkbx pods logs kube-system \ metallb-frr-k8s-7cttf --previousWhat each container wrote before its last restart.
A restart, planned firstkbx pods delete demo \ whoami-6d6dc4d9b8-cqfxz --dry-runThe plan, and nothing touched.
The Pods window: 79 pods, every one running; a Cilium agent chosen, its container ready with 4 restarts, and the last lines of its log
capture · a pod, its container, and the last lines of its log
stop 5 · watchflows

Every flow, the dropped first

Cilium is the cluster's network: eBPF programs in each node's kernel, in place of kube-proxy. Hubble records the flows through it: who spoke to whom, on which port, and whether it was forwarded or dropped. The Flows window shows the last thousand, the dropped ones first with Hubble's reason, and the counts by verdict above them.

capture to come · the Flows window, the dropped ones first
Only the droppedkbx flows --droppedEach with its two ends, its port, and Hubble's reason.
One namespacekbx flows --namespace default \ --last 20The flows with an end in it, newest first.
stop 6 · the wirestwo networks

Two networks, each for one thing

What people reach is on the nodes' own network: the cluster's API at one address that kube-vip holds on whichever control plane leads, and each service of type LoadBalancer at an address from MetalLB's pool. That network is a private one the box makes for itself, or your LAN with the addresses you give it.

What the nodes say to each other goes over a WireGuard mesh: the kubelets, etcd and the API all speak there, each node's key made on that node and never leaving it, and pods on different nodes reach each other through Cilium's VXLAN tunnel inside it.

The nodes' network
what you reach
WireGuard
node to node
Cilium
pod to pod

The Network window shows each node's Cilium agent: its state, its reach to the other nodes, how a packet crosses to another node, the pod addresses it has handed out, and what is wrong in a few words, the agents with something wrong first.

The Network window: 9 Cilium agents, 9 whole; a row a node: Ok, Cilium 1.20.4, kube-proxy replacement, a vxlan tunnel, encryption, and the flows it has seen
capture · the Network window, an agent a node
stop 7 · trustsecurity

Every process, on every node

Tetragon watches each node's kernel through eBPF: every program a workload starts and every one that ends, and whatever its tracing policies ask after. Two come with the cluster: every write to the files that say who may log in, in a pod or on a node, and every zfs, zpool and zdb that anything but the kubelet runs on a node.

The Security window lists the last thousand events, a policy's first, each with the pod or the host it ran in, the node, the program and its arguments, and what the hook saw. On the bench, a shell in a pod appending to its own /etc/passwd was reported; the read just before it was not.

The Security window: 696 Tetragon events, 4 exec, 1 exit and 691 by a tracing policy, each with its time, node, policy, pod, binary and the whole command it ran
capture · the Security window, Tetragon's events
What a policy caughtkbx security --policyThe tracing policies' events, newest first.
One namespacekbx security --namespace default \ --last 20Every program started and ended there.
stop 8 · the machinesnodes

Nodes are machines, a click away

The Nodes menu has a row for each node: its state, its roles and its share of CPU and memory, with cordon, uncordon and drain as its buttons. Drain moves a node's pods to the others before you work on it; a pod on a ZFS volume, which lives on its node, waits for it to come back. Add a worker, or two control planes so etcd keeps an odd count: one click, and it starts at once.

When the box restarts, the control planes start first and the workers once the API answers, so the workers' pods start with an API to reach.

The Nodes menu: the nine nodes, each ready, with its cordon, uncordon and drain buttons, then Add a worker and Add two control planes
capture · the Nodes menu, cordon, uncordon and drain on each row
Before you work on onekbx nodes drain lab-w-1 --dry-runThe plan; without --dry-run, the drain.
Back to workkbx nodes uncordon lab-w-1Pods may be scheduled on it again.
stop 9 · carriedthe stack

Everything it runs, carried

The cluster is built from a lock: Kubernetes and every add-on at an exact version, every image by its digest, twenty-eight in all, carried inside the appliance and put on every node. A node missing one of them fails its health check. Nothing comes from a registry at the build, so a box with no internet builds the same cluster.

KubernetesetcdCoreDNSCiliumHubble TetragonMetalLBkube-vipmetrics-serverZFS volume driverGateway API

Every volume is a ZFS dataset on its node's pool, by one of two storage classes: zfs, the default, and zfs-db for a database: 16K records, synchronous writes logged for latency, lz4, no access times.

kbx tui on its Stack tab: Kubernetes 1.37.1, 28 images, 4 charts, 2 manifests and 7 add-ons, each image by its sha256 digest
capture · kbx tui, the stack: each image by its digest
stop 10 · proofready

Ready means every check

The cluster is ready when its checks say so, not when its build ends:

NodesEvery node Ready, none under pressure.
etcdAs many members as control planes, every one healthy, no alarm raised.
The APIReady through the cluster's own address.
CiliumA whole agent on every node.
The imagesThe stack's on every node.
The meshEvery pair of nodes handshaking.
The poolMetalLB holding the addresses declared.
DNSA pod that schedules and resolves the API's name.
CertificatesEvery control plane's more than 30 days from their end.

And every pack it rolled out, whole and answering. A check that cannot run counts as failed, never as passed. Each is shown red by its own fault in the tests, and on the bench moving the pool and stopping CoreDNS turned theirs red. An upgrade of the box is judged by them too, once the cluster has had time to settle.

The Health window, every check ok: the API, 40 certificates on 3 control planes, 9 Cilium agents whole, etcd's 3 members, 28 images on each of 9 nodes, the mesh's 36 pairs, 9 of 9 nodes Ready, the demo pack answering, the address pool and 15 of 15 workloads available
capture · the Health window, the cluster's checks
stop 11 · deploypacks

Your workload, carried in

A pack is a workload with every image it needs inside it. One rollout proves the pack whole, puts each image into every node that lacks it from the pack itself, applies its manifests, and reads it back: every deployment available, its service given an address from the pool, and that address answering.

The first pack comes in the image: a small page that says which pod answered it, so each refresh shows the load balancer at work. On the bench it rolled out in six seconds, its image into all six nodes, nothing pulled. Your own packs, built on a workstation and signed with your key, are next.

What it carrieskbx packEach pack, its images, its namespace, and where it answers.
Out, and provenkbx pack rollout demoPrinting where it answers once it does.
kbx tui on its Packs tab: 1 pack carried, 1 rolled out: demo, answering at http://10.250.0.200:80/
capture · kbx tui, the packs, and where each answers
stop 12 · in testingwhere it stands

Where it stands

kbx is in testing, on the beta line only: its installer is below. Every picture on this page is from the bench, a cluster of three control planes and six workers on one box. The installer runs from memory before it installs, so it needs a machine with about 8 GiB of memory or more; on less it stops and says how much.

What one box cannot do, said plainly: three control planes on one box survive a node failing, a control plane being replaced, and a bad deploy. They do not survive the box itself. That is the appliance's own job, with its boot environments; a cluster across two boxes comes later.

Still to come:

Snapshots of the clusterEvery node's disks at one moment, and rollback to it.
Backups, and the drilletcd snapshots on a schedule, sent to a zxp, and a restore that reads them back.
Upgrades node by nodeEach node drained and booted into a new boot environment, kept when healthy and sent back when not.
Your own packsBuilt on your workstation, signed with your key, received at the install or after.
Nodes on bare metalThe same node image, put on a machine of its own by bootmass.

Download

x86-64 · UEFI · one file for a USB stick or a disc · installs with no network

Beta · kernel 7.2 · OpenZFS 2.4 · the new line, proven on the bench first; kbx has no LTS

kbx 0.2.15 · 3.6 GB

Verify

It comes with beta's SHA256SUMS, its signature and the release key.

beta sha256 582cd94fbd2f1dc6a45338500505f3f13a7045a9fcd7338c0661061489f1d43c

vmx

The hypervisor kbx is built on: many computers in one box, every machine on one screen. Downloadable today.

vmx →

zxp

The storage server: every pool on one screen. Downloadable today.

zxp →
zettarack.com · website designed by North Star