An operator is a CRD plus a controller that encodes what a human operator of that software would do. It runs the reconciliation loop of the built-in controllers (The Reconciliation Loop): watch the custom objects and everything they own, compare spec with reality, act, and report in status. The difference is domain knowledge. A StatefulSet restarts a dead PostgreSQL 1,289 Pod; a PostgreSQL operator also knows to promote the replica with the most recent write-ahead log, to move the read-write Service to the new primary and to rebuild the old one as a replica.
Operators are usually written in Go with Kubebuilder (github.com/kubernetes-sigs/kubebuilder (https://github.com/kubernetes-sigs/kubebuilder 9,324 ), Apache-2.0, v4.16.0) or the Operator SDK (v1.42.3), which builds on it: both generate the CRD from Go structs and leave you a Reconcile function to fill in. Kopf 2,641 (Python) and the Java Operator SDK cover other languages.