When deploying multiple resources to Kubernetes, it is often challenging to keep track of all the resources, image tags, and environment variables distributed across multiple manifest files. To address this issue, manifest templating tools such as Kustomize and Helm exist, simplifying large, complex manifest files to templates with customization available through values.yaml. This provides flexibility with a single template across multiple environments (e.g., QA, staging, production), with changes configured via the values.yaml file. Additionally, it offers ease-of-use for end-users to deploy into any new environment with just a single command.
However, solving one set of problems often introduces new challenges. Creating individual Helm charts can become difficult to manage as applications increase. It becomes essential to track changes across all Helm charts used by an organization, consuming significant engineering hours. Using community charts poses the challenge of pulling and customizing new charts, maintaining separate copies in the Helm repository, and consuming considerable time to pull and run these charts.
Just as we've created a Helm chart for each application, bundling all required Kubernetes resources into a single chart, it would be advantageous to bundle all these micro-services into a single chart.
Helm sub-charts are like mini-charts residing inside a larger Helm chart, akin to different players in your favorite video game. It's Helm's way of implementing inheritance. Charts can have dependencies, called subcharts, each with its values and templates.
Before creating sub-charts, consider the following:
To create a master Helm with sub-charts, consider a master Helm chart example deploying Nginx and PostgreSQL. The folder structure is as follows:
To create Helm sub-charts within the master Helm chart, add the following to the values.yaml file, describing the name of the Helm charts along with their versions and repositories.
apiVersion: v2
name: my-master-chart
description: A Helm chart to deploy Nginx and PostgreSQL
version: 0.1.0
dependencies:
- name: nginx
version: 15.4.3
repository: https://charts.bitnami.com/bitnami
- name: postgresql
version: 13.2.16
repository: https://charts.bitnami.com/bitnami
After adding the above to the values, run the following command to pull and add these dependencies to the charts folder.
helm dependency update
Once pulled, the folder structure should have .tgz files in the charts folder. To untar the .tgz file, use the command:
tar -zxvf nginx-15.4.3.tgz
After extraction, your file structure would resemble the one below:
Just as we can manipulate inputs from the values file in individual Helm charts, we can use the global values.yaml file to manipulate the values of each of these Helm charts. By doing so, we can use the base Helm charts as templates and make all modifications from the global values.yaml file. This reduces complexity and simplifies the management of different input values in various Helm charts.
Consider the following example to illustrate the use case. The values for Nginx mention the image tag, and PostgreSQL mentions the image tag along with the port number at which the PostgreSQL deployment runs. Here are the default values passed in the Nginx and PostgreSQL values.yaml files:
Now, change the values in the master values.yaml file at the top level. Change the Nginx image from 1.25.3-debian-11-r1
to 1.24.0-debian-11-r153
and the PostgreSQL image from 16.1.0-debian-11-r9
to 15.5.0-debian-11-r9
. Also, change the PostgreSQL default port from 5432
to 5111
.
The values for both Nginx and PostgreSQL images have changed, and the PostgreSQL port has been updated.
Liked my content? Feel free to reach out to my LinkedIn for interesting content and productive discussions.