Hello World with Kubernetes

“Hello World” with Operator SDK

Deepak Sharma
tech_vichaar
Published in
5 min readJul 29, 2020

--

“This post was originally published on Red Hat Developer. To read the original post, visit https://developers.redhat.com/blog/2020/08/21/hello-world-tutorial-with-kubernetes-operators/.”

“Operators are Kubernetes applications.”

Kubernetes Operators are built to reduce the work of Human operators or SREs.

I won’t be doing justice by giving you guys any half baked definition. So, the best source of this definition is from the creators itself.

When I started building Operators with operator-sdk there are a number of unknowns that were difficult to address. At the same moment, I decided to come up with a guided journey of introduction to SDK.

Hang tight!

AIM

Operator SDK is used to make/deploy a complex app in Kubernetes, but here for sake of brevity and understanding, we will create a bare basic namespace scoped Operator in Golang.

We will build a deployment and set up a service. Our custom controller reconciliation loop will keep a watch on our deployed resources.

Few prerequisites for this guided Journey:

  • You should be familiar with any Programming language, best if Golang.
  • minikube installed

Environment setup

In this section, we will be installing a few utilities, which will be helpful for us in building our operator.

Setup Golang

We will be building an operator using Golang.

Install it from here

Set $GOPATH= ”/your/preffered/path/”
$GO111MODULE=on

and other necessities that you feel.

# Verify
$ go version
go version go1.13.3 linux/amd64

Setup SDK

We will be using Operator SDK to build our operator

Install Operator SDK from here

# Verify
$ operator-sdk version
operator-sdk version: "v0.17.0", commit: "2fd7019f856cdb6f6618e2c3c80d15c3c79d1b6c", kubernetes version: "unknown", go version: "go1.13.10 linux/amd64"

Building Operator

At the end of each section, I will be sharing the file tree. Please do verify to keep things in sync.

Scaffolding

Head over to $GOPATH/src/operators and run

$ operator-sdk new hello-operator

This command is used to generate a Boilerplate code. The default operator type is GO.

By now we should have a file tree-like this.

Adding Custom Resource Definition

CRD’s are used to introduce Custom Resource (kind) understandable by our K8s deployment only.

$ operator-sdk add api --api-version=example.com/v1alpha1 --kind=Traveller

— api-version: It is actually used to namespace our operator, in format (group/version)

— kind: custom kind, will be used by all our following CRs.

By now you should have a file tree like this.

Updating Custom Resource

Specs are like hardcoded Config values. It is also called as the desired state of the cluster. In this section, we will be editing 2 files

  1. Update example.com_v1alpha1_traveller_cr.yaml

We can add any custom values that are likely to be needed for our controller functioning. Here we will be adding:

image: paulbouwer/hello-kubernetes:1.8
deploy > crds > example.com_v1alpha1_traveller_cr.yaml

2. Update traveller_types.go

This will bring custom values to controllers. Please note to keep variables in Titlecase.

Eg: {Variable} {type} {json:"name in *_cr.yaml" }

pkg > apis > example > v1aplha1 > traveller_types.go

To update the generated code for that resource type, make sure to run

$ operator-sdk generate k8s

After each edit in *_types.go, CRD needs to be updated to add open API validations against newly introduced values. This process is completely automated by

$ operator-sdk generate crds

This should produce this diff.

Add Controller

Controllers are deployed for defining Reconcile logic and to define which cluster resources to keep Watch. Any change in the watched resource will trigger an event which triggers reconciliation in our controller

$ operator-sdk add controller --api-version=example.com/v1alpha1 --kind=Traveller

Find and verify Code Diff we added here.

Till now Controller is added accompanied by default APIs with default RBAC roles and Service accounts. Now we will jump into writing a few lines of code to add logic for creating Deployment and service.

We will make sure whatever the logic we write should be Idempotent.

Add Custom Logic

We will be adding 5 custom functions-

  1. backendDeployment : Deployment for Pod. Exposes 8080 Port.
  2. backendService: Make a new Service for exposed Port.
  3. ensureDeployment: Ensures presence of Deployment in the given namespace. If not, it will create Deployment by calling 1.
  4. ensureService: Ensures service is preset and running in a given namespace. If not, it will create Service by calling 2.
  5. labels: Sets labels on Deployment and Pods

Last but not least, Add a change in Reconcile function to trigger all new defined functions. See this.

After this section, Code diff should look like this.

Make a Build

By now, we are done adding custom logic and building up the functionality.

We will Test the operator locally.

# Please deploy in Sequence only
$ kubectl apply -f deploy/role.yaml
$ kubectl apply -f deploy/service_account.yaml
$ kubectl apply -f deploy/role_binding.yaml
$ kubectl apply -f deploy/crds/example.com_travellers_crd.yaml
$ kubectl apply -f deploy/crds/*_cr.yaml

After successful deployments of the above artifacts, Proceed to run operator locally by

$ operator-sdk run up --local

This should start up the operator. Now make sure all our custom resources are well deployed by checking against namespace. For brevity, we are on “default” namespace.

$ kubectl get all
kubectl get all

Finally, Test our service in minikube by opening up a tunnel,

$ minikube service backend-service
minikube service backend-service

This should redirect us to-

Voilaaa! We have developed our first Basic Operator.

Export

For Deployments in real clusters, we need to export the Operator.

$ operator-sdk build docker_username/repo:v0.0.1
$ docker push docker_username/repo
$ sed -i "" 's|REPLACE_IMAGE|quay.io/example/memcached-operator:v0.0.1|g' deploy/operator.yaml
$ kubectl apply -f deploy/operator.yaml

Publish it via Git, SCM, or zip or Mail it, whatever.

I again want to emphasize that Operators are introduced to Simplify much complex App deployments on Kubernetes by keeping in mind day 2 functionalities like Upgrading / Downgrading etc but Yes, the above activity should be a good starting point to get us Introduced to the concept.

Check out repo for Final Code

References:

Catch me on https://finddeepak.com

Thank you for reading. If you believe I missed something, please leave a comment!

--

--

Deepak Sharma
tech_vichaar

Software Engineer @RedHat. Loves R&D, DevOps, and Engineering. Football and Chess are Love. https://finddeepak.com