What is the Operator pattern?
Tags: kubernetes, devops, sre, tutorial
Published: 2023-06-05 13:14:00

Automate tasks is always something particular. When we want to do some tasks we need to be able to react or being triggered on some specific events. But a lot of events can't be listen easily, especially in a Kubernetes Cluster. So today, we will see how to try to resolve it, with the **operator pattern**.

---

## TLDR
> Operators are software extensions to Kubernetes that make use of [custom resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) to manage applications and their components. Operators follow Kubernetes principles, notably the [control loop](https://kubernetes.io/docs/concepts/architecture/controller).

*Source - [Kubernetes Documentation](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/)*

---

## What is the operator pattern ?
This pattern allows Kubernetes users to create their own **resource controller** in order to automate the management of their application/product stack.

The operator pattern uses **CRDs** *(Custom Resource Definition)* in order to facilitate the resources/tasks configuration.

*Exemple of a CRD from Strimzi which let us create a complete Kafka cluster*
```yaml
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  name: my-cluster
spec:
  kafka:
    version: 3.4.0
    replicas: 3
    listeners:
      - name: plain
        port: 9092
        type: internal
        tls: false
      - name: tls
        port: 9093
        type: internal
        tls: true
    config:
      offsets.topic.replication.factor: 3
      transaction.state.log.replication.factor: 3
      transaction.state.log.min.isr: 2
      default.replication.factor: 3
      min.insync.replicas: 2
      inter.broker.protocol.version: "3.4"
    storage:
      type: jbod
      volumes:
      - id: 0
        type: persistent-claim
        size: 100Gi
        deleteClaim: false
  zookeeper:
    replicas: 3
    storage:
      type: persistent-claim
      size: 100Gi
      deleteClaim: false
  entityOperator:
    topicOperator: {}
    userOperator: {}
```

And since it follows a lot of Kubernetes principles as the control loop, your operator will be *(depending your configuration and what you've code in your code)* able to monitor resources that it has created and/or other resources on your cluster.

Here is a scheme coming from the [RedHat blog](https://developers.redhat.com/articles/2021/06/22/kubernetes-operators-101-part-2-how-operators-work#deploying_workloads_in_kubernetes) illustrating the context.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rckc4hv6vab0zoth2h1z.png)


### Example
In order to be more concrete, here are some examples.

#### 1. Automate to avoid to repeat multiple deployments
If you are in a team who deploy and give access to each team of your company a complete tool stack to collect and visualize their metrics, you need to deploy **manually** for **each of them** the following stack :
- Prometheus
- OpenTelemetry
- Grafana
- Postgres

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8o566lytsc8z0u5271g3.png)

In this situation, instead of repeating the same task to deploy all theses apps and all the related components *(Services, configmaps, service accounts...)*, you can just **create an operator** to let it manage
this kind of tasks for you with a CRD to contain all the configurations which can be updated.

For example, the CRD can be named `ObservabilityStack` and each time a new  instance of this resource will be created, it will automatically create all the resources you've defined.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5y8ue9oq9ltmiode1ez.png)

#### 2. Automate to avoid manual errors
People who already  managed `StatefulSet` knows what I will talk about.

When we manage some applications *(especially the apps with volumes)*, it can happend that we need to do some specific tasks in a specific order in order to create, update or delete something.

So if you only have 3 or 4 resources of this kind, it can be correct to do it with bash scripts or ansible scripts. But if you have 50? 100? or more?

In this kind of situation, the operator pattern can help you too. If you are able to define all the tasks you need to do, they  will be executed in the required case.

Thus, this applications won't be dependant anymore of you during an update. And it will make your life easier.

#### 3. Automate configuration
In this example, imagine you are in a team who manage a Nginx which expose all the APIs of your company. And all the APIs and your nginx are in the same Kubernetes cluster. Once a new one is deployed, you need to update your config file with the new endpoints in all the environments. Also your company loves microservices, so you have new APIs and updates every week.

Also some of them are renamed, moved or even deleted. But you are not always in the loop, so if one api doesn't work anymore, you receive calls to understand what's happening.

As you already understand, operators are a solution to help you in this case. As you are able to track resources on all the cluster, you can see if some deployements are added, renamed or deleted! So with this, you are able to trigger when these kind of event happend and you can update your configuration file!

---

## Conclustion
With all this examples, I think you understand the principle and the utility of this pattern.

Now, if we want to go further, we need put our hands in the code. So we will see in the following post **how to create an operator**!

I hope it will help you and if you have any questions *(there are not dumb questions)* or some points are not clear for you, don't hesitate to add your question in the comments or to contact me directly on  [LinkedIn](https://www.linkedin.com/in/maxime-guilbert-14b6a5128/).

---

<center><h3>You want to support me?</h3></center>
<a href="https://www.buymeacoffee.com/mxguilbert7" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>