====== Docker & Kubernetes vs. "The Nine Unix Philosophy Principles" (Mike Gancarz) ====== Mike Gancarz’s **nine principles** define the **Unix Way**: small, focused, composable, text-driven tools. **Docker** and **Kubernetes** claim to be "modern Unix" but both fail the Unix test **hard**. Let’s evaluate **both** using Gancarz’s principles. ==== 1. **Small is beautiful** ==== > *"Small programs are easier to understand, maintain, and reuse."* | **Docker** | **Kubernetes** | | Single binary: `docker` is a 100MB+ It's Daemon: `dockerd` is written in "Go" (oh yeah, we all learned "Go" right?) and is 200k+ lines of code. It requires root | 50+ microservices Control plane: 10+ binaries Typical cluster: 1000s of YAML lines | | **Fails** | **Fails spectacularly** | **Verdict:** Both are **bloated**. Docker is a fat daemon. Kubernetes is a distributed monolith. ==== 2. **Make each program do one thing well** ==== > "Focus on a single, well-defined task." | **Docker** | **Kubernetes** | | Builds images, Runs containers, Pushes to registry, Manages volumes, Networks, Even `docker compose` | Orchestrates, Networks, Stores, Schedules, Secrets, CI jobs, Service mesh | | **Fails** — does 5+ things | **Fails** — does //everything// | **Verdict:** Neither respects **single responsibility**. ==== 3. Build a prototype as soon as possible ==== > "Fail fast, iterate." | **Docker** | **Kubernetes** | | `docker run nginx` is instant, Fast feedback | 6-month release cycle, 3-month deprecation, Breaking API changes, `kubectl` syntax churn | | **Passes** | **Fails** | **Verdict:** Docker wins on speed. Kubernetes prototypes **in production**. ==== 4. Choose portability over efficiency ==== > "Write once, run anywhere." | **Docker** | **Kubernetes** | | OCI images do run anywhere, but: host kernel matters (cgroups, namespaces) | Same YAML (in theory), But: CSI, CNI, cloud load balancers, node OS | | **Mostly passes** | **Fails in practice** | **Verdict:** Docker is **more portable**. Kubernetes is **cloud-coupled**. ==== 5. **Store data in flat text files** ==== > "Human-readable, grep-able, diff-able." | **Docker** | **Kubernetes** | | `Dockerfile` — text, good, Images → tar layers, Config → JSON in daemon | Everything in **etcd** (not files), `kubectl get -o yaml` gives 300+ lines, No `grep /var/lib/kube/state` | | **Partially passes** | **Fails Miserably** | **Verdict:** Docker has text config. Kubernetes hides state in a database. Didn't we want computers working for us, not the other way around? ==== 6. Use software leverage to your advantage ==== > "Reuse existing tools. Compose." | **Docker** | **Kubernetes** | | Reinvents `tar`, `chroot`, `iptables`, Replaces `rkt`, `lxc` | Reinvents `crontab`, `systemd`, `iptables`, `nginx`, `supervisord` | | **Fails** | **Fails worse** | **Verdict:** Both **replace** Unix tools instead of **composing** them. There really isn't an excuse, either. Just some blank stare and "but it's newer" which shouldn't hold water for anyone with critical thinking skills. ==== 7. **Use shell scripts to increase leverage and portability** ==== > "Glue tools with shell." | **Docker** | **Kubernetes** | | `docker run` in scripts is OK `docker exec` is debug only | `kubectl exec` → not for workflows, >Helm/Kustomize replace shell, Operators in Go (It's a formerly trendy programming language like ADA and it's already fading out) | | **Uhhh, kinda** | **Fails** | **Verdict:** Docker allows shell scripts but doesn't really leverage them. Kubernetes **discourages** it. ==== 8. Avoid captive user interfaces ==== > "Don’t force a GUI. Let the user choose." | **Docker** | **Kubernetes** | | CLI: `docker` GUI: Docker Desktop (optional) | `kubectl` is CLI But: Dashboard, Lens, K9s **needed** for sanity | | **Passes** | **Partially passes** | **Verdict:** Docker CLI is usable. Kubernetes CLI is **unreadable without tools**. ==== 9. Make every program a filter ==== > "Take input, produce output. Chain them." | **Docker** | **Kubernetes** | | docker logs to text files and mostly respects text but Docker containers cannot use pipes like normal Unix programs. | `kubectl get pods -o json then pipe to jq`
But: no stdin for `apply`, `create` | | **Doesn't fail, exactly, doesn't pass either** | **Fails** | **Verdict:** Docker is **pipe-friendly**. Kubernetes is **API-bound**. ====== Final Scorecard ====== ^ Principle ^ Docker ^ Kubernetes ^ | 1. Small is beautiful | No (100MB daemon) | No (50+ services) | | 2. One thing well | No (build+run+net+vol) | No (does everything) | | 3. Prototype fast | Yes (`docker run`) | No (6-month cycles) | | 4. Portability > efficiency | Warning (kernel-dependent) | No (cloud-coupled) | | 5. Flat text files | Warning (Dockerfile yes, state no) | No (etcd) | | 6. Reuse tools | No (reinvents) | No (reinvents more) | | 7. Shell scripts | Warning (possible) | No (discouraged) | | 8. Avoid captive UIs | Yes (CLI first) | Warning (CLI unusable alone) | | 9. Be a filter | Kinda (pipeable mostly) | No (not stdin/stdout) | **Docker: 3/9** **Kubernetes: 0/9** I'm just going to have to ask... What is really gained here over more traditional solutions or even better, Unixy solutions? ====== Conclusion: Both Are "Anti-Unix" ====== > **Docker** is a **fat, root-requiring, daemon-heavy** tool that **mostly fails** Unix principles. > **Kubernetes** is a **distributed, YAML-bloated, shell-hostile, API-locked** platform that **fails every principle** They are **not Unix tools**. They are **web-era, cloud-native, enterprise-grade abstractions** built for **scale, not simplicity or good engineering**.