Build Kubernetes Operator using Kubebuilder

Introduction

Hari Manikkothu
Kubernetes
7 min readDec 25, 2019

--

Building Kubernetes API involves writing a lot of boiler plate codes and CRDs. There are many ways to implement the Operators for kubernetes, Kubebuilder framework is one of such tool to easily create required boiler plate codes and necessary CRDs. Other tools include KUDO, Operator Framework,and Metacontroller. This article provides a walk through of a sample operator implementation using Kubebuilder framework.

Operator

Operator is a type of controller that implements a specific operational logic to manage a group of resources. Operator makes use of the control loop to manage the resources’ state. The control loop logic brings the state of the target resource to from the current state to the desired state.

CRD

CRD — Custom Resource Definition — defines a Custom Resource which is not available in the default Kubernetes implementation.

E.g.

The CRD alone doesn’t do anything, a controller/operator needs to be implemented to create and manage the resources for the CRD (‘Foo’ in the example above).

Kubebuilder

Kubebuilder is a framework for building Kubernetes APIs / Operators, which helps to generate a set of boiler plate codes for the Controller, and related CRDs.

Kubernetes API Terminology

Groups and Version —An API Group in Kubernetes is a collection of related functionality. Each group has one or more versions, which allow to change how an API works over time.

e.g. When we define “apiVersion: webapp.demo.my-watchlist.io/v1” in a CRD yaml file, the ‘webapp.demo.my-watchlist.io’ part indicates the group name, and ‘v1’ indicates the version.

Kind and Resources — Each API group-version contains one or more kubernetes API types, which is called as a ‘Kind’.

A Kind consists of Metadata + Spec + Status + List. Typically the spec contains the desired state and the status contains the observed state.

Example:

MyWatchlist Operator Demo

The goal of this demo is to deploy the my-watchlist-go-redis-demo using operators and CRDs. A high level view of the deployment is depicted in the diagram below.

Setup

Init (go mod, kubebuilder)

Use the following commands to scaffold the basic project structure.

The above command will generate the main.go file and a set of scaffold configs under the ‘config’ directory.

Create API types and Controllers

Create a new Kind ‘MyWatchlist’ and its controller using the following command.

The intended yaml structure for the ‘MyWatchlist’ deployment is as follows, note that this structure will drive how we want to implement the controller.

Implement the ‘MyWatchlist’ types to match the above desired structure. Note the // +kubebuilder code generation markers are used for automatic CRD generation, and validations (https://book.kubebuilder.io/reference/markers.html).

Since there is a new struc ‘FrontendSpec’ added, use the following to auto generate the required deepcopy methods.

The intended frontend deployment for the MyWatchlist Kind is similar to https://github.com/hmanikkothu/my-watchlist-go-redis-demo/blob/master/watchlist-app-deployment.yaml. So implement the controller logic in the ‘Reconcile’ method to create a ‘Deployment’ kind and ‘Service’ kind in the cluster that matches desired structure.

/controllers/mywatchlist_controller.go

Note the +kubebuilder markers, these are required for the operator to be able to update the ‘mywatchlist’ resources. Second set of markers is required for the operator to be able to create the Deployment and Service.

Next step is to retrieve the ‘MyWatchlist’ object, and related ‘Redis’ object. Note that the MyWatchlist has a dependency on redis object, so the redis kind should be deployed for the ‘MyWatchlist’ reconciler to complete successfully.

The following code creates the ‘watchlist’ frontend Deployment and related Service.

Next step is to update the MyWatchlistSatus.URL with the value of the service url.

Note the service created in this example is of type ‘LoadBalancer’. The Status.URL will be displayed with the ‘kubectl get mywatchlist’, and the url can be used to access the frontend UI. Some dev clusters (e.g. Kind cluster) does not support the service type ‘LoadBalancer’, so some kind of port forwarding commands can be used to view the UI. e.g. kubectl port-forward svc/mywatchlist-sample 7000:8080

Entire code for the MyWatchlist controller implementation can be found here.

Follow similar approach to implement the ‘Redis’ controller as well — a completed code can be found here.

Generate Manifests

Use the following to generate manifests

An updated set of manifest for the CRDs will be generated at the folder ‘config/crd/base’ as per the API Types and kubebuilder markers.

Run locally

Now it’s time to apply the CRDs and run controller locally to test.

Use the following command to run and test the controller locally.

Now, if everything is fine, the output will show a bunch of messages indicating successful completion of the Reconcile loop.

Publish to Docker Repo

Use the following command in order to build a docker image, and push it to the repo

RBAC

Notice the autogenerated files in the folder ‘config/rbac’. role.yaml defines the manager-role role with necessary permissions for mywatchlist and redis resources as per the info provided through the kubebuilder markers. Additionally, for this sample it requires permissions to manage deployment and services to deploy the necessary pods and services.

Deploy from Docker Repo

Now that we have the operator available as a docker image, use the following to directly deploy the controller from docker repo.

This would create necessary controller in the namespace provided in the ‘/config/default/kustomization.yaml’, e.g. ‘watchlist-operator-system’

Now, use the following to deploy Redis and MyWatchlist CRDs

Verify

Verify that the controller is deployed in ‘watchlist-operator-system’ namespace

Verify that the pods and services for frontend and Redis are created in the default namespace

Get the URL to test the UI

Or use port-forward option with kubectl

Navigate to the frontend UI

References

--

--

Hari Manikkothu
Kubernetes

kubernetes enthusiast | AWS certified Solution Architect