A simple tutorial on how to create a Kubernetes Helm Operator ie. a Kubernetes Operator from a Helm Chart
A means of packaging up a collection of K8s specifications (such as yaml files) in a managed idempotent fashion. For example, a simple Helm Chart may contain deployment.yaml a service.yaml files with placeholders for number of replicas, name etc.
By default, K8s comes with several exisiting resource Kind
types. For example, some pre-packed native K8s resources are Deployment
and Service
. Basically, the contents of the Kind
field in yaml spec. An operator is an example of a Custom Kind
a.k.a. Custom Resource Definition (CRD) called what ever you want eg Foo, Bar, MyKind ... You get the idea.
A Helm Operator takes an existing Helm Chart as input and magicallly creates a CRD (say MyKind) out of it (that will need to be installed on the target K8s cluster). Then, the CRD can be operated upon as a first class K8s citizen eg kubectl create MyKind abcd
- First Class K8s Citizen
- Can be managed using kubectl commands
The following example describes how to create. install and use a Helm Operator from a Helm Chart
- Install helm
- Install the operator sdk
- Login to your dockerhub account from the command line
helm create nginx-app
helm package nginx-app
operator-sdk new my-nginx-operator --kind=MyNginx --type=helm --helm-chart nginx-app-0.1.0.tgz
export DH_USER=<your dockerhub userid eg johnsmith>
cd my-nginx-operator
operator-sdk build $DH_USER/my-nginx-operator:0.1.0
docker push $DH_USER/my-nginx-operator:0.1.0
sed -i "s|REPLACE_IMAGE|$DH_USER/my-nginx-operator:0.1.0|g" deploy/operator.yaml
Note: If your K8s cluster is on a separate machine, copy the deploy
directory to the cluster master node
kubectl apply --validate=false -f deploy/crds/*_crd.yaml
kubectl apply -f deploy/operator.yaml
kubectl apply -f deploy/role_binding.yaml
kubectl apply -f deploy/role.yaml
kubectl apply -f deploy/service_account.yaml
-
A usable sample specification of the
MyNginx
spec has been autogenerated atdeploy/crds/charts.helm.k8s.io_v1alpha1_mynginx_cr.yaml
-
Edit it as desired, for example, you may want to change the name (to "example-nginx") and the number of replicas (to 4).
sed -i "s|replicaCount: 1|replicaCount: 4|g" deploy/crds/*_cr.yaml
sed -i "s|name: example-nginx|name: example-nginx|g" deploy/crds/*_cr.yaml
- Apply the modified spec
kubectl apply -f deploy/crds/*_cr.yaml
Note: After applying the spec, if we chose to modify the name (and other fields) of the CR instance (say to "example-nginx-2") and re-apply the spec, 2 instances of the CR will be created ie. example-mynginx and example-mynginx-2 .
Note how we can address the CR Directly
$ ~/junk/my-nginx-operator/deploy/crds $ kubectl get MyNginx
NAME AGE
example-mynginx 11m
Note the operator deployment, and also a deployment for the sample Nginx service as a result of the CRD
$ ~/junk/my-nginx-operator/deploy/crds $ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
example-mynginx-nginx-app 4/4 4 4 11m
my-nginx-operator 1/1 1 1 13m
....
Note that an Nginx is running at port 80
$ ~/junk/my-nginx-operator/deploy/crds $ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
example-mynginx-nginx-app ClusterIP 10.43.183.123 <none> 80/TCP 11m
...
We can connect to this server
$ ~/junk/my-nginx-operator/deploy/crds $ curl http://10.43.183.123:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
.
.
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Note that there are 4 instances of Nginx running, as per our modifications
$ ~/junk/my-nginx-operator/deploy/crds $ kubectl get po
NAME READY STATUS RESTARTS AGE
example-mynginx-nginx-app-7dfc477d84-8857k 1/1 Running 0 11m
example-mynginx-nginx-app-7dfc477d84-9n5jt 1/1 Running 0 11m
example-mynginx-nginx-app-7dfc477d84-kpnvx 1/1 Running 0 11m
example-mynginx-nginx-app-7dfc477d84-z7h48 1/1 Running 0 11m
...
If we want to delete the instance of the CRD we just created, merely execute
$ ~/junk/my-nginx-operator/deploy/crds $ kubectl delete MyNginx example-mynginx
mynginx.charts.helm.k8s.io "example-mynginx" deleted
$ ~/junk/my-nginx-operator/deploy/crds $ kubectl get po
NAME READY STATUS RESTARTS AGE
example-mynginx-nginx-app-7dfc477d84-8857k 0/1 Terminating 0 20m
example-mynginx-nginx-app-7dfc477d84-9n5jt 0/1 Terminating 0 20m
example-mynginx-nginx-app-7dfc477d84-z7h48 0/1 Terminating 0 20m
...