Helm to the rescue!
Over time, the Kubernetes community discovered that creating and maintaining Kubernetes resources to deploy applications is difficult. This prompted the development of a simple yet powerful tool that would allow teams to overcome the challenges posed by deploying applications on Kubernetes. The tool that was created is called Helm. Helm is an open source tool used for packaging and deploying applications on Kubernetes. It is often referred to as the Kubernetes Package Manager because of its similarities to any other package manager you would find on your favorite OS. Helm is widely used throughout the Kubernetes community and is a CNCF graduated project.
Understanding package managers
Package managers are used to simplify the process of installing, upgrading, reverting, and removing a system's applications. These applications are defined in units, called packages, which contain metadata around target software and its dependencies.
The process behind package managers is simple. First, the user passes the name of a software package as an argument. The package manager then performs a lookup against a package repository to see whether that package exists. If it is found, the package manager installs the application defined by the package and its dependencies to the specified locations on the system.
Package managers make managing software very easy. As an example, let's imagine you wanted to install
htop, a Linux system monitor, to a Fedora machine. Installing this would be as simple as typing a single command:
dnf, the Fedora package manager since 2015, to find
htop in the Fedora package repository and install it.
dnf also takes care of installing the
htop package's dependencies, so you would not have to worry about installing its requirements beforehand. After
dnf finds the
htop package from the upstream repository, it asks you whether you're sure you want to proceed. The
--assumeyes flag automatically answers
yes to this question and any other prompts that
dnf may potentially ask.
Over time, newer versions of
htop may appear in the upstream repository.
dnf and other package managers allow users to efficiently upgrade to new versions of the software. The subcommand that allows users to upgrade using
dnf is upgrade:
dnf to upgrade
htop to its latest version. It also upgrades its dependencies to the versions specified in the package's metadata.
While moving forward is often better, package managers also allow users to move backward and revert an application back to a prior version if necessary.
dnf does this with the
This is a powerful process because the package manager allows users to quickly roll back if a critical bug or vulnerability is reported.
In this section, we reviewed how the
dnf package manager on Fedora can be used to manage a software package. Helm, as the Kubernetes package manager, is similar to
dnf, both in its purpose and functionality. While
dnf is used to manage applications on Fedora, Helm is used to manage applications on Kubernetes. We will explore this in greater detail next.
The Kubernetes package manager
Given that Helm was designed to provide an experience similar to that of package managers, experienced users of
dnf or similar tools will immediately understand Helm's basic concepts. Things become more complicated, however, when talking about the specific implementation details.
dnf operates on
RPM packages that provide executables, dependency information, and metadata. Helm, on the other hand, works with charts. A Helm chart can be thought of as a Kubernetes package. Charts contain the declarative Kubernetes resource files required to deploy an application. Similar to an
RPM, it can also declare one or more dependencies that the application needs in order to run.
Helm relies on repositories to provide widespread access to charts. Chart developers create declarative YAML files, package them into charts, and publish them to chart repositories. End users then use Helm to search for existing charts to deploy onto Kubernetes, similar to how end users of
dnf will search for
RPM packages to deploy to Fedora.
Let's go through a basic example. Helm could be used to deploy
Redis, an in-memory cache, to Kubernetes by using a chart published to an upstream repository. This could be performed using Helm's
This would install the
redis chart from the bitnami chart repository to a Kubernetes namespace called
redis. This installation would be referred to as the initial revision, or the initial deployment of a Helm chart.
If a new version of the
redis chart becomes available, users can upgrade to a new version using the
This would upgrade
Redis to meet the specification defined by the newer
With operating systems, users should be concerned about rollbacks if a bug or vulnerability is found. The same concern exists with applications on Kubernetes, and Helm provides the rollback command to handle this use case:
This command would roll
Redis back to its first revision.
Finally, Helm provides the ability to remove
Redis altogether with the
Earlier in this chapter, we reviewed how Kubernetes applications are created by managing Kubernetes resources, and we discussed some of the challenges involved. Here are few ways that Helm can overcome these challenges.
The abstracted complexity of Kubernetes resources
Let's assume that a developer has been given the task of deploying a MySQL database onto Kubernetes. The developer would need to create the resources required to configure its containers, network, and storage. The amount of Kubernetes knowledge required to configure such an application from scratch is high and is a big hurdle for new and even intermediate Kubernetes users to clear.
With Helm, a developer tasked with deploying a MySQL database could simply search for MySQL charts in upstream chart repositories. These charts would have already been written by chart developers in the community and would already contain the declarative configuration required to deploy a MySQL database. In this regard, developers with this kind of task would act as simple end users that use Helm in a similar way to any other package manager.
The ongoing history of revisions
Helm has a concept called release history. When a Helm chart is installed for the first time, Helm adds that initial revision to the history. The history is further modified as revisions increase via upgrades, keeping various snapshots of how the application was configured at varying revisions.
The following diagram depicts an ongoing history of revisions. The squares in blue illustrate resources that have been modified from their previous versions:
The process of tracking each revision provides opportunities for rollback. Rollbacks in Helm are very simple. Users simply point Helm to a previous revision and Helm reverts the live state to that of the selected revision. With Helm, gone are the days of the
n-1 backup. Helm allows users to roll back their applications as far back as they desire, even back to the very first installation.
Dynamically configured declarative resources
One of the biggest hassles with creating resources declaratively is that Kubernetes resources are static and cannot be parameterized. As you may recall from earlier, this results in resources becoming boilerplate across applications and similar configurations, making it more difficult for teams to configure their applications as code. Helm alleviates these issues by introducing values and templates.
Values are simply what Helm calls parameters for charts. Templates are dynamically generated files based on a given set of values. These two constructs provide chart developers the ability to write Kubernetes resources that are automatically generated based on values that end users provide. By doing so, applications managed by Helm become more flexible, less boilerplate, and easier to maintain.
Values and templates allow users to do things such as the following:
- Parameterize common fields, such as the image name in a Deployment and the ports in a Service
- Generate long pieces of YAML configuration based on user input, such as volume mounts in a Deployment or the data in a ConfigMap
- Include or exclude resources based on user input
Consistency between the local and live states
Package managers prevent users from having to manage an application and its dependencies manually. All management can be done through the package manager itself. The same idea holds true with Helm. Because a Helm chart contains a flexible configuration of Kubernetes resources, users shouldn't have to make modifications directly to live Kubernetes resources. Users that want to modify their applications can do so by providing new values to a Helm chart or by upgrading their application to a more recent version of the associated chart. This allows the local state (represented by the Helm chart configuration) and the live state to remain consistent across modifications, giving users the ability to provide a source of truth for their Kubernetes resource configurations.
Helm simplifies application deployments by determining the order that Kubernetes resources need to be created. Helm analyzes each of a chart's resources and orders them based on their types. This pre-deterministic order exists to ensure that resources that commonly have resources dependent on them are created first. For example, Secrets and ConfigMaps should be created before Deployments, since a Deployment would likely consume those resources as volumes. Helm performs this ordering without any interaction from the user, so this complexity is abstracted and prevents users from needing to worry about the order that these resources are applied.
Automated life cycle hooks
Similar to other package managers, Helm provides the ability to define life cycle hooks. Life cycle hooks are actions that take place automatically at different stages of an application's life cycle. They can be used to do things such as the following:
- Perform a data backup on an upgrade.
- Restore data on a rollback.
- Validate a Kubernetes environment prior to installation.
Life cycle hooks are valuable because they abstract complexities around tasks that may not be Kubernetes-specific. For example, a Kubernetes user may not be familiar with the best practices behind backing up a database or may not know when such a task should be performed. Life cycle hooks allow experts to write automation that performs those best practices when recommended so that users can continue to be productive without needing to worry about those details.