Topic 8.1
CRDs & Operators
In one line
A CustomResourceDefinition teaches the API server about an entirely new kind of object; an Operator is the controller that watches it and does something real — the same reconciliation loop from Phase 0.1, now applied to whatever you define.
Think of it like this
Every built-in Kubernetes object so far (Pod, Deployment, Service) is like a pre-printed form the API server already knows how to process — a CRD is the act of designing and registering an entirely NEW form type, one the API server has never seen before, so that it can be filled out, stored, and validated exactly like any built-in one.
Key ideas
- 01
A CUSTOMRESOURCEDEFINITION (CRD) extends the Kubernetes API itself with a brand-new resource TYPE — once registered,
kubectl get <your-new-type>,kubectl apply -f, and full RBAC/admission control (Phase 5) all work on it identically to any built-in type, even though Kubernetes' own core code has zero built-in knowledge of what it actually means. - 02
A CRD alone does NOTHING beyond storage — creating a custom resource just persists it in etcd, exactly like any object. An OPERATOR is the actual CONTROLLER (Phase 0.1's reconciliation loop, now custom-written) that watches for instances of your custom resource and takes real action to make the cluster's actual state match what they declare — the CRD is the noun; the Operator is the verb that makes it mean something.
- 03
The classic real example: a
PostgresClusterCRD lets you declarereplicas: 3, version: "16"as a single, simple custom object — the accompanying Postgres Operator watches for these objects and does the actual, genuinely complex work behind the scenes: creating the right StatefulSet (Phase 1.3), configuring replication between the pods, handling failover if the primary dies, and managing backups — all real, non-trivial Kubernetes operations, hidden behind one simple declarative object. - 04
This is genuinely the same design principle behind EVERY built-in controller this entire course has covered — a Deployment's own controller does exactly this reconciliation for ReplicaSets, and a Job's controller does it for one-off pods. Operators simply mean YOU (or a vendor) can write this exact same pattern for entirely new kinds of domain-specific logic Kubernetes itself was never built to understand natively.
- 05
You'll far more often INSTALL and USE an existing, well-tested Operator (for a database, a certificate manager like cert-manager, a monitoring stack) than write one from scratch —
kubectl get crdsshows every custom resource type currently registered in a cluster, a genuinely useful first command for understanding what's actually been extended beyond Kubernetes' own built-in vocabulary.
Code & diagrams
The exact same reconciliation loop from Phase 0.1, now watching a resource type YOU (or a vendor) defined.
One simple object — a real operator handles the genuinely complex work behind it.
apiVersion: postgresql.example.com/v1
kind: PostgresCluster # a CUSTOM type — not built into Kubernetes itself
metadata:
name: my-database
spec:
replicas: 3
version: "16"
storage:
size: 20Gi
backup:
schedule: "0 2 * * *" # same cron syntax as Phase 1.4's CronJobSee what's already been extended in a cluster, and watch an operator do real work behind a simple object.
# See every custom resource TYPE currently registered
kubectl get crds
# See what operators are actually running (usually their own Deployments)
kubectl get deployments -A | grep -i operator
# Create an instance of a custom resource — behaves exactly like a built-in one
kubectl apply -f custom-resource.yaml
kubectl get postgresclusters
kubectl describe postgrescluster my-database
# The REAL resources the operator created behind the scenes
kubectl get statefulsets -l app=my-database
kubectl get pvc -l app=my-databaseExplain it without notes
Why does creating a CRD alone accomplish nothing on its own, without a corresponding Operator also running in the cluster?
What's the relationship between an Operator and the reconciliation concept Phase 0.1 introduced for Kubernetes' own built-in controllers?
Practice
Run kubectl get crds on any cluster you have access to and identify at least one CRD that isn't part of Kubernetes' own core (often installed by a specific tool or operator you or someone else added).
If you have access to a cluster with an actual operator installed (cert-manager is a genuinely common, easy one to find), create a simple custom resource it manages and watch, via kubectl get/describe, what real resources it creates behind the scenes.
Trade-offs
- ↔
Operators are genuinely powerful for encoding real operational expertise (how to correctly run a specific database, how to correctly issue and renew certificates) into a simple, declarative interface — but writing and maintaining a genuinely correct, production-grade operator yourself is real, substantial engineering effort; for anything with an existing, well-maintained community or vendor operator already available, using that is almost always the better choice over building your own from scratch.
Done when you can
I understand a CRD only defines a new resource type — an Operator is what actually acts on it.
I can explain the Operator pattern as the same reconciliation loop from Phase 0.1, applied to a custom resource type.
I know to check kubectl get crds to see what's already extended a cluster beyond its built-in resource types.