Search documentation
karat

+

K

Publishing versioned Helm charts

Apollo was built to help organizations deploy software into many different environments. To achieve this goal, your software must be portable and easily reproduced. Containers are foundational to this goal, but we believe that publishing versioned containers alone is not sufficient. It is just as important to publish immutable versioned artifacts with the details of how a container image is run.

This is often overlooked in how organizations deploy Helm charts today. The goal of this guide is to:

  • Dive deeper into the options for managing your Helm charts.
  • Describe why Apollo requires immutable versioned Helm charts to be published to a registry.
  • Show a low-cost path to adopting Apollo if you do not currently follow that method.

What’s the point?

There are two primary approaches to managing Kubernetes manifests and Helm charts that describe how a container image should be run: you can either publish Helm charts in registries or host Helm charts in Git repositories.

Helm charts in registries

Our required option is to package, version, and publish Helm charts to a registry that describes how your container images should be deployed to Kubernetes. Semantic versioning is most commonly used for versioning of these artifacts. The Helm ecosystem has first-class support for packaging, versioning, and publishing Helm charts to Helm chart repositories.

In this method, you can rely on Helm tools to deploy a specific version of a Helm chart to one or more clusters, providing operators clarity around what versions are running where. Any variance in your deployed software installations is handled through Helm Values. You typically leverage the same container registry that is used for publishing and serving the container images referenced in the Helm charts.

Helm charts in Git repositores

Many organizations use a Git repository to define and manage the Helm charts or Kubernetes manifests that describe how container images should be deployed. Rather than publish an immutable and versioned Helm chart to a registry, they often rely on Git references to represent specific versions of Helm charts or manifests.

There are different common strategies for deploying a single Helm chart or set of Kubernetes manifests to multiple clusters. The layout of Helm charts in Git repositories is typically left as an exercise to the reader:

  • Environment branches: One Git repository stores a Helm chart, and Git branches resolve resources to deploy to instances of your product.
  • Environment tags: One Git repository stores a Helm chart, and Git tags resolve resources to deploy different instances of your product in a software environment.
  • Environment folders: One Git repository stores many Helm charts, organized by folders into the target software environments. There is no single representation of how a container image is deployed. These versions often will diverge over time.
  • Environment repositories: Multiple Git repositories define and organize which Helm charts or Kubernetes manifests should be deployed into each cluster. Like the previous strategy, there is no single source of truth, and what defines how a container image gets deployed is likely to diverge across clusters over time.

None of these four approaches use versioned Helm charts. In practice, the Helm chart is versioned only in the context of a given environment, which means it is not portable, and it is easy for environment-specific charts to diverge.

As the number of environments you manage grows over time, it becomes harder to ensure that the same Helm chart is running across your environments, even if they are pointed at the same container version.

Choosing Helm charts in Registries

As mentioned above, a core design principle of Apollo is that the instructions for how a container image is deployed should be versioned and immutable in the same way as the container image itself. We believe that context, like resource requests, default configuration, or how a service is exposed to the network, is just as important as the container image for a service running correctly.

Apollo holds that the second approach above is insufficient to porting and deploying your software as the number of environments you manage scales. You need full confidence that given the same version, what you have running in one cluster is the same thing running in another, and if it works in one, it should work in another.

There are key features of Apollo that build on this decision. One key example is in capturing “recall ranges” for problematic releases of your software. If there is a discovered problem in a Helm chart or the underlying containers it references, you can communicate that problem to Apollo and describe the intended remediation steps. Apollo knows exactly where all of this software is deployed, and it can automatically roll it off to a known, good version if desired. There is no DevOps or manual actions in the loop, even when performing these operations across hundreds of software environments.

Adopting Apollo

Apollo requires you to publish immutable, versioned Helm charts. Publishing new Releases to Apollo requires Maven coordinates to the Helm chart location in a Helm chart repository. There are many valid strategies for versioning your Helm charts, this is one possible approach towards doing so as a reference implementation.

Defining versions

Helm and Apollo both require Helm chart versions to follow Semantic Versioning. Learn more in Helm’s documentation on versioning, and Apollo’s documented on Product versions. If your starting point is deploying Helm charts via Git references from a Git repository, we recommend using Git tags with Semantic Versioning 2.0.0 values. These values must follow the following basic format.

Given a version number MAJOR.MINOR.PATCH, increment the:

  • MAJOR version when you make incompatible API changes.
  • MINOR version when you add functionality in a backward compatible manner.
  • PATCH version when you make backward compatible bug fixes.

Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

Once you define your version, tag Git commits that you want to publish as a release. For example:

Copied!
1 git tag 0.0.1 -m "Tagging first version of a release"

In build automation you can use the following command to evaluate the version for the current build:

Copied!
1 git describe --tags --always --first-parent

Packaging and publishing a Helm chart to a repository

Combined with the versioning strategy described above, the following command will produce a versioned Helm chart and publish it to a Helm chart repository:

Copied!
1 2 3 4 5 6 7 8 9 10 export RELEASE_VERSION=${git describe --tags --always --first-parent} export HELM_REPOSITORY="your-helm-repository.com" export HELM_REPOSITORY_USER="your-username-here" export HELM_REPOSITORY_PASS="your-password-here" export HELM_CHART_NAME="chart-name-here" cd helm-chart helm package . --version ${RELEASE_VERSION} --app-version ${RELEASE_VERSION} helm registry login -u $HELM_REPOSITORY_USER -p $HELM_REPOSITORY_PASS $HELM_REPOSITORY helm push "${HELM_CHART_NAME}-${RELEASE_VERSION}.tgz" "oci://${HELM_REPOSITORY}"

Learn more about how to use Helm’s CLI to package a Helm chart.

Reference implementation

You can find a full reference implementation of how to package a Helm chart and publish it to your Apollo catalog in Apollo’s public documentation.