Categories
Automation DevOps Orchestration

Create Kubernetes Operator using Ansible

Today, I’ll show how to create and use Kubernetes operator using Ansible. I’ll also explain why to use Kubernetes operators and their relation to Kubernetes CRDs. As always, I’ll show a demo. If you later find this article useful read the disclaimer on ways to thank me.

Firstly, we’ll see what are Kubernetes CRDs and why to use them. Next, I’ll highlight their relation to Kubernetes operator. Finally, we’ll see a demo focusing on how to create Kubernetes operator using Ansible.

Why to use Kubernetes CRDs?

If you run kubectl api-resources you’ll see all available Kubernetes resources on a Kubernetes cluster. Of course, you’ll see in the output Kubernetes Pods, Services and Deployments and other less known resources. These resources are basically endpoints on which you can run HTTP requests. Run kubectl auth can-i --list to see what HTTP verbs you can apply on which Kubernetes resources.

Kubernetes resources allow to express almost all aspects of modern applications deployed to Kubernetes. For instance, we have seen how RabbitMQ can be deployed as Kubernetes StatefulSet. Yet, we’ve also seen StatefulSet limitations. Namely, it doesn’t allow us to configure RabbitMQ cluster without additional effort. To elaborate, while you can deploy a RabbitMQ StatefulSet of several replicas, you’ll still need to apply an additional configuration so RabbitMQ processes inside those replicas will form a valid RabbitMQ cluster. Previously, I showed how to configure RabbitMQ cluster as a single Docker Swarm service. Similarly, that will apply to any stateful application (e.g. database) you’d want to deploy to Kubernetes. It would be much easier for reasoning and management to have a resource named RabbitMQCluster in Kubernetes. Luckily, Kubernetes allows to achieve just that using Custom Resource Definitions (CRDs).

What are Kubernetes CRDs?

CRDs are custom resource definitions. This is a Kubernetes way for extending its API for developers who need custom resources. Such resources usually represent custom applications deployed to Kubernetes. To give a quick example, let’s go back to posts where I reviewed Kubernetes StatefulSets and. Let’s assume you want to automatically deploy and configure RabbitMQ cluster in Kubernetes cluster.

What are Kubernetes Operators?

I’ll give a quick and dirty answer in order to give an idea as there are many resources on the web which explain what Kubernetes operators are. Let’s assume you raised RabbitMQ processes and manually configured its cluster by running some commands. Now, instead of manually raising RabbitMQ processes following their failure we rely on Kubernetes to raise pods where these processes run. Yet, it’s not enough, because we need to add these processes back to RabbitMQ cluster. So instead of running these commands manually following each replica failure, Kubernetes Operator will run that code for us after catching relevant Kubernetes events.

So Kubernetes operators automatically manage Kubernetes custom resources in order to enforce their desired state. In the context of RabbitMQCluster CRD instance, Kubernetes Operator will configure RabbitMQ cluster because that’s the desired state. In addition, it will react to events like RabbitMQ pod’s failures and will add new RabbitMQ processes back to RabbitMQ cluster running in the new pods which Kubernetes spins up for us. Of course, there could be many more actions the operator might perform. Yet, the idea is the same. Events pop, some operator’s code runs to enforce the desired state following these events.

Why use Ansible Kubernetes Operators?

While Kubernetes operators are typically written in Go, I’m a Python guy and as Ansible is written in Python I’m a little biased:) To give a couple of practical reasons:

  • Ansible (and Kubernetes) manifests are both specified in yaml format and follow declarative style which allows for a quick entry into writing operators.
  • Ansible has k8s module for interacting with Kubernetes api for common operations.

Let’s now see how to create Ansible Kubernetes Operators.

Demo Prerequisites

You’ll need operator-sdk.

Create Ansible Kubernetes Opearator

Let’s create Ansible operator using operator-sdk.

mkdir rabbitmq-cluster-operator
cd rabbitmq-cluster-operator/
operator-sdk init --plugins=ansible --domain example.com

Last command bootstraps Kubebuilder project of Ansible layout.

Create RabbitMQCluster CRD

Let’s now create RabbitMQCluster CRD.

operator-sdk create api --group queue --version v1alpha1 --kind RabbitMQCluster --generate-role

Inspect config/crd/bases/queue.example.com_rabbitmqclusters.yaml to view CRD schema.

Let’s add replicasCount field to the schema:

            properties:
              replicasCount:
                type: integer 

RabbitMQCluster object will have field – replicasCount in its spec.

Now, you wonder where the operator’s code is? You’ll need to code it as Ansible role at roles/rabbitmqcluster/tasks/main.yml. This role will run each time a RabbitMQCluster resource is created, updated or deleted. To remind, this code will have to ensure the desired state of RabbitMQCluster e.g. automate cluster creation commands.

That’s it for today. You can follow operator-sdk tutorial to further explore how to deploy the crd and the operator to Kubernetes cluster.

Summary

That’s it about Ansible Kubernetes operators. As always, feel free to share.

If you found this article useful, take a look at the disclaimer for information on how to thank me.

You may also find below articles interesting:

Bonus:

Recommended Kubernetes courses on Pluralsight:

Sign up using this link to get exclusive discounts like 50% off your first month or 15% off an annual subscription)

Recommended Kubernetes books on Amazon.