DebugBox is an open-source Kubernetes diagnostics toolkit: a debugging container image in three size-scoped Alpine variants, 15 MB to 91 MB, the smallest 93% smaller than netshoot. Every variant builds from a digest-pinned base, ships multi-arch for amd64 and arm64, and reaches a registry only after Hadolint linting, in-container smoke tests, and Trivy gating that fails the job on HIGH or CRITICAL. Documented on a versioned MkDocs site, MIT licensed, 22 tags per release.
You need to debug a pod. You run kubectl debug my-pod --image=netshoot and wait for 202 MB to download. On an edge cluster or a metered connection, every megabyte costs time. And you only needed to check DNS. netshoot is all or nothing.
Lite (15 MB): curl, dig, nslookup, netcat, iproute2, iputils, jq, yq, vi. DNS and connectivity.
Balanced (47 MB): adds tcpdump, socat, mtr, openssl, strace, lsof, htop, git, vim, kubectx, kubens. The daily driver.
Power (91 MB): adds tshark, nmap, ngrep, iperf3, ethtool, iftop, iptables, nftables, conntrack-tools, ltrace. Packet analysis and forensics.
Lite is roughly 13x smaller than netshoot. Even Power is 111 MB smaller, a 55% reduction.
kubectl debug my-pod -it --image=ghcr.io/ibtisam-iq/debugbox
kubectl run debug --rm -it --image=ghcr.io/ibtisam-iq/debugbox --restart=Never
docker run -it ghcr.io/ibtisam-iq/debugbox
kubectl run works on any Kubernetes version. kubectl debug requires 1.23 or later.
Not for persistent sidecars, production workloads, or control plane access. It runs as root and is meant for ephemeral debugging only.
json(), yaml() and ll() ship in every variant.
Balanced and Power add ports(), connections(), routes(), k8s-info(), sniff(), sniff-http(), sniff-dns() and cert-check().
Power also adds conntrack-watch().
Dockerfiles stay declarative and installation stays procedural. Package lists live in .packages files, and complex installs such as yq, with architecture detection and SHA256 verification, get dedicated scripts. Every tool version is pinned, and each variant builds from its base by SHA256 digest rather than by tag, so a rebuilt base cannot silently change what ships.
Every commit builds 6 images: 3 variants across 2 architectures, using Docker Buildx and QEMU. Each is loaded into the local Docker daemon. None are pushed.
Then each one has to earn it. Compressed size is measured and printed in the job log, because size is the entire point of this project and a regression should be visible before release rather than in a user's slow pull. A smoke test runs inside the container rather than against it, verifying it works as a runtime: identity resolves, /tmp is writable, procfs is mounted, the network stack answers, core binaries resolve on PATH. Trivy scans with HIGH and CRITICAL set to exit code 1, and the only exceptions are tracked, with reasons, in a committed .trivyignore. Hadolint lints every Dockerfile.
Publishing is a separate workflow, triggered only by a version tag, that scans again before it builds and pushes multi-arch images (amd64 and arm64) to GHCR and Docker Hub with OCI metadata labels injected at build time. Tags come in two forms: floating per variant, and pinned semantic versions for production use.
A registry should be a record of things that already passed, not the place you find out.
The docs started with the same fact written down in too many places. One image's compressed size appeared in 10 separate files, and a runnable pull command in 16. Then the image changed, and correctness depended on finding all of them.
Now every fact has exactly one home and everything else links to it. The tool inventory lives in a single manifest.yaml and renders into one reference page, so adding a tool is a one line change. An entire installation page turned out to be a longer restatement of the quick start, so it stopped existing. That cleanup added 117 lines and removed 474.
Two checks run on every push: a strict docs build that fails on a broken internal reference, and a link checker that crawls every rendered page and fails on dead external URLs.
A hands-on tutorial on iximiuz Labs walks all three variants end to end in a live multi-node Kubernetes playground, no local cluster required.
Published with CONTRIBUTING.md, CODE_OF_CONDUCT.md and SECURITY.md. One command runs the whole quality loop locally: make check does lint, build, test and scan in that order.
Built with