What Is a Kubernetes Operator?
A Kubernetes operator encodes operational knowledge into software, automating tasks a human admin would otherwise do by hand for a specific application.
A Kubernetes operator is a piece of software that extends Kubernetes with application-specific operational knowledge, automating tasks — provisioning, backups, upgrades, failover — that a human administrator would otherwise perform by hand. It’s built from two parts: a Custom Resource Definition (CRD) that teaches Kubernetes a new kind of object, and a controller that watches those objects and continuously drives the cluster toward whatever state they describe.
The gap operators fill
Kubernetes ships with built-in controllers for generic workloads. See pods, deployments, and services for how those fit together: a Deployment knows how to keep N replicas of a stateless container running, roll out updates, and replace failed pods. That works well for stateless applications, but it knows nothing about the internals of, say, a PostgreSQL cluster — how to promote a replica to primary during a failover, take a consistent backup, or safely upgrade a running database one node at a time without data loss. A Deployment will happily restart a database pod the same crude way it restarts a stateless web server, which is often exactly the wrong thing to do.
Operators close that gap by encoding an application’s specific runbook into software. Instead of a human running a checklist during a database failover, an operator’s controller notices the failure and executes the same steps automatically, using knowledge specific to that database engine rather than generic Kubernetes primitives.
Custom resources and the control loop
The mechanism has two pieces working together:
- A Custom Resource Definition (CRD) registers a new object type with the Kubernetes API — for example, a
PostgresClusterresource with fields for replica count, storage size, and backup schedule. Once registered, users createPostgresClusterobjects withkubectl apply, the same way they’d create aDeployment. - A controller runs inside the cluster, continuously watching for
PostgresClusterobjects and comparing their declared state (what the YAML says should exist) against actual state (what’s actually running). When the two diverge — a replica crashed, a backup is due, someone edited the replica count — the controller takes whatever action closes the gap.
This is the same reconciliation loop pattern that powers every built-in Kubernetes controller, just pointed at an application-specific resource instead of a generic one. The operator pattern doesn’t introduce a new mechanism; it reuses Kubernetes’s own extension points to teach the control plane about a new kind of thing to manage.
What operators typically automate
- Provisioning — creating the StatefulSets, Services, Secrets, and storage volumes a stateful application needs, correctly wired together, from a single declarative spec.
- Scaling — adding or removing replicas while respecting an application’s specific constraints, such as a database that must replicate data to a new node before serving traffic from it.
- Failover — detecting a failed primary and promoting a replica, updating routing so clients reach the new primary without manual intervention. This is a more application-aware version of what liveness and readiness probes do at the pod level.
- Backups and restores — taking consistent snapshots on a schedule and restoring from them, using the application’s own tooling rather than a generic volume snapshot that might catch data mid-write.
- Version upgrades — rolling out a new database or message-broker version node by node, respecting quorum requirements that a naive rolling update would violate.
Operators vs Helm charts
Operators are often mentioned alongside Helm, but they solve different problems and are frequently used together. A Helm chart templates and installs a fixed set of Kubernetes manifests — it’s a packaging and templating tool, good at getting an application’s resources onto a cluster with configurable values. It has no ongoing awareness of the application after installation; if a database pod crashes in an unusual way, Helm has nothing left to do about it.
| Helm chart | Operator | |
|---|---|---|
| Job | Package and template manifests | Continuously manage a running application |
| Runs after install? | No — install-time only | Yes — an ongoing controller process |
| Handles failover/backups? | No | Often, yes |
| Complexity | Lower | Higher — requires writing and maintaining a controller |
It’s common to use Helm to install an operator itself, and then use the operator’s custom resources for the actual application lifecycle from that point on.
When to use one
Writing or adopting an operator is worth it when an application has enough operational complexity that generic Kubernetes primitives get it wrong — clustered databases, message brokers with partition rebalancing, certificate authorities with rotation logic. It’s overkill for simple stateless services that a Deployment already handles correctly; adding a custom controller there just adds a new component to operate, ironically without reducing operational burden.
Most teams don’t write operators from scratch. Popular stateful systems — PostgreSQL, Kafka, Elasticsearch, cert-manager for TLS certificates — have mature community or vendor-maintained operators available, distributed as Helm charts or through the Operator Hub. Writing a custom operator is generally reserved for internal applications with operational needs specific enough that no existing operator fits, and it’s a real engineering investment: the controller has to be at least as correct as the runbook it replaces, or it automates mistakes instead of preventing them. Managing an operator’s own lifecycle — upgrading the controller, migrating CRDs between versions — is itself a GitOps-friendly workflow, since the operator and the custom resources it watches are just more YAML in the same declarative pipeline as everything else in the cluster.
The takeaway
A Kubernetes operator pairs a custom resource definition with a controller that continuously reconciles an application’s declared state against reality, using operational knowledge specific to that application rather than Kubernetes’s generic primitives. It’s the right tool for stateful, operationally complex systems — databases, brokers, certificate management — where a plain Deployment doesn’t understand what a safe failover or upgrade looks like. For everything else, the built-in controllers Kubernetes already ships with remain the simpler, sufficient choice.
Tagged
Keep reading
Chisato · · 4 min read Kubernetes ConfigMaps vs Secrets: What's the Difference
ConfigMaps store non-sensitive configuration; Secrets store credentials with base64 encoding and tighter access controls. When to use each.
Chisato · · 4 min read Kubernetes StatefulSets vs Deployments Explained
Deployments manage interchangeable, stateless pods; StatefulSets give each pod a stable identity and storage. When each one actually belongs.
Chisato · · 4 min read Kubernetes Ingress vs Gateway API: What's the Difference
Ingress and Gateway API both route external traffic into a Kubernetes cluster. Gateway API is the more expressive successor — here's how they differ.