/pwatcher

Example Kubernetes Controller built with Kubebuilder

Primary LanguageGoApache License 2.0Apache-2.0

pwatcher

Example Kubernetes Controller built with the kubebuilder to showcase different use-cases in a controller.

pwatcher is a Kubernetes controller which:

  • Listens for new pods
  • Annotates those pods with a timestamp
  • Logs the pod and timestamp to stdout
  • Only respond to pods with a particular annotation (e.g. observable=true)
  • Only respond to pods in namespaces with a particular annotation (e.g. observable=true)
  • Implement leader election

Use Cases

Listens for new pods

To listen for only new pods, we used predicate to supress Update, Delete, Generic events.

This filtering only leaves us with Create event. Requests against this event will now be passed on to the reconciler.

Annotates those pods with a timestamp

Annotate pod with current timestamp if the annotation doesn't already exist

Logs the pod and timestamp to stdout

Log the namespaced name of the pod along with the timestamp.

Only respond to pods with a particular annotation (e.g. observable=true)

To facilitate this, we added a new environment variable POD_FILTER_KEY. By using this environment variable we can specify the key for filtering. Pod should have the given key in it's annotations.

predicate was used to add this filter. We added the logic to filter out pods against Create event in the predicate.

Only respond to pods in namespaces with a particular annotation (e.g. observable=true)

To facilitate this, we added a new environment variable NAMESPACE_FILTER_KEY. By using this environment variable we can specify the key for filtering. Namespace containing the pod should have the given key in it's annotations.

predicate was used to add this filter. We added the logic to drop namespace, containing the pod, that doesn't have the required key in annotations. Create event in the predicate was used for this.

Alternate Approach

An alternate approach for this would have been to:

  1. Compute list of namespaces that contain the annotation
  2. Update manager options and specify namespaces like:
// Options are the arguments to specify manager configuration
options := ctrl.Options{}

// watchNamespace contains comma separated list of namespaces (e.g ns1,ns2)
options.Namespace = ""
options.NewCache = cache.MultiNamespacedCacheBuilder(strings.Split(watchNamespace, ","))

This idea was dropped because the biggest downside of this is that this list is populated when the controller is initialized. We cannot change this list at the runtime. So any new namespaces that will have this annotation will be ignored.

Installation

Helm Chart

For helm view chart

Kustomize

To install using kustomize

  • Ensure that kustomize is installed
  • Run VERSION=v0.0.x make deploy from the root directory to deploy controller with an image tag v0.0.x

Local Development

Requirements

Execution

  • Ensure that a valid kubeconfig is loaded
  • Run make run from the root directory to build and execute the binary

Test for filters

  • Run NAMESPACE_FILTER_KEY=pwatcher-test POD_FILTER_KEY=pwatcher-test make run to run the controller
  • Run kubectl apply -f examples/manifest.yaml to create resource that complies with the filters
  • kubectl get pod pwatcher-test -n pwatcher-test -o jsonpath='{.metadata.annotations}' to check that the pwatcher.io/timestamp annotation has been added