Helm adds a templating language on top of the standard Kubernetes YAML. You turn your object specs into templates with variables for values which need to change between releases or environments - like the image tag to use, or the number of replicas. Helm has its own CLI which you use to install and upgrade apps, but the deployed objects are standard Kubernetes resources you can manage with Kubectl.
Application packages in Helm are called charts, and you can install a chart from a local folder, a compressed archive, or from a remote chart repository (similar to Docker Hub, but for apps). Charts just contain the YAML templates so they're small downloads - container images are still pulled from the image registry.
Helm uses the same context configuration as Kubectl to connect to your Kubernetes cluster(s). To start with you need to install the Helm CLI:
The simple way, if you have a package manager installed:
# On Windows using Chocolatey:
choco install kubernetes-helm
# On MacOS using brew:
brew install helm
# On Linux:
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
Test you have the CLI working:
helm version --short
You should see a version number.
You shouldn't use versions of Helm earlier than v3. Older versions needed a server component running in Kubernetes, which was a security issue. From v3 onwards, Helm is a purely client-side tool which only needs the CLI.
Here's a simple Helm chart for the whoami app. The release name is used in the object names, so the same app can be deployed multiple times.
.Values.imageTag
and standard objects (e.g. .Release.Name
)📋 Use Helm to install the chart from the labs/helm/charts/whoami
folder, calling the release whoami-default
.
To install a chart with default values, just give it a name and the location of the chart:
helm install whoami-default labs/helm/charts/whoami
List your Helm releases, and check the Kubernetes objects:
helm ls
kubectl get all -l app.kubernetes.io/managed-by=Helm
You have one release installed, which created the Kubernetes Service and Deployment. The object names are based on the Helm release name.
📋 Confirm this chart could be deployed again with a new release name - check the labels applied to the Pod, and the label selector used by the Service.
kubectl get po -o wide --show-labels
kubectl describe svc whoami-default-server
Two Pods are in the Service endpoints. The selector label comes from the release name, so a second release would not interfere with this one.
Try the app:
curl localhost:30028
If you repeat the call you'll see responses load-balanced between Pods. The replica count and server mode are variables, currently using the default settings in the values file.
Any field in the values file can be overridden when you install or upgrade a release, using the set
flag with the Helm CLI.
📋 Install a new release from the same whoami chart, called whoami-custom
. Set the replica count to 1 and the Service port to 30038
.
You can use multiple set
flags, providing the variable name and value:
helm install whoami-custom --set replicaCount=1 --set serviceNodePort=30038 labs/helm/charts/whoami
Validate your new release of the app is deployed:
helm ls
kubectl get pods -l component=server -L app
You should see one Pod with the app label
whoami-custom
, and two with the labelwhoami-default
.
Your new Service should be listening at the specified port:
curl localhost:30038
You can upgrade a release with the Helm CLI. You do this to update to a new chart version, or use the same chart and change the deployed values.
Try to update the custom release, settings a new value for the server mode:
# this will fail:
helm upgrade whoami-custom --set serverMode=V labs/helm/charts/whoami
Custom values from the install are not reused. The upgrade tries to change the port value from the custom one to the default, which is already in use from the other release.
📋 Repeat the upgrade command, but add a flag so Helm will reuse the values from the original install command.
The Helm upgrade options provide the reuse-values
flag:
helm upgrade whoami-custom --reuse-values --set serverMode=V labs/helm/charts/whoami
Now the custom port from the install is reused, and only the server mode is changed.
Try the app now:
curl localhost:30038
Check the ReplicaSets for the custom install and you can see that Helm just makes changes to the Kubernetes objects - the Deployment got updated and it rolled out the change in the usual way:
kubectl get rs -l app=whoami-custom
📋 You can also use Helm to roll back releases. Check the history of the custom app and roll back to the first revision.
The history command lists all the revisions of the release, and the rollback command reverts to a previous revision.
helm history whoami-custom
helm rollback whoami-custom 1
After the rollback, check the ReplicaSets and you'll see the original has scaled back up:
kubectl get rs -l app=whoami-custom
And the app is working with the "quiet" server mode:
curl localhost:30038
Some teams use Helm to package their own apps - others stick with YAML files and only use Helm to deploy third-party apps.
Projects like Prometheus and the Nginx Ingress Controller publish packages as Helm charts, which makes it easy for you to install a production-grade release.
Charts are published in repositories, which can be public or private. Start by adding a simple repo:
helm repo ls
helm repo add kiamol https://kiamol.net
helm repo update
Adding and updating chart repositories is similar to package managers like APT and APK on Linux.
📋 Search the repositories for a chart called vweb
, and list the default values for the version 2.0.0
chart.
The search command looks across all repos:
helm search repo vweb --versions
There are two version numbers for each line - the app version and the chart version. Charts can evolve independently, so the same app version might have multiple charts.
Default values are packaged in the chart, and you can print them from the CLI, using the repo name and chart details:
helm show values kiamol/vweb --version 2.0.0
The values file is YAML, so it can contain comments - very helpful for users.
📋 Install a release called vweb
from the kiamol/vweb
chart at version 2.0.0
, using a NodePort service listening on port 30039.
It's the same install command, specifying the chart version and the location includes the repo name:
helm install --set replicaCount=1 --set serviceType=NodePort --set servicePort=30039 vweb kiamol/vweb --version 2.0.0
List the Services to confirm the deployment:
kubectl get svc -l app.kubernetes.io/instance=vweb
You should be able to browse to the app at http://localhost:30039. It's not very exciting.
Upgrades don't have to use a newer version. You can downgrade to the version 1.0.0
chart of this app, but it might not do what you think.
📋 Check the default values for the 1.0.0
release, and upgrade to that version. How do you access the site now?
helm show values kiamol/vweb --version 1.0.0
# the v1 chart doesn't let you choose the service type, only the port
helm upgrade --reuse-values vweb kiamol/vweb --version 1.0.0
The "upgrade" works, but the v1 chart doesn't have a variable for the Service type, it's fixed as LoadBalancer. The app is still available at http://localhost:30039, but only if your cluster supports LoadBalancer services.
You can use a local values file to override the defaults in a chart, instead of using lots of set
arguments.
This values file is suitable for the Nginx ingress controller chart in a local environment:
Install the Nginx Ingress controller from the public Helm chart, using at least version 1.3.0
of the app. Use a new namespace called ingress
. Browse to the HTTP endpoint and confirm you get a response from Nginx.
Remove all the Helm releases:
helm uninstall vweb whoami-custom whoami-default
helm uninstall ingress-nginx -n ingress
kubectl delete ns ingress