Day 1: The 8GB Budget: Why Your Kubernetes Tutorial Is Lying To You

Lesson 1 15 min

The Bloat Trap: How Standard Tutorials Kill Your Machine

Every Kubernetes tutorial starts the same way:

bash
# "Just run this!"
curl -sfL https://get.k3s.io | sh -
# Or this!
kind create cluster

What they don't tell you: You just allocated unbounded memory to a cluster that will consume every byte your system has. Within 10 minutes of installing Prometheus, Grafana, and "just the basics," your laptop becomes a space heater, and the Linux OOM killer starts executing random processes.

The standard Kubernetes stack assumes you have 16GB RAM minimum. The real consumption breakdown:

  • K3s default install: 1.2GB (etcd, apiserver, controller-manager, scheduler, CoreDNS)

  • Traefik (bundled): 200MB

  • Metrics Server (bundled): 100MB

  • Local Path Provisioner: 50MB

  • Flannel/CNI: 150MB

Total before you deploy a single workload: ~1.7GB

Now add "Day 2" operations:

  • Prometheus: 800MB-2GB (depending on retention)

  • Grafana: 400MB

  • ArgoCD full install: 1.5GB (Redis, Repo Server, Dex)

You're at 4-5GB consumed before you've deployed anything valuable. On an 8GB machine with 1.5GB for the OS, you have 1.5GB left for actual applications. This is why developers "just use Docker Compose" - because the platform is heavier than the workloads.

This is unacceptable.


The Nano Architecture: Ruthless Accounting

Component Architecture

8GB System Boundary OS Layer (4GB Reserved) Linux Kernel ~500MB SystemD + Services ~300MB Page Cache + Buffer ~3.2GB Docker Boundary (4GB Hard Limit) Docker Daemon ~400MB K3d Cluster (~600MB) kube-apiserver 200MB etcd 150MB controller-manager 100MB scheduler 50MB CoreDNS (28MB) local-path-provisioner (18MB) Workload Space ~3GB Available OOM Killer Protection

We're building an IDP that runs on 4GB allocated to Docker, with 4GB reserved for the OS. This isn't a "toy" setup - this is how you build platforms when you respect constraints.

The Memory Budget Breakdown

Here's the actual allocation for the Nano-IDP:

ComponentMemory AllocationJustification
K3d (cluster)600MBK3s with Traefik/Metrics disabled, single node
Cilium (eBPF CNI)150MBReplaces kube-proxy, no Hubble UI
ArgoCD Core400MBNon-HA mode, no Dex/Redis
Crossplane300MBCore only, Providers loaded on-demand
vCluster (sleeping)50MBAggressive sleep policy, wakes on API call
Portal Backend80MBFastAPI on Python 3.12-slim
Portal Frontend40MBVite build served by Nginx (static)
Buffer380MBWorkload burst capacity
Total2GBLeaves 2GB in Docker for user apps

This is aggressive, but achievable. The key: every component runs in degraded/minimal mode by default.


Flowchart

User setup_lesson_01.sh Kernel Config Docker K3d Kubernetes API Execute ./build_and_deploy.sh Apply vm.swappiness=10 ✓ Tunings applied Copy daemon.json Memory limit: 4GB No swap ✓ Config ready (restart needed) create cluster nano-substrate --disable=traefik --disable=metrics-server --max-requests-inflight=200 Start k3s container Initialize control plane Start etcd (quota: 2GB) Start kube-apiserver (throttled) Start controller-manager Start scheduler Deploy CoreDNS Deploy local-path-provisioner ✓ All pods ready ✓ Cluster created kubectl top nodes 600MB used Deployment complete Monitor: ./scripts/monitor.sh

State Machine

Total System: 8192 MB OS Reserved: 4096 MB Kernel: 500 MB SystemD: 300 MB Buffer/Cache: 3296 MB Docker cgroup: 4096 MB Docker Daemon: 400 MB K3d Cluster: 600 MB kube-apiserver: 200 MB etcd: 150 MB controller-mgr: 100 MB scheduler: 50 MB CoreDNS: 28 MB local-path: 18 MB kubelet overhead: 54 MB Available for Workloads 3096 MB Can be reclaimed
Need help?