Blog
Thoughts on engineering, design, and building great products.
API Aggregation: Bolting On a Second API Server
A CRD adds a new kind that the main API server itself stores in etcd. API aggregation goes further: it bolts a second API server in behind the main one, serving an API group that it stores and computes on its own terms. Our cluster has been running one example since Article 39 — metrics-server. This article examines it as an aggregated API: how the APIService registers it, where requests get proxied, and why the CPU/memory figures it returns never sit in etcd.
Admission Webhook: Wedge Into the Write Path
Article 54 used a built-in admission controller (Pod Security). This article writes one of your own: an HTTPS service the API server calls before storing each object, returning allow or deny. We build a real validating webhook in Python — self-sign a cert, make the API server trust it via caBundle, and require every pod to have a team label. A pod missing the label is rejected immediately; a pod in a namespace out of scope is untouched.
CustomResourceDefinition: Add Your Own Kind
Part XII shifts from using Kubernetes to extending it. The first article is CustomResourceDefinition — declare a new kind of object, and the API server immediately serves it like a native resource: kubectl get works, it validates against a schema, it stores in etcd. We build a Widget CRD with type and value-range constraints, create a valid custom resource, watch two invalid ones get rejected, then update status through a separate subresource.
Object management, recommended labels, and storage version
For the same Deployment, we have three ways to create and edit it — type a command directly, create -f a file, or apply a whole directory — and mixing them invites bugs. This article closes Part V with those three object-management techniques (plus why apply differs from create -f), the recommended app.kubernetes.io/* label set so tools speak the same language, and storage version — digging into etcd to see which API version an object is actually stored in.
Finalizers, ownerReferences and garbage collection
Every time we deleted a Deployment, the pods and ReplicaSet vanished with it — we called that garbage collection without dissecting it. This article digs into the mechanism: ownerReferences link parent and child, the garbage collector auto-cleans children when the parent is gone (background, foreground, or orphan), and finalizers block deletion until cleanup is done. All three tested for real — including an object stuck in Terminating because of a finalizer.