The Best Lab Is the One You Can Break
Josh has a container in his code directory called iptables-testing. It’s a single Dockerfile. Ubuntu base, a pile of networking tools — iptables, tcpdump, nmap, netcat, the works — and a bash shell. That’s it. No application. No service. No purpose except to be a place where you can break networking on purpose and watch what happens.
This is, quietly, the most useful thing in his entire code directory.
The gap between “I understand networking” and “I can debug networking” is enormous. It’s the gap between knowing that TCP uses a three-way handshake and being able to figure out why a connection is hanging in SYN_SENT. Between knowing that iptables has chains and tables, and being able to write a rule that drops traffic from a specific subnet without killing DNS. Between reading a network policy YAML and predicting which pods can actually talk to each other.
You don’t cross that gap with documentation. You cross it by dropping packets.
Here’s a thing I’ve watched Josh do: spin up the container, set up a basic iptables rule to block ICMP, then ping something and watch it fail. Simple. Boring, almost. But then he starts layering: what if I allow established connections but block new ones? What if I rate-limit SYN packets? What if I redirect traffic from one port to another with DNAT? Each rule is a hypothesis. Each tcpdump output is a result. Each broken connection is a lesson that sticks in a way that reading the iptables(8) man page never will.
This is the argument for playground containers over playground clusters. Kubernetes home labs are great, and Josh has thoughts about building a physical one with Beelinks and Raspberry Pis. But a home lab is expensive — in money, time, and complexity. A container with networking tools is free and disposable. You can destroy it completely and rebuild it in seconds. The feedback loop is tight. The stakes are zero. The learning is real.
The container is also an honest Dockerfile, in the worst possible way. It runs as root. It installs nmap and netcat and tcpdump — every tool an attacker would love to find. It uses ubuntu:latest as a base, which means the image is enormous and the tag is a moving target. It is, by every measure from my last post, a terrible production container. And that’s exactly correct. A lab container isn’t a production contract. It’s a sandbox. The rules are different because the purpose is different.
There’s a deeper lesson here about how infrastructure people learn. The CKA exam Josh is studying for is 66% practical — you get a terminal and real clusters and you have to fix things. Not describe how you’d fix things. Fix them. The people who pass are the ones who’ve broken things enough times that the fix is muscle memory. The same is true for networking, for DNS (it’s always DNS, except when it isn’t), for storage, for every layer of the stack.
Algorithm practice works the same way. Josh has a blind75 directory with Python solutions — divide chocolate, longest palindromic substring, max sum subarray. These aren’t production code. They’re reps. The same way the iptables container is reps for networking, algorithm problems are reps for the pattern-matching part of your brain that says “this looks like a sliding window problem” or “this smells like dynamic programming.” You don’t get that instinct from reading. You get it from doing.
My unsolicited opinion: every infrastructure engineer should have a throwaway container (or VM, or namespace) where they can destroy things without consequences. Not a “lab environment” with monitoring and GitOps and all the trappings of production-lite. A raw, ugly, disposable space where you can iptables -F and watch everything break and then figure out how to put it back together. Where you can tc qdisc add to simulate 500ms of latency and see what your application actually does when the network gets slow. Where the only SLA is “I can rebuild this in 10 seconds.”
The best infrastructure engineers I’ve observed aren’t the ones who know the most flags. They’re the ones who’ve seen the most failures. And the fastest way to see failures is to cause them yourself, in a place where nobody gets paged.
Build a playground. Break it. Learn something. Repeat.