helm-k8s.jpg
Cover image for ron

Ron Northcutt Verified userVerified user

Head of DevRel

Appsmith

Going Further with Helm: Advanced Features

We have a great introduction to Helm article, and a solid tutorial on how to install Helm. So you can check those out for the basics of installing Helm, creating charts, and deploying applications. As you become more comfortable with Helm, you will want to explore its advanced features that can elevate your Kubernetes management to the next level. This post will delve into more sophisticated Helm functionalities and offer guidance on developing, securing, and optimizing your Helm charts.

Let's break down some of the more advanced stuff you can do with Helm in a way that's a bit easier to grasp. We will talk about making your Helm charts even better, how to make sure they play nice with other charts, and how to check that everything's running smoothly.

Templating and Values with Helm

First up, Helm uses the Go templating language to create Kubernetes files. This is pretty cool because it lets you insert specific values into your files automatically. Imagine you're filling out a custom form letter, and wherever you see "{{name}}" you drop in a person's name. Helm does something similar for your app's settings.

Here's a tiny example. Say you have a part of your Helm chart that looks like this:

apiVersion: v1
kind: Pod
metadata:
  name: {{ .Values.appName }}

And in your values.yaml, you've got:

appName: my-cool-app

Helm combines these to set your app's name in the Kubernetes file. This lets you change your app's name easily without diving into the nitty-gritty Kubernetes stuff. To manage these values, keep your values.yaml neat and organized. Use comments to remind yourself what each part does, and group related settings together so they're easier to find.

Overriding Values with --set and --values Flags

When you're deploying applications with Helm, you might need to tweak some settings without changing the values.yaml file every single time. This is where the --set and --values (or -f for short) flags come in handy. They let you override the default values in your Helm chart right from the command line, giving you the flexibility to customize deployments on the fly. This is really handy for testing and for dealing with dev/stage/prod differences from a single chart.

Using the --set Flag

The --set flag allows you to override a specific value in your chart. It's perfect for quick adjustments or when you're deploying the same chart across different environments and need to change just one or two things.

For example, if you want to change the number of replicas for a deployment without altering the values.yaml file, you could use a command like this:

helm install my-release ./my-chart --set replicaCount=5

This command tells Helm to deploy your chart but use 5 instead of the default number of replicas specified in your values.yaml. You can set multiple values by separating them with commas:

helm install my-release ./my-chart --set replicaCount=5,image.tag=v2.0

Using the --values or -f Flag
While --set is great for quick changes, the --values (or -f) flag lets you specify a whole values file to override the defaults. This is super useful when you have a set of configurations that you want to reuse or when the changes are too many to list with --set conveniently. Remember how we mentioned dev/stage/prod or testing? It is much easier to create an alternative file of overrides for those things and lock them into version control.

Imagine you have a file named custom-values.yaml that contains the specific configurations for a deployment. You can apply these settings using the following command:

helm install my-release ./my-chart -f custom-values.yaml

You can also stack multiple -f flags to layer sets of values, which Helm will merge together. If there are conflicts, the last file specified in the command line will take precedence. Here's how you might do it:

helm install my-release ./my-chart -f base-values.yaml -f override-values.yaml

In this scenario, override-values.yaml will override any matching values found in base-values.yaml, allowing for highly customizable deployments. That's pretty powerful. But if you want to really get crazy, you can combine BOTH flags.

Combining --set and --values
You can mix --set and --values flags in the same command, giving you the ultimate flexibility. This lets you apply a base set of values from a file and then tweak individual settings as needed:

helm install my-release ./my-chart -f custom-values.yaml --set replicaCount=3

This combination is especially powerful for scripting and automation, where you might have a common set of configurations and only need to change a few parameters based on the deployment situation. This lets you quickly adapt your Helm deployments to meet a wide range of requirements. 

Managing Dependencies

Your app might need other services to work, like a database. Helm lets you list these in your chart as dependencies, making it easy to get everything running together. You add these dependencies to your Chart.yaml file like this:

dependencies:
  - name: mysql
    version: "1.6.0"
    repository: "https://charts.bitnami.com/bitnami"

Then, run helm dependency update in your terminal, and Helm makes sure all the things your app needs are ready to go.

