What Is picokubelet?
picokubelet is a Rust kubelet by cedi for the ESP32-S3, and picokubelet is one of the best Embedded Kubernetes Node Agents tools for Rust embedded developers and Kubernetes edge operators. It boots bare metal, joins a real k3s API server, and keeps a node Ready with 10-second Lease renewals and 5-minute status patches, which is the kind of hard evidence that matters when you want a microcontroller to behave like a worker node instead of a demo.
The project is built around the idea that Kubernetes state is mostly API traffic, not magic. picokubelet keeps that state honest enough for kubectl while still admitting that pods, exec, logs, and a container runtime are not present yet.
Quick Overview
| Attribute | Details |
|---|---|
| Type | Embedded Kubernetes Node Agents |
| Best For | Rust embedded developers and Kubernetes edge operators |
| Language/Stack | Rust, no_std, embassy, embassy-net, esp-radio, embedded-tls, esp-hal, Kubernetes/k3s |
| License | N/A in scraped page text |
| GitHub Stars | N/A in scraped page text as of Feb 2026 |
| Pricing | Open-Source |
| Last Release | N/A in scraped page text |
Who Should Use picokubelet?
- Rust embedded engineers building
no_stdfirmware who want to experiment with a real control-plane integration instead of a toy HTTP client. - Kubernetes platform engineers who care about node registration, Lease renewal, and
/statusbehavior on constrained hardware. - Edge computing teams validating whether a board can survive Wi-Fi drops, TLS resets, and clock anchoring without losing its place in the cluster.
- Hardware hackers using ESP32-S3 boards, especially the Waveshare ESP32-S3-ETH, who want their board to show up in
kubectl get nodeslike a genuine worker.
Not ideal for:
- Teams needing actual pod execution because picokubelet does not run a CRI, mount volumes, or launch containers.
- Operators expecting Linux semantics because there is no PID namespace, no disk, no shell, and no
kubectl execpath. - Production workloads that require standard kubelet guarantees because picokubelet intentionally fakes parts of the node lifecycle.
Key Features of picokubelet
- Real node registration — picokubelet creates a
NodeviaPOST /api/v1/nodes, advertises capacity, and shows up inkubectl get nodes -owidewith a custom OS image string. The node reportscpu: 240m,memory: 320Ki, andxtensa-lx7, which is exactly the kind of constrained profile you expect from an ESP32-S3. - Lease-based liveness — picokubelet renews
kube-node-lease/<name>every 10 seconds against a 40-second lease duration. That cadence keeps the control plane from timing out the node even when the board is recovering from reconnects. - Status reconciliation with correct transition semantics — picokubelet PATCHes
/api/v1/nodes/<name>/statuson a 5-minute cadence or immediately when a tracked condition flips. It also preserveslastTransitionTimesemantics, so the field only changes when status changes instead of on every heartbeat. - TLS and DHCP on embedded networking — picokubelet brings up Wi-Fi with
esp-radio, gets DHCP throughembassy-net, and speaks TLS to a real k3s API server throughembedded-tls. The board has no RTC, so it anchors wall-clock time from theDateheader on the first/versionresponse. - Condition tracking with real signals — picokubelet drives
MemoryPressurefrom actual heap free bytes and flips it true below 20 KB free. It also exposes custom conditions such asVibes,Caffeinated,Existential,Peckish, andHaunted, which are derived from uptime, reconnects, BSSID changes, and wall-clock skew. - Low-overhead serialization — picokubelet uses typed builders that own their JSON serialization instead of pulling in
serdefor everything. That keeps the payloads short, fixed-shape, and easier to reason about on a small target. - Independent status LED task — picokubelet drives the WS2812 on GPIO 21 through RMT in a dedicated task, so the LED keeps animating even during TLS handshakes or reconnect loops. The LED states are useful because they tell you whether the board is booting, connecting, healthy, or just busy doing node things.
picokubelet vs Alternatives
| Tool | Best For | Key Differentiator | Pricing |
|---|---|---|---|
| picokubelet | ESP32-S3 boards that need to register as Kubernetes nodes | Runs on embedded hardware and speaks enough kubelet API to stay visible to k3s | Open-Source |
| upstream kubelet | Full Linux worker nodes | Real pod lifecycle, CRI integration, volumes, logs, and exec | Open-Source |
| k3s agent | Lightweight Linux workers in k3s clusters | Minimal agent path with mature production behavior on standard OS hosts | Open-Source |
| KubeEdge edgecore | Edge nodes with unreliable network links | Edge/cloud sync model designed for intermittent connectivity | Open-Source |
Pick upstream kubelet when you need the real container lifecycle and you are on Linux, not on an ESP32-S3. Pick k3s agent when you want a normal lightweight worker that behaves like a standard host and you do not need custom embedded behavior.
Pick KubeEdge edgecore when your edge fleet needs an established cloud-edge model with intermittent connectivity baked in. Pick picokubelet when you want the node object, Lease, and status flow without pretending the board can host a full container runtime.
If you are building tooling around this sort of control-plane experiment, djevops is a better fit for cluster automation than hand-rolled scripts, OpenTrace is useful when you want to trace the PATCH cadence and reconnect behavior, and AV Chaos Monkey is the right way to smash Wi-Fi links and TLS sessions on purpose.
How picokubelet Works
picokubelet is structured like a real kubelet syncloop, but stripped down to the parts Kubernetes actually needs to believe a node exists. The firmware boots, starts Wi-Fi via esp-radio, lets embassy-net handle DHCP, and then uses an ApiClient to talk to the Kubernetes API over TLS. The important abstraction is not a container runtime; it is the sequence of API mutations: anchor clock, register node, create Lease, and push status.
The project keeps the Node, Lease, and condition state separate so each resource can be updated on its own cadence. That matters because the Lease is the short heartbeat and /status is the slower truth source, and conflating them makes nodes look flappy in monitoring. picokubelet also updates a node.specht.dev/heap-bytes-free annotation on every status push, which gives you a cheap telemetry channel without inventing a sidecar.
kubectl get nodes -owide
kubectl describe node esp-node-01-guenther
That output shows the node object that picokubelet created, including the custom OS image string, the fake container runtime version, and the condition set exposed through kubectl describe node. When the firmware is healthy, you should see the Lease keep renewing, Ready stay true, and the custom conditions reflect the actual device state instead of a static success flag.
The async design is intentionally boring. picokubelet runs the Lease reconcilers and status reconcilers as separate embassy tasks, shares one ApiClient behind an embassy_sync::Mutex, and keeps the LED responsive with its own task and signal path. That split means a slow network handshake does not freeze the indicator, and a reconnect storm does not stop the node from trying again.
Pros and Cons of picokubelet
Pros:
- Real Kubernetes API interaction — picokubelet does not fake the control plane. It registers a node, maintains a Lease, and PATCHes status against a live k3s server.
- Good failure isolation — Lease renewal and status updates are decoupled, so a transient API failure does not collapse the entire node model.
- Accurate transition tracking —
lastTransitionTimeonly changes when a condition changes, which makes monitoring and debugging much cleaner. - Embedded-first stack —
embassy,embassy-net,esp-radio, andembedded-tlsare a sensible set for Rust firmware that needs async networking. - Low runtime overhead — no
serde-heavy model layer and no CRI plumbing keeps the firmware surface area small. - Useful hardware feedback — the WS2812 patterns and heap annotation give you visibility without needing extra tooling.
Cons:
- No pod execution yet — picokubelet does not watch pods, run containers, mount volumes, or support
kubectl exec. - Wi-Fi is the current production path — the W5500 Ethernet route is on the roadmap, so the hardware story is not complete yet.
- Compile-time configuration — API server address, bearer token, and Wi-Fi credentials are baked in at compile time via
env!, which is convenient for a prototype but awkward for fleets. - False kubelet fields by design —
PIDPressure,DiskPressure, and the container runtime version are not real in the Linux sense. - Board-specific assumptions — the firmware is tuned for the Waveshare ESP32-S3-ETH and similar setups, not for generic SBCs.
Getting Started with picokubelet
Clone the repo, create the firmware environment variables, install the Rust tooling, and build for the ESP32-S3 target. picokubelet expects the k3s API server URL, bearer token, and Wi-Fi credentials at compile time, so the first setup step is preparing .env before you build.
git clone https://github.com/cedi/picokubelet.git
cd picokubelet
# set API server URL, bearer token, Wi-Fi SSID, and Wi-Fi password in .env
mise install
cargo build --release --target xtensa-esp32s3-none-elf
After the build succeeds, flash the firmware with your normal ESP32-S3 workflow and boot the board on the same network as the k3s control plane. Once it connects, watch kubectl get nodes -owide and kubectl describe node <name> to confirm that the Lease, status, and custom conditions are updating.
Verdict
picokubelet is the strongest option for proving Kubernetes node behavior on an ESP32-S3 when you want real API interactions without a real container runtime. Its main strength is honest Lease and status reconciliation over TLS, and its main caveat is that pods are still fake. Use it when you want embedded Kubernetes plumbing, not a full worker node.



