Kubernetes CRD and Operator — a basic exercise for beginners

  • Kubernetes cluster
  • Basic knowledge using Kubernetes
  • Golang setup for development

What are CRDs

What is an operator

Use case we will be building

  • A CRD that represents a Compute VM/Bare Metal in a cloud infrastructure
  • An operator that will create an actual VM/Bare Metal when a CRD is created

What options do we have

Installations

go

Go to: https://golang.org/doc/install
Install the binary or from source
Test the installation by:
go version

kubebuilder

Source: https://book.kubebuilder.io/quick-start.html
os=$(go env GOOS)
arch=$(go env GOARCH)
curl -L https://go.kubebuilder.io/dl/2.3.1/${os}/${arch} | tar -xz -C /tmp/
sudo mv /tmp/kubebuilder_2.3.1_${os}_${arch} /usr/local/kubebuilder
export PATH=$PATH:/usr/local/kubebuilder/bin

kustomize

Source: https://kubectl.docs.kubernetes.io/installation/kustomize/binaries/
curl -s "https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash

Let’s initialise our development directory

mkdir ~/cloudbuilder
cd ~/cloudbuilder/
go mod init cloudbuilder
kubebuilder init --domain example.com

Now, let’s build the CRD

kubebuilder create api --group cloudbuilder --kind Compute --version v1alpha1
Create Resource [y/n]
y
Create Controller [y/n]
y
  • api/v1alpha1/compute_types.go — This defines the structure of your new type.
  • controllers/compute_controller.go — This defines the actions to be performed when a reconcile occurs on a custom resource of this type.
type ComputeSpec struct {
CloudProviderName string `json:"cloudprovidername"`
ComputeName string `json:"computename"`
OSImage string `json:"osimage"`
Shape string `json:"shape"`
Region string `json:"region"`
Zone string `json:"zone"`
}
make manifests
  • config/crd/bases/cloudbuilder.example.com_computes.yaml
kubectl apply -f config/crd/bases/cloudbuilder.example.com_computes.yaml
# This is an alternative to above
make install

Okay, shall we create a resource on a cluster?

apiVersion: cloudbuilder.example.com/v1alpha1
kind: Compute
metadata:
name: demoinstance
spec:
cloudprovidername: <cloud_provider>
computename: DemoInstance
osimage: centos-8
shape: <shape_available_in_cloud_provider>
region: <region>
zone: <zone>
network: <network>
kubectl apply -f config/samples/cloudbuilder_v1alpha1_compute.yaml

And then build the operator

// +kubebuilder:rbac:groups=cloudbuilder.example.com,resources=computes,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=cloudbuilder.example.com,resources=computes/status,verbs=get;update;patch
func (r *ComputeReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
ctx := context.Background()
log := r.Log.WithValues("compute", req.NamespacedName)

log.Info("This is not a perfect code and is only for the purpose of the blog")
compute := &cloudbuilderv1alpha1.Compute{}
err := r.Get(ctx, req.NamespacedName, compute)
if err != nil {
return ctrl.Result{}, err
}
computeName := compute.Spec.ComputeName
log.Info("Compute resource record created in cluster. Creating compute on cloud platform with name: " + computeName)
switch compute.Spec.CloudProviderName {
case "<cloud_provider_1>":
if error := r.create<cloud_provider_1>Compute(ctx, log, compute); error != nil {
log.Error(err, "Compute create failed for: "+computeName)
return ctrl.Result{}, error
}
case "<cloud_provider_2>":
if error := r.create<cloud_provider_2>Compute(ctx, log, compute); error != nil {
log.Error(err, "Compute create failed for: "+computeName)
return ctrl.Result{}, error
}
default:
log.Info("Unknown cloud provider")
}
return ctrl.Result{}, nil
}

Test it locally

make run

Finally, publishing the docker image

make docker-build docker-push IMG=akfarooqnaveen/cloudbuilder-compute:v1alpha1
make deploy IMG=akfarooqnaveen/cloudbuilder-compute:v1alpha1

Thank you!

Related links

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Farooq Naveen A K

Farooq Naveen A K

Software Engineer | Site Reliability Engineering