Enabling GitOps in k8s with Helm Controller (CRD).

Francisco Bobadilla
IoTOps
Published in
3 min readFeb 6, 2020

A couple of months ago I was trying to run k8s on a raspberry pi @ home, that was when I first met k3s, and their neat way to deploy helm charts completely fascinated me. They called it helm-controller. It was so simple, so…… tiller-less. Back then helm v3 was not around so that was a game changer then. Currently the tiller is no longer a problem, how ever when you try to automate chart deployments with a pipeline you still need to maintain some state.

If you are not familiar with what rancher’s k3s or helm-controller I would suggest you go take a look at this article first and then (once you are amazed) come back and continue reading this piece.

So now that I knew this was possible I wanted to deploy everywhere in this fashion, but not all k8s flavors come with a “helm-controller“ right out-of-the-box.

The solution was simple go and that deployed in my k8s cluster and enjoy it. How ever simple not necessarily means easy. I had to work it a little bit to get that running on my cluster.

Here is how I did it. Note that these steps will deploy RBAC settings, the CRD and the deployment that watches the CRD in the helm-controller namespace. You probably will need to adjust some settings to your environment.

In this example, I will be deploying bitnami’s nginx chart.

First deploy the CRD, RBAC and helm-controller deployment.

$ kubectl apply -f https://raw.githubusercontent.com/iotops/helm-controller/master/manifests/deploy-namespaced.yamlnamespace/helm-controller created
customresourcedefinition.apiextensions.k8s.io/helmcharts.helm.cattle.io created
deployment.apps/helm-controller created
clusterrole.rbac.authorization.k8s.io/helm-controller created
clusterrolebinding.rbac.authorization.k8s.io/helm-controller created

Verify everything is there.

$ kubectl get all -n helm-controller
NAME READY STATUS RESTARTS AGE
pod/helm-controller-86dd4bc695-jjj28 1/1 Running 0 12m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/helm-controller 1/1 1 1 12m
NAME DESIRED CURRENT READY AGE
replicaset.apps/helm-controller-86dd4bc695 1 1 1 12m
$ kubectl api-resources | grep -i helm
helmcharts helm.cattle.io true HelmChart

With the helm controller installed lets deploy the following manifest.

apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: nginx
namespace: helm-controller
spec:
chart: https://charts.bitnami.com/bitnami/nginx-5.1.4.tgz
targetNamespace: default

This manifest can be download, git cloned or simply deployed from the web as follows.

$ kubectl apply -f https://raw.githubusercontent.com/iotops/helm-controller/master/manifests/example-helmchart.yamlhelmchart.helm.cattle.io/nginx created

Lets check nginx was deployed.

$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/nginx-d58c4d75d-lbhkd 1/1 Running 0 94s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 100.64.0.1 <none> 443/TCP 27m
service/nginx LoadBalancer 100.70.186.15 a54156bcaa24642e48c398d99b8e8b07-143731831.us-east-2.elb.amazonaws.com 80:31948/TCP,443:30058/TCP 94s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 1/1 1 1 95s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-d58c4d75d 1 1 1 95s

Let's open that elb address on a web browser.

nginx welcome page displayed on a firefox
Nginx chart successfully deployed

The chart can easily be updated and deleted with the same manifest, it can also be patched and edited with regular kubectl magic.

Lest remove the chart now.

$ kubectl delete -f https://raw.githubusercontent.com/iotops/helm-controller/master/manifests/example-helmchart.yamlhelmchart.helm.cattle.io "nginx" deleted$ kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 100.64.0.1 <none> 443/TCP 34m

With the helm-controller charts can be easily installed in a gitops approach with out maintaining states in the deployer's host. The manifest also allows to overwrite default chart's values individually or by a whole different values.yaml file.

I hope you enjoyed this article.

--

--

Francisco Bobadilla
IoTOps
Editor for

Head of DevOps @ ThirdPartyTrust. Full time father and husband. Outdoor enthusiast. And passionate about of open source solutions.