K8s Operators are responsible for building, packaging, and managing Kubernetes controllers, whether they are Custom Kubernetes Controllers or Native Kubernetes Controllers. Essentially, an Operator monitors your resources and executes custom logic to oversee the application lifecycle.
The main notion of the K8s Operators is to work with Custom Kubernetes Controllers.
Why Do We Need Operators?
Kubernetes can manage stateless applications (like web servers) very well using Deployments and Services. But for stateful applications like databases or message brokers (PostgreSQL, Kafka, Redis), things get tricky.
You often need to:
Handle version upgrades safely
Perform backups and restores
Monitor health and replace broken instances
Ensure high availability
Manage secrets, storage, and replicas
Doing all of this manually (or via scripts and CronJobs) isn’t scalable or reliable. That’s where Operators step in.
How Do Operators Work?
Operators are built using the Kubernetes controller pattern. Here’s the simplified lifecycle:
CRDs (Custom Resource Definitions): Define new types of Kubernetes objects (like PostgresCluster or RedisFailover).
Controller (Operator): Watches for events on these custom resources.
Reconciliation Loop: If the actual state doesn’t match the desired state (e.g., 1 replica instead of 3), the operator takes action.
Operators continuously reconcile the desired state with the real state just like Kubernetes does for Pods, but with domain-specific intelligence.
Is the Operator a replacement for the HELM ?!
No, an Operator is not a total replacement for Helm; each serves a different purpose, and often they complement each other.
HELM | OPERATOR |
---|---|
Helm does not deal with the reconciliation logic (watches & reacts to changes) within it. | The operator needs reconciliation logic included within itself (best practice) |
In Helm, we need to manually update if upgrading to new versions. | In Operator, we need to just enable auto upgrade for version upgrades |
Best for Simple Deployments | Best for the Stateful Apps with the Operational Logic |
What is OLM (Operator Lifecycle Manager) ?!
OLM (Operator Lifecycle Manager) is a Kubernetes component that helps you install, manage, and update Operators in a Kubernetes cluster automatically and safely.
What it does
Installation Management
Versioning and Upgrades (Similar to App updates in mobile apps)
Dependency Handling (Operator to Operator)
Scoped Access
Provides Safety nets (Preventing Broken Deployments)
What's Custom Operator ?!
Think of a Kubernetes Operator as a smart assistant for your apps running inside the cluster. It understands how your app should behave and takes care of managing it like installing, scaling, healing, or even upgrading it.
Now, a Custom Operator is something you build when your app has unique needs that standard Operators can’t handle. To create one, you’d typically use the Operator framework, which makes the whole process much easier.
You can write Operators using Golang, Ansible, or Helm. But here’s the thing if you're aiming to build a full-blown, production-grade Operator (like the ones used by CNCF projects), Golang is usually the way to go. It’s native to Kubernetes and gives you the most control.
Here are a few well-known Operators you might’ve heard of:
Prometheus Operator (one of the more complex ones)
Elasticsearch Operator
Istio Operators
ArgoCD Operators
MinIO Operators
Once you've built your Operator, you can publish it to operatorhub think of it as the DockerHub for Operators. But there’s a small catch: it’s a curated marketplace. That means your Operator needs to be reviewed and approved by the Kubernetes OperatorHub( k8s-operatorhub) team before it shows up there for everyone to use.
Deploying the CloudNativepg using OLM
Install the OLM(Operator Lifecycle Manager)
curl -sL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.32.0/install.sh | bash -s v0.32.0
Install the Operator from OperatorHub (Operatorhub.io)
kubectl create -f https://operatorhub.io/install/cloudnative-pg.yaml
Check out the Cluster version (CSV) created
Why? => OLM uses ClusterServiceVersions (CSV) to define which Kubernetes versions an Operator supports & supports the Rollbacks (backward-compatible update)
kubectl get csv -n operators --watch
Create the Cluster Demo file for a running example
vi cluster-example.yaml
# Contents of the Cluster Example
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-example
spec:
instances: 3
storage:
size: 1Gi
Apply the changes of the Cluster Example
kubectl apply -f cluster-example.yaml
Watch for the resource changes in the Default namespace
It will create the 3 Instances of Pods => 1 Primary as well as 2 Replicas(read-only mode) & a statefulset managed by Operator
Also responsible to crate a Custom Resource ==> Cluster under the cnpg CRD
kubectl get pods --watch
Now, in these pods, check out the Pod with the label tagged as role=Primary
kuebctl describe pods <Pod-Name>
Let's try to exec into the PostgresPods; In my case, "cluster-example-1"
kubectl exec -it cluster-example-1 -- psql -U postgres
If the connection is successful, the Operator is working properly; otherwise, verify the Operator installation
kubectl exec -it cluster-example-1 -- psql -U postgres
\conninfo
\l <List of DB's>
Voila! We've installed the Kubernetes Operator and established a PostgreSQL connection within the cluster.
Conclusion
Kubernetes Operators are a powerful pattern to extend Kubernetes beyond the limits of YAML and manage complex applications automatically.
If your team spends hours writing scripts to manage stateful apps or doing manual upgrades, you probably need an Operator.
Start by exploring existing Operators on OperatorHub.io or try building your own with the Operator SDK
EzyInfra.dev – Expert DevOps & Infrastructure consulting! We help you set up, optimize, and manage cloud (AWS, GCP) and Kubernetes infrastructure—efficiently and cost-effectively. Need a strategy? Get a free consultation now!
Share this post