Ansible is a tool for provisioning, configuration, and management of application infrastructure on compute resources. Operator SDK allows someone familiar with Ansible to quickly scaffold an operator based on Ansible playbooks and roles.
Prereqs:
- Operator SDK (I have installed the macOS)
- Kubernetes cluster (you can easily use a minikube for dev purposes)
- Go (v1.21.1)
# Step 1: Create a project
$ mkdir ansible-operator && cd ansible-operator
$ operator-sdk init --plugins=ansible --domain example.com
— — domain
is used for any API groups the operator creates. So yours will be all *.example.com. An API Group is simply a group of related functionality, such as your operator. An API Group you might already be familiar with is rbac.authorization.k8s.io, which is where the functionality for creating RBAC resources such as ClusterRoles and ClusterRoleBindings is usually set up on a Kubernetes cluster. operator-sdk
allows you to specify a custom domain you can append to any API groups that you define to help avoid name collisions.
Generated files:
$ ls -lart ─╯
total 64
drwxr-xr-x@ 21 user x 672 Nov 8 16:27 ..
-rw-r--r-- 1 user x 205 Nov 8 16:28 requirements.yml
-rw-r--r-- 1 user x 126 Nov 8 16:28 .gitignore
drwxr-xr-x 4 user x 128 Nov 8 16:28 molecule
-rw-r--r-- 1 user x 312 Nov 8 16:28 Dockerfile
drwxr-xr-x 3 user x 96 Nov 8 16:28 playbooks
-rw-r--r-- 1 user x 10350 Nov 8 16:28 Makefile
drwx------ 11 user x 352 Nov 8 16:28 config
drwxr-xr-x 4 user x 128 Nov 8 16:28 roles
-rw-r--r-- 1 user x 179 Nov 8 16:28 watches.yaml
-rw------- 1 user x 556 Nov 8 16:28 PROJECT
drwxr-xr-x 13 user x 416 Nov 8 16:35 .
drwxr-xr-x 3 user x 96 Nov 8 16:35 bin
watches.yml
— file that defines the mapping between your API and your Ansible playbooks and rolesDockerfile
— for the controller image- a
PROJECT
file with the domain and project layout configuration - a
Makefile
to build, deploy and undeploy the project requirements.yaml
— holds the Ansible dependenciesPlaybooks
androles
directories for respective Ansible files- a
molecule
directory that containts scaffolding for use with Molecule, an Ansible test framework - a
config
directory which hols -> base manifest; kustomization yaml; rbac yaml for authorizing various components to interact with each other; a `Patch` file for enabling Prometheus metrics
# Step 2 : Create an API
$ operator-sdk create api --group cache --version v1alpha1 --kind Memcached --generate-role
This command creates a new API by creating a new CRD (Custom Resource Definition) in the ‘cache’ API group.
--generate-role
causes the Operator SDK to also generate an Ansible role that serves as the backing for your custom resource type.
This will generate you the following:
- a Memcached custom resource definition
- an Ansible role to back that CRD
- scaffolding to configure the ansible-operator server image to connect them
- RBAC to allow the ansible-operator server to edit the needed Kubernetes resources
- sample YAML in
config/samples/
to create an example Memcached custom resource object - changes in
watches.yaml
based on the new Memcached custom resource - changes in PROJECT to show the new API
# Step 3: Configure the Ansible role
Update roles/memcached/tasks/main.yml
to contain the following:
---
- name: start memcached
community.kubernetes.k8s:
definition:
kind: Deployment
apiVersion: apps/v1
metadata:
name: '{{ ansible_operator_meta.name }}-memcached'
namespace: '{{ ansible_operator_meta.namespace }}'
spec:
replicas: "{{size}}"
selector:
matchLabels:
app: memcached
template:
metadata:
labels:
app: memcached
spec:
containers:
- name: memcached
command:
- memcached
- -m=64
- -o
- modern
- -v
image: "docker.io/memcached:1.4.36-alpine"
ports:
- containerPort: 11211
This role contains a single task named ‘start memcached’. It uses the interface defined by the Ansible Kubernetes collection to create a deployment configured
with the information available from an instance of our Memcached custom resource. It is configured to set the replicas of the deployment to the size
variable from our custom resource’s spec.
# Step 4: Build and deploy the operator
$ make docker-build docker-push IMG=docker.io/$USERNAME/ansible-operator:1.0.0
$ make deploy IMG=docker.io/$USERNAME/ansible-operator:1.0.0
After a bit, you should see the pods containing the controller come up:
$ kubectl get pods --n ansible-operator-system
NAMESPACE NAME READY STATUS RESTARTS AGE
ansible-operator-system ansible-operator-controller-manager-7b8555fb4b-wv8mh 0/2 ContainerCreating 0 14s
Check to see that the CRD has been created:
$ kubectl get crds
NAME CREATED AT
memcacheds.cache.example.com 2021-03-13T00:20:18Z
That’s it. We are done.
Feel free to play around with it to get a feel for the behavior of the Custom Resource.
# Step 5: Cleanup
When you are done, you can cleanup the deployed operator by running the following commands:
$ kubectl delete memcached memcached-sample
$ make undeploy