Authoring a Helm Chart on Kubernetes / AKS – Parametrized values


In the last article, we authored a very simple chart.

In this article I want to show how to use one of the powerful features of Helm: values.

Values act as parameters to a chart.

Having parameters is key for dev ops as we want to deploy the same chart to different environment with different parameters.

As usual, the code is in GitHub. In order to try the example in the article, simple clone the repo locally.

Let’s dive in!

A Service

Let’s start by deploying a slightly more complicated chart. That chart will deploy a service instead of a namespace.

So, from the root of the repo, we can type:

$ helm upgrade --install myservice b-service

Here we use the idempotent form of install with Helm. This command will install the first time and update subsequent time. It is equivalent to a kubectl apply.

We install the chart b-service (which is in the b-service sub folder from the repo’s root). We call the release myservice.

We can see that deployed a cluster-IP service in the b namespace:

$ kubectl get svc --namespace=b
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
my-service   ClusterIP   10.0.44.202   <none>        80/TCP    8m

It also deployed a deployment with 2 pods:

$ kubectl get deploy --namespace=b
NAME            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
my-deployment   2         2         2            2           8m

We could test the service using

kubectl run -i --tty console --image=appropriate/curl -- sh

and curling the service.

Instead, let’s look at files in the chart:

b-service/
  Chart.yaml
  README.md           # Optional but quick to write
  values.yaml         # Mandatory, but empty in our case
  templates/
    deployment.yaml    # A deployment
    namespace.yaml     # The namespace b
    service.yaml       # A service bound to the deployment
    NOTES.txt          # Optional but quick to write

This time around we have two (3) yaml files in the templates folder.

deployment.yaml, a vanilla deployment with 2 replicas:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
  labels:
    app: get-started
spec:
  replicas: 2
  selector:
    matchLabels:
      app: get-started
  template:
    metadata:
      labels:
        app: get-started
    spec:
      containers:
      - name: myapp
        image: vplauzon/get-started:part2-no-redis
        ports:
        - containerPort: 80

namespace.yaml, a vanilla namespace:

apiVersion: v1
kind: Namespace
metadata:
  name: b

service.yaml, a vanilla service of type ClusterIP:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    app: get-started

This is Helm without values, without parameters.

Namespace

Helm can override the default namespace with the --namespace option for the install.

It doesn’t manage the namespace as one would expect though. It doesn’t delete the namespace when the Helm release is deleted for instance. Similarly, it wouldn’t recreate a namespace if it gets deleted. This is a partially documented issue.

For those reasons we instead manage the namespace explicitly by declaring a namespace object. This way, when we delete the release, the namespace will go away. This is useful for the demo aspect of this article.

For traditional work the --namespace is likely more useful. Often more than one chart / release will go in one namespace. We just need to be aware of the issue mentionned above.

Enter values parameters

Now, let’s deploy another chart:

helm upgrade --install myparameteredsvc c-parametrized-service

This is c-parametrized-service.

On the surface, it is quite similar to the previous chart. It deploys a service and a deployment with 2 replicas:

$ kubectl get svc --namespace=c
NAME            TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
param-service   ClusterIP   10.0.187.51   <none>        80/TCP    3m

$ kubectl get deploy --namespace=c
NAME          DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
get-started   2         2         2            2           3m

The major difference is that this chart uses values. Let’s look at values.yaml:

#  We use parameters here:
service:
  name:  param-service # Name of the Kubernetes' service
  replicaCount: 2 # Number of pods in the replica set
deployment:
  name:  get-started # Name of the deployment

This file is a plain old YAML file. Any values in the nodes of the YAML tree can be used. For instance service.name.

For instance, let’s look at namespace.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: {{ .Values.namespace }}

We see the value for the namespace name is pulled from the values yaml tree.

The template files are leveraging GO templates.

Overriding values

We can then override the values. We can do it piece by piece, using the set option. For instance, let’s bump the number of replica from 2 to 5:

helm upgrade --install myparameteredsvc c-parametrized-service --set service.replicaCount=5

We can then confirm the number of replica was changed:

$ kubectl get deploy --namespace=c
NAME          DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
get-started   5         5         5            5           1m

Using this we can parametrize a release.

Overriding many values

Using the previous method of overriding can quickly become cumbersome.

We can instead pass a file to override values.

Let’s look at _values-override.yaml:

deployment:
  name:  my-deployment
service:
  replicaCount: 4

Here we override the replica count but also the name of deployment.

The file name starts with an underscore. This is a trick to get a file ignored in the chart folder.

We can use that file with the values option:

helm upgrade --install myparameteredsvc c-parametrized-service --values=c-parametrized-service/_values-override.yaml

We can then validate:

$ kubectl get deploy --namespace=c
NAME            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
my-deployment   4         4         4            4           30s

The number of replica and the name of the deployment just changed.

Clean up

We can clean up our cluster with the following command:

helm delete myservice myparameteredsvc --purge

The --purge option clears the releases from Helm’s audit.

Summary

Using values in our Helm chart makes them parameterizable.

This makes them much more reusable but also enables Dev Ops scenarios.

I hope this article gives you tips to enable you to leverage Helm in your Dev Ops scenarios by authoring great charts!

Advertisements

One thought on “Authoring a Helm Chart on Kubernetes / AKS – Parametrized values

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s