Ansible Operator

Ansible Operator - Memcached

Let’s create a new directory for our project:

mkdir -p $HOME/tutorial/memcached-operator

Navigate to the directory:

cd $HOME/tutorial/memcached-operator

Initialize a new Ansible-based Operator SDK project for the Memcached Operator:

operator-sdk init --plugins=ansible --domain example.com

Create the Memcached API and generate an Ansible role skeleton. This will ensure our controller is setup to watch the Memcached resource with APIVersion ‘cache.example.com/v1alpha1’ and Kind ‘Memcached’.

operator-sdk create api --group cache --version v1alpha1 --kind Memcached --generate-role

Inspect the memcached-operator directory structure for yourself with ‘tree’, and then ‘cd’ into it.

tree

To speed development of our Operator up, we can reuse an existing Role. We will install a Role from Ansible Galaxy into our Operator: dymurray.memcached_operator_role: galaxy.ansible.com (https://galaxy.ansible.com/dymurray/memcached_operator_role)

Run the following to install the Ansible Role inside of the project:

ansible-galaxy install dymurray.memcached_operator_role -p ./roles
ls roles/

Since we’ll be reusing the logic from ‘dymurray.memcached_operator_role’, we can safely delete the placeholder Role generated by the the ‘operator-sdk new’ command we ran previously.

rm -rf ./roles/memcached

We can use the ‘tree’ command to get a general sense of the memcached Role installed from Ansible Galaxy.

tree roles/dymurray.memcached_operator_role

This Role provides the user with a variable size which is an integer to control the number of Deployment replicas to create. You can find the default for this variable in the memcached Role defaults/main.yml file:

# ---
# # defaults file for Memcached
# size: 1

Next, we’ll modify the necessary files to ensure that our Operator uses this Role instead of the generated scaffolding Role. Let’s modify watches.yaml.

By default, the memcached-operator watches Memcached resource events as shown in watches.yaml and executes Ansible Role Memcached.

Since we have swapped out the original Role for one from Ansible Galaxy, lets change the Watches file to reflect this:

---
- version: v1alpha1
  group: cache.example.com
  kind: Memcached
  role: /home/centos/.ansible/roles/dymurray.memcached_operator_role

Update this file by running the following command:

\cp /tmp/watches.yaml watches.yaml

In the next step, we’ll build and run our Ansible Operator. Before running the Operator, Kubernetes needs to know about the new custom resource definition the Operator will be watching.

Note: Before running the next step, delete your Go-based Operator’s memcacheds.cache.example.com/v1alpha1 CRD from the cluster.

oc delete -f /home/centos/projects/memcached-operator/config/crd/bases/cache.example.com_memcacheds.yaml

Deploy the Ansible Operator Memcached CRD:

oc create -f config/crd/bases/cache.example.com_memcacheds.yaml

By running this command, we are creating a new resource type, memcached, on the cluster. We will give our Operator work to do by creating and modifying resources of this type.

To run our Operator locally, we will manually copy any Roles used by our Operator to a configured Ansible Roles path for our local machine.

cp -r ~/tutorial/memcached-operator/roles ~/.ansible/roles

Create the Namespace/Project:

oc new-project tutorial

Before starting the Operator, update the Makefile to use the latest version of Ansible Operator to avoid Python dependency issues

sed -i 's/v1.8.0/v1.15.0/g' Makefile

Start the Operator and set the WATCH_NAMESPACE variable

WATCH_NAMESPACE=tutorial make run

Open a 2nd terminal window and navigate to your Ansible Operator memcached project root directory

cd ~/tutorial/memcached-operator

Scope yourself to the tutorial project:

oc project tutorial

Now that our Operator is running, let’s create a CR and deploy an instance of memcached.

There is a sample CR in the scaffolding created as part of the Operator SDK:

apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
  name: memcached-sample
spec:
  foo: bar

Inspect config/samples/cache_v1alpha1_memcached.yaml, and then update the object to specify 3 replicas:

apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
  name: memcached-sample
spec:
  size: 3

Update this file by running the following command:

\cp /tmp/cache_v1alpha1_memcached.yaml config/samples/cache_v1alpha1_memcached.yaml
oc --namespace tutorial create -f config/samples/cache_v1alpha1_memcached.yaml

Ensure that the memcached-operator created the deployment for the CR:

oc get deployment

Check the pods to confirm 3 replicas were created:

oc get pods

Change the spec.size field in config/samples/cache_v1alpha1_memcached.yaml from 3 to 4.

apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
  name: memcached-sample
spec:
  size: 4
<editor_of_your_choice> config/samples/cache_v1alpha1_memcached.yaml
oc --namespace tutorial apply -f config/samples/cache_v1alpha1_memcached.yaml

Confirm that the Operator changes the Deployment size:

oc get deployment

Inspect the YAML list of ‘memcached’ resources in your project, noting that the ‘spec.size’ field is now set to 4.

oc get memcached  -o yaml

First, delete the ‘memcached’ CR, which will remove the 4 Memcached Pods and the associated Deployment.

oc --namespace tutorial delete -f config/samples/cache_v1alpha1_memcached.yaml

Verify the memcached CR and deployment have been properly removed.

oc get memcached
oc get deployment