Advanced Guide to Helm Charts for Package Management in Kubernetes

This is an article from DZone’s 2022 Kubernetes in Enterprise Trends report.

for more information:

read the report

Helm is undoubtedly one of the most popular and successful open-source projects in the Kubernetes ecosystem. Since it was introduced at the inaugural KubeCon in 2015, Helm has been increasingly used to cement its position as the de facto package manager for Kubernetes. It graduated from the Cloud Native Computing Foundation in 2020, and in CNCF Survey 2020, over 60% of survey respondents cited Helm as their preferred method for packaging Kubernetes applications. These rates are much higher than those of Kustomize and other managed Kubernetes offerings.

Figure 1: Kubernetes Package Management Preference Survey Results

Image credit: “CNCF Survey 2020“Cloud Native Computing Foundation”

Given the popularity and ubiquity of Helm, it is important to understand the architecture and usage patterns in order to use the tool effectively. In this guide, we’ll break down the key concepts underlying Helm’s structure and walk you through some best practices.

hull structure

Helm packages Kubernetes applications into charts, which are a collection of templated Kubernetes manifest files. Each chart has the following content:

example-chart/ 
├── .helmignore
├── Chart.yaml 
├── values.yaml 
├── charts/
└── templates/
   └── tests/
   ...

Let’s dive deeper into each file:

  • .helmignore – Defines files or patterns to ignore when packaging Helm charts (for example, .vscode, .gitsecret files).
  • Chart.yaml – Contains top-level metadata about the Helm chart, including name, version, and other dependencies if the chart bundles multiple applications together. Examples of dependent charts include packaging ZooKeeper with Kafka or grouping Prometheus and Grafana together.
  • values.yaml – Sets the default values ​​for all templated parts of the chart under the template directory. These default values ​​can be overridden via –values either –set flags
  • charts – stores the tar files of the dependent chart if it was specified Chart.yaml,
  • templates – Maintains all Kubernetes manifest files that define the application, including but not limited to deployment, services, autoscaling, configmaps, and secrets. Along with core Kubernetes files, it can also hold template helpers, notes.txt, and test files.

Under the hood, Helm uses Go templates to combine values ​​into corresponding template files. This means that it is important to understand YAML syntax as well as Go’s data types in order to create, update, or use Helm charts.

helm lifecycle

Once the chart is created, it is ready to be deployed in a Kubernetes cluster. Helm CLI uses install either upgrade command to trigger a new release. Each release is a separate, deployed artifact of a versioned, templated chart. This means that it is possible to have multiple releases of the same chart, as long as the underlying values ​​do not conflict. For example, a PostgreSQL helm chart can be deployed to two different namespaces with the same configuration.

Plus, Helm keeps a history of each release, allowing for easy rollbacks. To see release history, run helm history <name-of-release>, Then to roll back, use helm rollback <name-of-release> <version>, While these CLI commands are useful for development, they are likely to be handled by more robust CD systems in production.

helm best practices

Now that we have a good understanding of Helm’s structure and lifecycle, we’ll review some best practices and useful tips for interacting with Helm charts.

Bootstrap Chart with Helm CLI

Provides an excellent skeleton for bootstrapping a new Helm chart via Helm helm create command. Instead of handcrafting individual Helm files from scratch, take advantage of create command to get default manifest files (for example, deployment.yaml, hpa.yaml, ingress.yaml, service.yamlAnd serviceaccount.yaml) as well as templates for providing unique names and annotations.

Check Errors with Helm CLI

Helm also provides a number of tools for validating charts before deployment. YAML and Go template syntax can be difficult to debug, especially when it is caused by simple indentation or empty value errors.

  1. helm lint – Checks charts for syntax issues such as poorly formatted YAML indentation or missing values. running this command with –debug Flags can provide more information.
  2. helm template – Renders templates using locally provided values. Might be useful to see if the overridden values ​​are correctly inserted into the manifest template. To focus on a single template, use -s flag: helm template my-chart -s templates/deployment.yaml,
  3. --dry-run The lint and template commands can only catch templating issues through static analysis. To catch errors related to Kubernetes (for example, using a deprecated Kubernetes API version), run --dry-run command before applying upgrade or install command.

For advanced guides on template functions, flow control, and other debugging tricks, see the Helm documentation section under “Chart Template Guide”.

package with treatment

As explained in the Helm Structure section, sometimes it makes sense to package multiple applications together into a single Helm chart. This pattern is useful for grouping related applications or databases together into a single deployable unit. Common use cases include packaging PostgreSQL and Redis with a Django app, or bundling together all the components of the ELK/EFK stack. Another way to use subcategory is to bundle common helper templates to add annotations, labels, or default values. A good example can be found with Bitnami’s charts:

apiVersion: v2
appVersion: "3.2.1"
dependencies: 
  - condition: zookeeper.enabled
    name: zookeeper
    repository: "https://charts.bitnami.com/bitnami"
    version: 10.x.x
  - name: common
    repository: "https://charts.bitnami.com/bitnami"
    tags:
      - bitnami-common
    version: 2.x.x
name: kafka
version: 18.2.0

use annotations

Since Kubernetes only sees changes to the deployment specification, by default, changing the contents of the config map or secret that is mounted on the pod does not automatically trigger rolling updates. This may be unexpected behavior for users who expect a restart with the updated values ​​when invoking the upgrade command.

To automatically roll out deployment, you can use a tool like Reloader or add a checksum annotation to the deployment spec:

kind: Deployment
spec: 
  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}

Annotations are also useful for defining hooks for tasks that should run before or after an install or upgrade. Common use cases might include running flyway migrations or running clean-up jobs. While this can be achieved with other CD tools, helm hooks provide a native way to change the release lifecycle behavior:

apiVersion: batch/v1 
kind: Job
metadata:
  annotations:
    "helm.sh/hook": post-install
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": hook-succeeded

Helm’s limits

While Helm comes with a suite of features to make creating packages and handling Kubernetes applications easier, it is important to note that Helm is only a package manager – it is not a fully featured CD tool. In other words, organizations should not rely on Helm alone for end-to-end Kubernetes CI/CD tools. Instead, Helm should integrate with more robust tools such as ArgoCD, JenkinsX, or Spinnaker to keep deployment consistent. Furthermore, since Helm uses plaintext YAML as the primary templating interface, secret and non-YAML files are not handled very well. This means that secret or configuration binaries (eg, public keys, .dat files) can be better handled through another CI/CD tool outside of Helm.

Finally, while subcharts are useful for organizing related components together, deeply nested subcharts can cause templating issues. If the application really needs multiple nested subcharts, look at other deployment patterns such as ArgoCD’s ApplicationsSet to group multiple Helm charts together instead.

final thoughts

Helm is a powerful tool that has stood the test of time. Compared to verbose, vanilla Kubernetes manifest files, Helm allows advanced templating techniques to package Kubernetes applications into deployable units. In this guide, we looked at the high-level Helm structure as well as some best practices for using Helm effectively. We then went through some of Helm’s limitations—primarily the fact that it shouldn’t be used as a standalone CD tool.

Still, with a wide selection of public, production-ready Helm charts, it’s easier than ever to download, modify, and install various Kubernetes components.

This is an article from DZone’s 2022 Kubernetes in Enterprise Trends report.

for more information:

read the report

Leave a Comment