Understanding Kubernetes deployments with Helm
I am trying to understand all the YAML code we have in our solution for deploying to Kubernetes. I’ve got three hours today, here’s what I learnt.
What is a Kubernetes object?
A Kubernetes object represents how you would like your cluster to behave in Kubernetes — it describes which applications are running, the resources available to those applications, and any policies that have been set.
There are two main parts to a Kubernetes object — the spec and the status.
- The spec is set when you create the object and describes what you want to happen in your cluster.
- The status is the current state of the object which is continually updated by the Kubernetes system. Kubernetes ensures that the two states match.
This example is taken from the Kubernetes documentation, which I thought was helpful to explain the concept:
For example: in Kubernetes, a Deployment is an object that can represent an application running on your cluster. When you create the Deployment, you might set the Deployment
spec
to specify that you want three replicas of the application to be running. The Kubernetes system reads the Deployment spec and starts three instances of your desired application--updating the status to match your spec. If any of those instances should fail (a status change), the Kubernetes system responds to the difference between spec and status by making a correction--in this case, starting a replacement instance.
What is Helm?
Without Helm, you would need to create your own YAML files to define the state of a Kubernetes object, which is known as a manifest file. This can be quite complex and result in lots of files and duplicate code.
Helm helps to make the process of doing Kubernetes deployments easier. It is a package manager for Kubernetes and works like the package managers you may be familiar with (e.g. NuGet for .NET). It installs software and dependencies, upgrades it and configures software deployments.
What are charts?
I see there is a folder called charts in our solution — Helm packages are called charts and they consist of some YAML config files and some templates.
Here’s an overview of the files included:
- The templates folder has template files that are combined with the config values from the values.yaml file to create the Kubernetes manifests.
- The Chart.yaml file includes data about the chart e.g. name and version and details of who is the maintainer.
- The values.yaml file has default configuration values for the chart.
How does a release work?
During a release, Helm combines the chart templates with the configuration in the values.yaml. This is turned into Kubernetes manifests which are then deployed via the Kubernetes API.
Understanding YAML templates in Helm
- The template files have template directives embedded in so you can use {{ …}} to inject in objects.
- Template files can include {{ .Values.whatever.whateverelse }} which uses the values which you have added to your values.yaml file. There are other built-in objects which may be helpful — more detail here in the Helm Docs.
- $ is used to define a variable and := is used to assign a value.
- $ is also useful if you are looping in a range and you want to access a value outside of the range.
- |- declares a multi-line string.
- {{- … -}} will chomp the white space from left and right — needed if you have an if statement on its own line for example, otherwise a blank line will appear in the YAML file.
- You can use if / else for conditional blocks and range for a “for each” loop. For example: {{- range $.Values.deployments -}} means go through each of the items in the deployments list in the values.yaml file.
Conclusion
I am now able to understand the code that is included in the charts folder of my solution and I appreciate what it is doing now. My next step is to look more deeply into the YAML Azure pipeline to make sure I can understand exactly what is happening there too.