What's the difference between a CRD-based Operator and a Helm chart?
Quick Answer
A Helm chart is a one-time (or repeated, on-demand) templating and installation mechanism — you run `helm install`/`helm upgrade`, and once the resulting resources are applied, Helm's job is done until you explicitly run another command. An Operator is a continuously running controller that keeps actively reconciling and reacting to the live state of the software it manages, indefinitely, without needing a human to trigger each reconciliation. They solve genuinely different problems and are often used together: Helm to package and install the Operator itself, and the Operator to then provide ongoing, automated lifecycle management of the actual application afterward.
Detailed Answer
Helm — a packaging and installation-time tool
helm install my-postgres bitnami/postgresql --set replicaCount=3
Helm renders templates into concrete Kubernetes manifests and applies them once, at the moment you run install or upgrade — after that, Helm itself has no ongoing, running presence in the cluster reacting to changes. If the underlying PostgreSQL Pod crashes, or a replica falls out of sync, Helm does nothing about it (that's the job of whatever controller is managing the resulting objects — typically just a StatefulSet's own basic reconciliation, with no PostgreSQL-specific operational awareness).
Operator — a continuously running, domain-aware controller
apiVersion: postgresql.example.com/v1
kind: PostgresCluster
metadata:
name: my-postgres
spec:
replicas: 3
Once this custom resource exists, the Operator's controller is continuously watching it (and the real state of the PostgreSQL cluster it manages) indefinitely — not just at the moment of initial creation. If a replica becomes unhealthy, the primary fails, or the spec is edited to request a version upgrade, the Operator reacts and takes appropriate, software-specific action, on an ongoing basis, with no human needing to run any command to trigger each reaction.
The key distinction: point-in-time templating vs. ongoing reconciliation
| Helm | Operator | |
|---|---|---|
| When it acts | Only when you explicitly run install/upgrade/rollback | Continuously, in response to any relevant change or failure |
| What it knows | How to render and apply YAML templates | Deep, software-specific operational logic (failover, upgrades, backups) |
| Ongoing presence in the cluster | None (no running component after install completes) | A running controller Pod (or Deployment), watching indefinitely |
| Handles a replica crashing at 3am | No — relies on whatever it deployed (e.g., a plain StatefulSet) to handle this on its own, generically | Yes — this is exactly the kind of scenario Operators are built to actively manage |
Why they're commonly used together, not as competing choices
A very common real-world pattern: use Helm to install the Operator itself (the Operator's own Deployment, its CRDs, its RBAC rules) as a one-time setup step, and then interact with the application going forward purely through the Operator's custom resources (kubectl apply -f postgres-cluster.yaml), letting the now-running Operator handle all further lifecycle management continuously. This isn't a contradiction — Helm and Operators solve different layers of the same overall problem (installing software vs. operating it long-term), and combining them is the standard, not an unusual choice.
The distinction to articulate clearly: Helm is fundamentally a templating and installation-time tool with no ongoing runtime presence, while an Operator is a continuously running controller with real operational awareness of the software it manages — conflating "a Helm chart that installs a complex application" with "an Operator that manages that application's ongoing lifecycle" is a common surface-level misunderstanding that a precise answer should specifically avoid.