# THE EXPLODEDCLUSTER

a five-course tasting menu · kubernetes · openshift · docker
jonny@edge — bash
scroll to tear it down▼
Course I — entrée
Image & Container · Docker

## A container is a lie the kernel tells a process.

That terminal did more than it admitted. `docker build` turned each Dockerfile step into an immutable
, stacked by an
— the running container adds one thin writable layer that dies with it. Shipping is a push to a
. The trap: a
is a pointer that can move under you; a
is the artefact itself. At run time, isolation is just the kernel:
decide what a process sees,
decide what it uses. No VM — very confident bookkeeping. Scroll: the image rises out of the deep, layer by layer.

FROM ubi9-minimal base OS — shared, cached, content-addressed
RUN install deps a filesystem diff — cache hit if unchanged
COPY src/ /app your code — order it late, bust the cache less
writable layer the running container — ephemeral, dies with it

#### registry

push / pull — only missing layers move

#### tag vs digest

:latest can move · @sha256 cannot

read-only layers below · one writable lie on top
Say it like you mean it Build once, promote by digest.
Field noteIf your deploy "changed" without a code change, a floating tag moved under you. Production manifests pin digests; humans read tags.
Course II — the machine
The Cluster

## A cluster is a promise, not a place.

You never tell Kubernetes how to run your app. You describe what you want —
— and the cluster works, forever, to make it true. That habit is the
: compare
against
, fix the difference, repeat. Two halves: a control plane that decides, and worker nodes that run. That `kubectl apply` in the terminal didn't launch anything; it filed paperwork. The machine took it from there.

#### CONTROL PLANE

decides — holds truth, schedules, reconciles

#### NODE 1

runs pods

#### NODE 2

runs pods

#### NODE 3

runs pods

decide ▲ / run ▼ — the split that makes everything else possible
Say it like you mean it Kubernetes doesn't run your app — it reconciles it.
Field noteIf you're SSHing into nodes to "fix" things, you're arm-wrestling the reconciler — and it doesn't get tired. Change the desired state instead.
The Control Plane

## Four processes and a filing cabinet.

The
is the only door in the building. Behind it,
is the cluster's memory — only the API server may touch it. The
picks where each pod lands — filter, score,
— and never runs a thing. The
hosts the loops: a Deployment begets a
, which begets pods.

#### kube-apiserver

the only door — authn, authz, admission, persistence

#### etcd

consensus truth — quorum or nothing

#### scheduler

filter → score → bind

#### controller-manager

the reconciliation loops

everything watches the api-server — nothing talks sideways
Say it like you mean it etcd is the truth; everything else is a cache.
Field noteThe API server being the bottleneck is the design, not a flaw — one authenticated, audited, admission-controlled door beats five convenient ones.
Course III — where it runs
The Node

## Where intent becomes a process.

Every node runs a
— the only component in the whole system that actually starts your container. It speaks
to containerd or CRI-O, which pulls images and launches containers. A
hands each pod a real IP, and
— or an
dataplane replacing it — makes Service addresses route to real pods.

#### kubelet

node agent — the only thing that starts your container

#### containerd / CRI-O

pulls images, runs containers (CRI)

#### CNI plugin

a real IP per pod

#### pod ⬤⬤

lands here

#### kube-proxy / eBPF

makes Services route

kubelet drives · runtime executes · cni wires · proxy routes
Say it like you mean it The kubelet is the only component that actually starts your container.
Field noteNode `NotReady`? Check kubelet ↔ api-server connectivity before anything else — a node that can't phone home is presumed lost.
The Pod

## One IP, shared fate.

A pod isn't a container — it's a jacket around one or more. Everything inside shares a
(one IP, localhost between friends) and can share
.
run first, in order — gatekeepers.
ride along. Then the probes — three different jobs:
owns warmup,
gates traffic,
restarts the truly hung. Confusing them is how healthy pods get executed.

shared network namespace — one IP

#### app container

your process

#### sidecar

proxy · logs · reload

#### initContainer

runs first, to completion — the gatekeeper

#### volumes

shared mounts

#### probes

startup → readiness → liveness

smallest schedulable unit — the jacket, not the container
Say it like you mean it containerPort is documentation — the app still has to bind the port itself.
Field note `exit 137` with reason `Error` is the kubelet's probe kill; `OOMKilled` is memory. Same exit code, different crimes — read the reason.
Course IV — the traffic
Services & Ingress

## Pods are cattle; Services are the brand.

Pods are ephemeral — they die, respawn, change IPs. A
is the stable name in front of the churn: a
inside, a
at the edge, and
(or the Gateway API) for host- and path-routing above them. Membership is decided by readiness — a pod failing readiness silently leaves the pool. That's the feature. It's also the first place to look when traffic "disappears".

☺ client
LB / Ingress
Service VIP

#### pod · ready

in the pool

#### pod · not ready

silently removed

readiness decides membership — traffic follows
Say it like you mean it Never talk to a pod; talk to a Service.
Field note"The network is broken" after a deploy is usually readiness telling the truth about your app — not the network lying about your packets.
Course V — dessert
OpenShift

## Kubernetes with opinions — and a security guard.

OpenShift is a distribution of Kubernetes: same engine, opinionated chassis. The doorman is the
: the default,
, runs your container as a random non-root UID — your image has to cope. Workloads that genuinely need privilege get a dedicated ServiceAccount bound to a minimal custom SCC — never the stock one.
predate Ingress and still rule here.
run the platform itself, and
puts the whole thing on one box in a shop's back office. The OS underneath is immutable — changed by
, not SSH. Scroll — the opinions orbit the core.

#### KUBERNETES CORE

same engine underneath

#### SCC

admission: what a pod may BE

#### Routes

L7 exposure, pre-Ingress

#### Operators / OLM

the platform runs itself

#### oc + console

kubectl, extended

#### MachineConfig

immutable OS, declared changes

#### SNO

the whole cluster on one edge box

a ring of opinions around the same core — scroll to spin it
Say it like you mean it On OpenShift, admission is the interview — the SCC is the dress code.
Field noteDeployment stuck at 0/1 with no pod at all? The refusal happened above scheduling — read the ReplicaSet events. The error lives a level up.
Petits fours
Phrasebook

## Take the words with you.

Hover (or tap) any term — the load-bearing phrases of the whole trade. Use them precisely and people will assume, correctly, that you know where the bodies are buried.