Helm workshop: Build your first chart
Create a simple webserver chart
In order to get familiar with a typical chart we will create a simple webserver chart.
1$ helm create web
2Creating web
The above command will create a chart directory named web
web/ | ||
---|---|---|
charts | directory that contains the subcharts | |
Chart.yaml | metadatas (author, version, description), dependencies and more | |
templates | contains all the templates basically kubernetes resources in the form of templated yaml files. (go template) | |
deployment.yaml | ||
helpers.tpl | helpers, functions that can be used from the templates. | |
hpa.yaml | ||
ingress.yaml | ||
NOTES.txt | This file is used to print information after a release has been successfully installed. | |
serviceaccount.yaml | ||
service.yaml | ||
tests | contains a job that will run a command to check the application after it has been installed. | |
test-connection.yaml | ||
values.yaml | Maybe the most important file. We’ll play with the values to define how the kubernetes resources will be rendered. |
Testing the chart
Here’s a combo if you want to check properly your chart before actually deploying it:
template + lint + kubeval + test
Golang errors
When you add templating changes, you should run the command helm template --debug <chart_dir>
1$ helm template --debug web
2install.go:173: [debug] Original chart version: ""
3install.go:190: [debug] CHART PATH: /tmp/web
4
5Error: parse error at (web/templates/_helpers.tpl:73): unexpected EOF
6helm.go:81: [debug] parse error at (web/templates/_helpers.tpl:73): unexpected EOF
Read carefully if there are error messages. Always use the option --debug to see the template rendering.
Chart linting
The command helm lint <chart_dir>
verifies that the chart is well-formed.
1$ helm lint web/
2==> Linting web/
3[ERROR] Chart.yaml: apiVersion 'v3' is not valid. The value must be either "v1" or "v2"
4[INFO] Chart.yaml: icon is recommended
5[ERROR] Chart.yaml: chart type is not valid in apiVersion 'v3'. It is valid in apiVersion 'v2'
6
7Error: 1 chart(s) linted, 1 chart(s) failed
Validate Kubernetes resources
In order to validate that the rendered kubernetes objects are well-formed we’ll make use of a tool named kubeval.
This is even easier by using the Helm plugin.
Install the plugin:
1$ helm plugin install https://github.com/instrumenta/helm-kubeval
2Installing helm-kubeval v0.13.0 ...
3helm-kubeval 0.13.0 is installed.
Then check the chart as follows
1$ helm kubeval web
2The file web/templates/serviceaccount.yaml contains a valid ServiceAccount
3The file web/templates/secret.yaml contains a valid Secret
4...
Now you can safely install the chart
1$ helm upgrade --install web web
2Release "web" has been upgraded. Happy Helming!
3NAME: web
4LAST DEPLOYED: Mon Feb 15 18:22:23 2021
5NAMESPACE: default
6STATUS: deployed
7REVISION: 1
Check that the application works as expected
This is a good practice to add tests under the directory template/tests.
Basically, this is achieved with a job that you can call when the release is already installed (just after)
It returns a code 0 if the command succeeds.
In the chart we’ve already generated there’s a job that checks the webserver availability.
Check that the release is already installed
1helm list
2NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
3web default 1 2021-02-15 15:11:09.036602795 +0100 CET deployed web-0.1.0 1.16.0
1helm test web
2NAME: web
3LAST DEPLOYED: Mon Feb 15 15:11:09 2021
4NAMESPACE: default
5STATUS: deployed
6REVISION: 1
7TEST SUITE: web-test-connection
8Last Started: Mon Feb 15 16:55:17 2021
9Last Completed: Mon Feb 15 16:55:19 2021
10Phase: Succeeded
Dependencies
Sometimes, the application requires another component to work (caching, database, persistence …).
This dependency system has to be used with caution because this is generally recommended to manage the applications lifecycles independently from each other.
Let’s say that our webserver need to store the information related to the sessions in a Redis server.
We’ll add a redis server to our web application by declaring the dependency in the file chart.yaml.
1dependencies:
2 - name: redis
3 version: "12.6.4"
4 repository: https://charts.bitnami.com/bitnami
5 condition: redis.enabled
As you may have noticed, this dependency will be pulled only if the condition redis.enabled is True.
So we need to change our values.yaml accordingly:
1redis:
2 enabled: True
3 master:
4 persistence:
5 enabled: False
Check all the available values for this chart here.
Whenever you add a dependency and you’re using a local chart (on your laptop), you must run the following command to pull it
1helm dep update web
2Hang tight while we grab the latest from your chart repositories...
3….
4...Successfully got an update from the "bitnami" chart repository
5Update Complete. ⎈Happy Helming!⎈
6Saving 1 charts
7Downloading redis from repo https://charts.bitnami.com/bitnami
8Deleting outdated charts
The dependencies are stored in the directory charts.
After testing your changes you can install the release with the command
helm upgrade --install <release_name> <chart_dir>
1helm upgrade --install web web
2Release "web" has been upgraded. Happy Helming!
3NAME: web
4LAST DEPLOYED: Mon Feb 15 18:22:23 2021
5NAMESPACE: default
6STATUS: deployed
7REVISION: 2
You can notice that your webserver has been successfully installed along with a HA Redis cluster
1kubectl get po
2NAME READY STATUS RESTARTS AGE
3web-74bf5c6c66-fjsmb 1/1 Running 0 3h14m
4web-test-connection 0/1 Completed 0 90m
5web-redis-master-0 1/1 Running 0 3m14s
6web-redis-slave-0 1/1 Running 0 3m14s
7web-redis-slave-1 1/1 Running 0 2m42s
Hooks
Helm comes with a hook system that allows it to run jobs at given times of the lifecycle.
The description is crystal clear in the documentation and you’ll have the opportunity to add one later on during this workshop.
Mastering the Golang template
The main challenge when you start using Helm is to learn all the tips and tricks of the Golang template
The official Helm documentation is very useful for that.
Your best friends when you write Helm templates are the Sprig functions, you should definitely add this to your bookmarks.
Furthermore, even if it has been deprecated, you should clone/fork the original stable chart repository. Indeed it has a wide range of examples.
Note that most of the time, if you want to keep the kubernetes manifests readable, you would put most of the code in what we call helpers files. There’s often at least one named _helpers.tpl.
Note: Even if you can do pretty advanced things with this templating language, you shouldn’t overuse it in order to keep the kubernetes resources readable and the chart maintainable.