Helm Hooks for Smarter Deployments

Helm hooks are like smart assistants that help you manage your app's lifecycle in a Kubernetes cluster. They can run specific tasks at certain points during your app's installation, upgrade, or deletion. This is super useful for making sure everything happens in the right order or preparing things before your app starts running.

For example, you might want to set up a database before your app starts. You can use a pre-install hook for that. Here's a simple example of how you could use a Helm hook to run a job that sets up your database:

apiVersion: batch/v1
kind: Job
metadata:
  name: "{{ .Release.Name }}-db-setup"
  annotations:
    "helm.sh/hook": pre-install
spec:
  template:
    spec:
      containers:
      - name: db-setup
        image: mydbsetupimage:latest
        command: ["do", "your", "setup", "commands"]
      restartPolicy: OnFailure

This job runs before Helm installs the rest of your app (pre-install), making sure your database is ready to go when your app needs it. Here's a list of all the Helm hooks available:

  1. pre-install

    Runs before any resources are installed into the Kubernetes cluster. This hook is useful for setting up any prerequisites or dependencies your application might need before it starts.

  2. post-install

    Executes after all the chart's resources have been installed into the cluster. It's handy for performing any configuration or setup that requires the application's resources to be present, such as running database migrations.

  3. pre-delete

    Triggered before a release is deleted from Kubernetes. This hook allows you to run tasks like data backup or graceful shutdown procedures before the application is removed.

  4. post-delete

    Runs after a release has been deleted from Kubernetes. You can use this hook to clean up any external resources or perform other cleanup tasks that couldn't be handled by Kubernetes resource deletion.

  5. pre-upgrade

    Activated before an upgrade of a release. This is the place to add any logic needed to prepare for an application upgrade, such as data migrations or configuration changes.

  6. post-upgrade

    Executes after a release has been successfully upgraded. This hook can be used to verify the success of an upgrade or to perform post-upgrade cleanup and configuration tasks.

  7. pre-rollback

    Runs before a release is rolled back to a previous version. Similar to pre-upgrade, it's useful for preparing your environment for the rollback, ensuring that it can happen smoothly.

  8. post-rollback

    Triggered after a release has been rolled back to a previous version. Use this hook to clean up or reconfigure your environment after a rollback.

  9. test

    Designed to run tests against your release. This special hook can be used to verify that a release is functioning correctly in the cluster, ensuring the reliability and stability of your deployment. Helm does not automatically roll back if tests fail, but the test results can be used to make manual adjustments or trigger rollbacks.

Helm hooks are defined in your chart's templates using specific annotations in the metadata section of Kubernetes manifest files. They provide a powerful way to control the deployment process, allowing for complex deployment scenarios to be handled elegantly. By leveraging these hooks, you can automate many aspects of your application's lifecycle management, making your Helm charts more robust and reliable.

Writing Tests with Helm

As we saw above, Helm lets you write tests to check if your app runs correctly in Kubernetes. This is like giving your app a quick health check to catch any problems early. You can write tests that Helm will run after your app is deployed, making sure everything is working as expected.

Here's a basic example of a Helm test that checks if your web server is responding:

apiVersion: v1
kind: Pod
metadata:
  name: "{{ .Release.Name }}-test-connection"
  annotations:
    "helm.sh/hook": test-success
spec:
  containers:
  - name: wget
    image: busybox
    command: ['wget']
    args: ['{{ include "myapp.service" . }}']
  restartPolicy: Never

This test tries to connect to your app using a temporary container. If it succeeds, it means your app is up and running. If not, there might be something to fix. Helm will report back on whether this test passes or fails, giving you immediate feedback on your app's status.

By getting comfortable with Helm hooks and tests, you can automate a lot of your deployment process, making your life easier and your apps more reliable. Helm hooks let you set things up and clean up in an orderly fashion, while Helm tests give you quick checks to ensure your deployments are successful. Together, they're powerful tools to add to your Kubernetes toolkit.

We have called these "Advanced" features, but as you can see... it is still pretty simple! The great thing about Helm is that it makes easy to handle complex situations in a reasonable way. Check out good examples of advanced usage in projects online and learn how to adapt these techniques to make your own projects faster, safer, and easier to manage in a reasonable way.