CRDs and operators

CRDs and operators

Custom Resource Definitions

A CRD teaches the API server a new kind. After you apply one, kubectl get, describe, explain, RBAC and every other tool work on it exactly as they do on Pods - because to the API server there is no difference.

kubectl get crd
kubectl api-resources | grep -v -E 'v1$|apps/v1'    # what is not core Kubernetes
kubectl explain cluster.spec                        # works on CRDs too

A CRD alone stores data and does nothing with it. It is a table with validation.

Operator = CRD + controller

An operator is a CRD plus a controller Pod that runs the same reconciliation loop Kubernetes runs for built-in objects - only the domain knowledge is about your application.

graph LR Y[your Cluster manifest<br/>3 instances, 1Gi] --> API[API server] API --> CRD[(stored as a<br/>custom resource)] OP[Operator controller Pod] -->|watches| API OP -->|creates and repairs| K[StatefulSet, Services,<br/>Secrets, PVCs, backups] K -->|actual state| API

You stop writing “a StatefulSet with three replicas, a headless Service, a Secret with the password, an init job that runs initdb, and a CronJob for backups”. You write:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: pgtest
spec:
  instances: 3
  storage:
    size: 1Gi

The operator creates all of it - and, unlike a Helm chart, it keeps operating: it fails over to a replica when the primary dies, rejoins the old primary, rotates credentials, and runs backups. Helm installs; an operator runs.

What the lab uses

CloudNativePG - a PostgreSQL operator. Its CRDs include Cluster, Backup and ScheduledBackup. You install the operator with Helm, create a Cluster, watch it build a StatefulSet-like set of Pods with PVCs, then delete the primary Pod and watch a failover happen without you.

The lab points the Cluster at a StorageClass, not at hand-written PVs. PostgreSQL runs as an unprivileged user and cannot write to an NFS export root owned by root, so this is the first workload in the course that genuinely requires dynamic provisioning - a good illustration of why real clusters run a CSI driver rather than hand-made volumes.

Where operators come from

OperatorHub.io and Artifact Hub. Most are installed by a Helm chart or a single manifest, and most follow the same shape: a *-system namespace, a Deployment for the controller, a set of CRDs, and RBAC.

Judge one before you adopt it: who maintains it, does it handle upgrades and backups, and what happens to your data if you delete the operator (usually nothing - CRs and PVCs survive, they simply stop being reconciled).

References