Build · shipped
Interactive Visual InstanceKubernetes Architecture From First Principles: Control Plane, Self-Healing Pods, and Zero-Downtime Networking
An interactive visual guide to how Kubernetes actually works — Control Plane reconciliation loops, why bare Pods die, how ReplicaSets self-heal, Service ClusterIP routing, and 12-Factor storage.
Kubernetes Control Plane, Self-Healing & Service Routing
Desired-State Reconciliation
- • Never deploy bare Pods; a
Deploymentmanages aReplicaSet. - • When a Pod crashes,
Controller Managerdetectsactual < desiredand schedules a replacement automatically.
Service Discovery & Readiness
- • Pods are ephemeral and their IPs change on every reschedule.
- •
Service (ClusterIP)+readinessProbeensures traffic only routes to healthy containers.
12-Factor Config & Persistence
- • Decouple config via
ConfigMapand credentials viaSecretmounts. - • Stateful workloads bind a
PersistentVolumeClaim (PVC)so data outlives pod restarts.
Why Kubernetes Exists (And the Mental Model That Clicks)
Running a single Go binary inside a Docker container on one Linux VM is simple until two production realities hit:
- Processes crash and nodes die at 3:00 AM.
- Traffic spikes and zero-downtime deploys require routing requests across multiple instances without dropping in-flight connections.
Kubernetes is not magic; it is a distributed desired-state reconciliation loop backed by an immutable key-value store (etcd). Instead of running imperative shell scripts (ssh node-01 && docker run ...), you hand the API Server a declarative YAML manifest stating: "I want 3 replicas of go-api:v1.4.0 listening on port 8080." Every component in the diagram above exists to make actual cluster state converge on that desired state.
1. The Control Plane vs. Worker Nodes
Click between 🟢 Steady (3/3 Ready) and 💥 Kill Pod (Self-Heal) in the interactive visual instance above to see how the two planes divide responsibility:
The Control Plane (The Brain)
kube-apiserver(:6443): The front door to the cluster. Everykubectlcommand, controller watch, andkubeletheartbeat goes through the API Server over TLS. It is the only component that talks directly toetcd.etcd: A strongly consistent Raft key-value store holding the entire cluster truth under/registry/. If it isn't recorded inetcd, it doesn't exist to Kubernetes.kube-controller-manager: Runs background control loops (ReplicaSet,Deployment,Node,Endpointcontrollers). Each loop watches the API Server and asks one question: Doesactual == desired?kube-scheduler: Watches for newly created Pods that havenodeName: ""(unscheduled), filters out nodes lacking CPU/memory requests, scores the remaining nodes, and binds the Pod to the best worker node.
The Worker Nodes (The Muscle)
kubelet: The node agent running on every worker. It watches the API Server for Pods bound to its node, instructs the container runtime (containerdvia CRI) to pull images and start containers, and continuously executeslivenessProbeandreadinessProbechecks.kube-proxy: Programs node networking rules (iptablesorIPVS) so traffic sent to a virtualServiceIP (ClusterIP) is load-balanced only to healthy Pod endpoints.
2. Core Mental Models: Pods, Deployments, and Services
| Resource | Mental Model | Why It Matters in Production |
|---|---|---|
| Pod | Peapod & Peas | The smallest deployable unit. Containers inside the same Pod share a single network namespace (localhost), IP address, and volume mounts. |
| Deployment / ReplicaSet | Factory Manager | You never deploy bare Pods in production. A Deployment owns a ReplicaSet that watches pod count and spawns replacements when a container crashes or a node goes dark. |
Service (ClusterIP) |
Receptionist Desk | Pods are cattle — every time a Pod restarts, it gets a brand-new IP (10.244.x.x). A Service provides a permanent virtual IP (10.96.0.10) and DNS name (go-api-svc.production.svc.cluster.local). |
| Rolling Update | Shift Change | Replaces v1 pods with v2 pods one at a time (maxSurge, maxUnavailable), waiting for readinessProbe to pass before draining the old replica. |
| ConfigMap & Secret | Backpack vs. Safe | Decouples 12-Factor configuration and credentials from the container image so the exact same Go binary runs in dev, staging, and prod. |
| PV & PVC | External Hard Drive | Container filesystems are wiped on restart. A PersistentVolumeClaim (PVC) mounts durable block/filesystem storage that outlives Pod lifecycles. |
3. Anatomy of a Self-Healing Go Deployment
When you click 💥 Kill Pod (Self-Heal) in the simulator above, trace the exact sequence that executes in under two seconds:
pod/go-api-7f8c-2suffers an OOMKill or node eviction (Status: Terminating).kubeletreports the container exit tokube-apiserver, which updatesetcd.- Traffic Protection: The Endpoint controller immediately removes
10.244.1.18fromgo-api-svc.kube-proxyupdates IPVS tables so zero user requests hit the dead pod. - Reconciliation:
ReplicaSet ControllerseesReady = 2 < Desired = 3and POSTs a new Pod spec (pod/go-api-4) tokube-apiserver. - Scheduling & Boot:
kube-schedulerplacespod/go-api-4ontoNode-02.kubeletstarts the Go container, waits forGET /healthz(readinessProbe) to return200 OK, and adds the pod back into theClusterIProtation.
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-api
namespace: production
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: go-api
template:
metadata:
labels:
app: go-api
spec:
containers:
- name: api
image: ghcr.io/divineforge/go-api:v1.4.0
ports:
- containerPort: 8080
resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "500m"
memory: "128Mi"
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 2
periodSeconds: 5
livenessProbe:
httpGet:
path: /livez
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
4. Field Triage Runbook (With kubectl & k9s)
When a deployment does not turn green, 95% of production failures fall into four states:
Pending: The scheduler cannot find a node that fits. Runkubectl describe pod <name>and checkEvents:forInsufficient cpu,Insufficient memory, or an unboundPersistentVolumeClaim.ImagePullBackOff: Bad image tag, missing registryimagePullSecrets, or rate-limited public pulls.CrashLoopBackOff: The container starts and exits non-zero (missing env var, panicking database connection, or an overly aggressivelivenessProbe). Inspect the previous crash withkubectl logs <pod> --previous.OOMKilled(Exit Code 137): The Linux kernel cgroup killer terminated the process for exceedingresources.limits.memory. For Go services, pair container memory limits withGOMEMLIMIT(e.g.,GOMEMLIMIT=110MiBon a128Micontainer) so the Go garbage collector runs before the kernel OOM-kills the pod.