This advanced example introduces a simple Operator which is based on the config watcher Controller, so we recommend to try controller demo first.
Here we add a dedicated Custom Resource Definition (CRD) ConfigWatcher
which turns our controller into an Operator.
For a detailed explanation of how this demo works, please refer to the Operator pattern in out book, this document gives you a brief walk-through the example code.
Note
|
Before we start, please ensure that you have stopped the controller deployment from the Controller demo. You can easily remove it also by a kubectl delete -f config-watcher-controller.yml . Actually, the ideal would be to setup this operator demo in a fresh namespace.
|
Warning
|
Again the warning, that this is example is meant for educational purposes only and is not suitable for general purpose usage. |
The easiest way to try this example is by using minikube with an ingress controller enabled:
# Start minikube and enable the ingress addon
minikube start
minikube addons enable ingress
As a first step, we have to install the CRD along with a role to allow to modify custom resource created for this CRD:
# Register ConfigWatcher CRD (Kubernetes >= 1.16)
kubectl create -f config-watcher-crd.yml
# For Kubernetes < 1.16 use
# kubectl create -f config-watcher-crd-v1beta1.yml
# Verify that the CRD is registered
$ kubectl get crd
NAME CREATED AT
configwatchers.k8spatterns.io 2018-12-28T17:19:28Z
The operator script itself is stored in a ConfigMap
:
# Create a configmap holding the controller shell script:
kubectl create configmap config-watcher-operator --from-file=./config-watcher-operator.sh
In order to deploy the operator a Deployment
creates a pod with two containers:
-
One Kubernetes API proxy which exposes the Kubernetes API on localhost with port 8001. The image for
k8spatterns/kubeapi-proxy
is defined in this Dockerfile. -
The main container which executes the script from the
ConfigMap
. It is based on a single Alpine base image with curl and jq included. The Dockerfile for this imagek8spattern/curl-jq
can be found here.
Both images, k8spatterns/kubeapi-proxy and k8spatterns/curl-jq are available from Docker Hub.
To create this deployment in the current namespace, call:
# Create the controller Deployment
kubectl create -f config-watcher-operator.yml
To see our operator in action, we are reusing the same super simple web application as for the Controller
example.
This image just exposes an environment variable as HTTP content on any request.
This image uses nc
to deliver the content and can be found on Docker Hub as k8spatterns/mini-http-server.
Before we deploy this app, we should tail on the log of our operator in another terminal (e.g. kubectl logs -f config-watcher-operator-….
) to see the events received by the operator as they come in.
Then create the web application itself:
# Create a sample web application with an 'expose' annotation:
kubectl create -f web-app.yml
If you look into this descriptor file, you will find the same Deployment
using our dumb HTTP server which references the content environment variable via a ConfigMap
.
In contrast to the other controller example the ConfigMap
does not contain a reference to the pods to restart.
You can access our web app directly
# Access webapp via the included Ingress obect
curl -sk https://webapp.$(minikube ip).nip.io
If you change the config map now, it doesn’t change anything.
We have to first install a concreate custom resource of kind ConfigWatcher
to trigger the operator on a config change:
# Install a ConfigWatcher custom resource
kubectl create -f config-watcher-sample.yml
# Check that the resource has been created
kubectl get configwatchers
NAME AGE
webapp-config-watcher 1m
After this connection between ConfigMap
and Pods
has been configured, change the content of ConfigMap
and watch the operator log:
# Patch config-map to update the web content
kubectl patch configmap webapp-config -p '{"data":{"message":"Greets from your smooth operator!"}}'
and then finally call the URL again to check that the content has been updated
# Access webapp via the included Ingress object
curl -sk https://webapp.$(minikube ip).nip.io