Share with friends
In this tutorial on Kustomize vs Helm, we will talk about everything from differences in file structure and how they work to templating, secret management, when to use them, and more.
In the rapidly evolving landscape of container orchestration and management, Kubernetes has emerged as the de facto standard for deploying and scaling containerized applications.
Helm and Kustomize are two of the most well-known tools in the Kubernetes ecosystem that are made to make application deployment and configuration management easier. Defining, deploying, and managing applications on Kubernetes may be accomplished with the help of Helm and Kustomize, but they do it in fundamentally different ways.
You will gain a thorough understanding of the distinctive features, use cases, and best practices of Helm and Kustomize after reading this article's discussion of their fundamental distinctions.
What is Helm & Helm Chart?
Helm is a package manager for Kubernetes. It simplifies the deployment and management of applications on a Kubernetes cluster by using charts.
A Helm Chart is a collection of YAML files that describe a set of Kubernetes resources required to run an application.
Think of it as a blueprint that defines the components and configurations needed to create a running instance of your application in Kubernetes.
Also Read: What is Helm in Kubernetes?
Why Should I Use Helm?
Helm comes with loads of benefits. Here are a few of them:
Simplified Deployment
Helm smoothens the deployment process by combining all the necessary components and configurations in a single package.
Reusability
Helm Charts are reusable (p.s. save climate) and shareable. What this means is you can easily distribute and deploy applications with very consistent configurations across different clusters.
Versioning
Helm allows you to manage different versions of your application, making it easier to roll back or upgrade as needed. It also helps with keeping your secrets, secrets by using Go templates!
Dependency Management
Helm supports managing dependencies between applications, so you can easily install an entire stack of services at once like DBs and software agents.
Templating
Helm uses Go templates to enable dynamic / on-the-go generation of Kubernetes manifest files, enabling customization and flexibility.
Helm does this by allowing you to add variables and use functions inside your template files.
How does Helm Work?
Helm achieves this by using a combination of two main components: Helm Charts and the Helm client.
1. Helm Charts
As we already know that a Helm Chart is a collection of pre-configured Kubernetes resources (YAML files) packaged together in a single directory.
These resources can include deployments, services, config maps, persistent volume claims, and any other Kubernetes objects required to run an application
A typical Helm Chart structure looks like this:
my-chart/
├── Chart.yaml
├── values.yaml
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── configmap.yaml
│ └── ...
├── charts/
└── ...
2. Helm Client
The Helm client is a command-line tool that interacts with the Kubernetes cluster and manages the deployment and management of Helm Charts.
It is responsible for performing actions like installing, upgrading, deleting, and listing charts.
The Helm client takes input from the user, such as chart configurations or values to override default settings, and uses the information to deploy the application on the Kubernetes cluster.
Tiller used to be the server-side component of Helm.
However, starting from Helm 3, citing security concerns, Tiller has been removed, and Helm now interacts directly with the Kubernetes API server, enhancing security and simplicity. You can still use Helm v2.
Here are some common Helm commands:
-
helm install
: Installs your Helm Chart onto the Kubernetes cluster. -
helm upgrade
: Upgrades an existing release to a new version of the Helm Chart. -
helm uninstall
: Uninstalls a release (removes the deployed resources from the cluster). -
helm list
: Lists all deployed releases.
When you use Helm to deploy an application, the Helm client reads the chart's templates and values, processes them with the provided configurations, and generates Kubernetes resources.
These resources are then deployed to the Kubernetes cluster, bringing your application to life.
Helm also uses repositories to store and share Helm Charts with others, so that you can easily distribute applications and manage dependencies like Artifact Hub.
Also Read: Kubectl Config Set Context Tutorial
What is Kustomize?
As stated by the official Kubernetes website:
“Kustomize is a standalone tool to customize Kubernetes objects through a kustomization file”.
Kustomize operates by constructing existing manifests, as opposed to Helm, which uses templates.
Also Read: Differences between Ansible & Terraform
How to Get Started with Kustomize?
You only need one or more Kubernetes manifests and a Kustomization file called kustomization.yaml to get started using Kustomize.
A manifest that lists a list of resources, patches to use, and several other choices is the Kustomization file itself.
Say you are utilizing a Helm chart from a specific vendor. It's a near fit for your use case, but it needs some customizing and isn't ideal.
In order to apply your configuration changes to your cluster, you fork the Helm chart. A few months later, the chart you are using is updated by the vendor to include certain crucial functionality that you require.
You need to fork the updated Helm chart and apply your setup changes again in order to take advantage of those new features.
Re-forking and re-customizing these Helm charts at scale adds a significant administrative burden and raises the possibility of configuration errors, endangering the reliability of your product and services.
Enter Kustomize.
The YAML files are generated by Helm, and Kustomize will modify them based on the events to include environment-specific variables.
For instance, if the branch is master and connected to the production environment, Kustomize will use the production-specific variables and not the other ones.
Also Read: Differences between Ansible & Terraform
How does Kustomize Work?
Kustomize allows you to define and manage configurations separately from the base manifests, making it easier to manage multiple environments and variations of your Kubernetes resources.
Kustomize is now a part of the official Kubernetes project and has been integrated into kubectl since version 1.14.
Imagine you have a set of base Kubernetes manifest files that define your desired resource state, like deployments, services, and config maps.
These base files form the foundation of your setup, but they lack environment-specific or runtime-specific values.
To work with Kustomize, you create a file called "kustomization.yaml" in the same directory as your base manifests.
This file serves as the control center for your customizations. It allows you to specify the changes you want to apply to the base manifests, making it easy to manage different environments and variations of your resources.
Now, let's talk about the 'kustomizations'. You can do various things with Kustomize:
-
You can add new resources, tweak existing ones, or remove unnecessary ones, all without touching the original base files.
-
With Kustomize, you can easily set a Kubernetes namespace and label prefixes for your resources, maintaining consistency and organization.
-
Kustomize enables you to define variables in the "kustomization.yaml" file or separate variable files.
These variables can be used to substitute values in your resources, making it a breeze to customize your manifests based on different environments (e.g., development, staging, production).
To apply these customizations, Kustomize uses something called “overlays”.
An overlay is like a separate directory that contains its own "kustomization.yaml" file.
Within the overlay, you can have patches and additional resources that extend or modify the base manifests.
Think of it as a neat way to keep your changes organized and separate from the base files which can get cluttered.
Once you've set up your customizations, you run the kubectl kustomize
command.
What happens later is Kustomize processes the base manifests, applies the customizations from the overlays, and substitutes variables.
The output is a set of customized manifest files, which you can directly apply to your Kubernetes cluster using kubectl apply -f
.
Also Read: Terraform Apply Tutorial
Helm vs Kustomize - Example
As we already know Helm and Kustomize are both popular tools in the Kubernetes ecosystem used for managing and templating Kubernetes manifests.
While they serve similar purposes, they have different approaches to achieving their goals.
It'll be best to compare examples to understand further.
Example Scenario: Deploying a simple web application with custom configurations.
Web Application YAML
Let's assume you have a simple web application with the following Kubernetes YAML manifests.
- deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-web-app
spec:
replicas: 3
template:
spec:
containers:
- name: my-web-app-container
image: my-web-app:latest
ports:
- containerPort: 80
2. service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-web-app-service
spec:
selector:
app: my-web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
Also Read: How to Use Kubectl Proxy Command?
Using Helm
Helm uses charts to package and manage Kubernetes resources.
- Create a Helm chart called "my-web-app" with the following directory structure:
my-web-app/
├── Chart.yaml
├── values.yaml
├── templates/
│ ├── deployment.yaml
│ └── service.yaml
└── ...
- In the
values.yaml
file, you can define customizable values for your application.
For example:
# values.yaml
replicaCount: 3
image: my-web-app:latest
serviceType: LoadBalancer
- In the
deployment.yaml
andservice.yaml
under thetemplates
directory, you can use Helm's templating syntax to reference the values defined invalues.yaml
.
For example, in deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-web-app
spec:
replicas: { { .Values.replicaCount } }
template:
spec:
containers:
- name: my-web-app-container
image: { { .Values.image } }
ports:
- containerPort: 80
- To deploy your application with Helm, you can run the following commands:
helm install my-web-app ./my-web-app -f values.yaml
This will install your application with the specified values.
Using Kustomize
- Create a Kustomization file, usually named
kustomization.yaml
, with the following content:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
configMapGenerator:
- name: my-web-app-configmap
literals:
- replicaCount=3
- image=my-web-app:latest
- serviceType=LoadBalancer
-
In this
kustomization.yaml
, you define the resources you want to apply, in this case,deployment.yaml
andservice.yaml
. Use theconfigMapGenerator
section to specify the customizable values for your application. -
In the
deployment.yaml
andservice.yaml
, we use the$()
syntax to reference the values defined in theconfigMapGenerator
.
For example, in deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-web-app
spec:
replicas: $(replicaCount)
template:
spec:
containers:
- name: my-web-app-container
image: $(image)
ports:
- containerPort: 80
- Next, deploy the application with Kustomize using the following command:
kustomize build ./path/to/kustomization | kubectl apply -f -
This will build the customized manifests and apply them to your Kubernetes cluster and voila!
Helm vs Kustomize - Package Management
Talking about Package management, Helm is generally better suited for complex applications that require a wide variety of Kubernetes resources and configurations.
It excels in versioning and managing the lifecycle of a Kubernetes application using charts and has a larger collection of readily available Helm charts.
Kustomize, on the other hand, is more suitable for managing configuration variations, applying patches, and customizing existing manifests.
It is a simpler tool and is integrated directly into kubectl, making it more accessible without additional installations.
Also Read: What is Internal Developer Platform - IDP?
Helm vs Kustomize - Templating
For templating purposes, Helm uses the Go templating engine to define dynamic Kubernetes manifests.
Here, templates are written in YAML with embedded Go templating constructs, allowing you to create reusable and parameterized configurations.
Kustomize uses "kustomization.yaml" files to define resources and configurations. It does leverages Go templates and allows you to customize individual fields in YAML files using patches.
So in this case, they are not very different from one another.
Also Read: Top 13 Heroku Alternatives
Helm vs Kustomize - Flexibility (Rollbacks)
When comparing Helm and Kustomize in terms of flexibility, particularly with respect to rollbacks, consider these arguments.
Helm has built-in support for rollbacks. When you use Helm to manage deployments, it keeps track of release history, including the different versions of your charts and the corresponding deployed resources.
If a deployment fails or if you need to roll back to a previous version, Helm makes it easy to do so using the helm rollback
command.
In addition to that Helm also maintains a revision history of your releases, allowing you to roll back to a specific revision or version of your application.
This feature provides a safety net in case something goes wrong with a new release.
Kustomize itself does not provide direct support for rollbacks like Helm does. It is primarily focused on customizing manifests rather than handling the deployment lifecycle.
As such, you won't find a built-in rollback mechanism in Kustomize.
Some users of Kustomize who follow the GitOps workflow may handle rollbacks through version control.
By using versioned configurations and relying on Git's capabilities, you can effectively roll back to a previous state of your manifests.
However, this approach depends on your specific GitOps workflow and is not inherently a feature of Kustomize, at least not yet!
Also Read: How to Use Kubectl Rollout Restart?
Helm vs Kustomize - Security (Secret Management)
When comparing Helm and Kustomize in terms of security, both tools have different approaches, let's compare them.
Helm offers a built-in mechanism for managing Kubernetes secrets through its "Values" files.
You can define sensitive data, such as passwords or API keys, in the Values file, and then reference those values in your templates.
Helm also has the capability to encrypt sensitive data in the Values files using a feature called "Helm Secrets."
Helm Secrets is an add-on tool that allows you to encrypt secret values, providing an additional layer of security.
Kustomize itself does not provide built-in secret management functionality like Helm. Instead, it relies on Kubernetes' native secret resources for handling sensitive data.
If you are using Kustomize, you would typically manage your secrets outside of Kustomize, using Kubernetes native secrets or external secret management tools like HashiCorp Vault, Bitnami Sealed Secrets, or SOPS.
Also Read: Differences between AWS ECS and EKS
Helm vs Kustomize - Project/ File Structure
Here's a detailed comparison of the file structure that these two options provide.
Helm Project Structure
my-app/
└── my-chart/
├── Chart.yaml
├── values.yaml
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── ...
├── charts/
│ ├── dependency-chart-1/
│ └── dependency-chart-2/
└── ...
-
In this example, "my-app" is the top-level umbrella project, and "my-chart" is the Helm chart.
-
The "Chart.yaml" file contains metadata about the chart, such as its name, version, and description.
-
The "values.yaml" file holds default configuration values for the templates.
-
The "templates" directory contains the Go templates that define the Kubernetes resources (e.g., deployment, service) for the application.
-
The "charts" directory contains dependencies to other charts if required.
Kustomize Project Structure
my-app/
├── base/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── ...
├── overlays/
│ ├── dev/
│ │ └── kustomization.yaml
│ ├── staging/
│ │ └── kustomization.yaml
│ └── production/
│ └── kustomization.yaml
└── kustomization.yaml
-
Again, in this example, "my-app" is the top-level project.
-
The "base" directory contains the base set of Kubernetes resources that represent the common configuration shared across different environments.
-
The "overlays" directory contains separate directories for each environment (e.g., "dev," "staging," "production"), each with its own "kustomization.yaml" file.
-
The "kustomization.yaml" files within each overlay directory describe the customizations and patches to apply on top of the base resources.
Helm vs Kustomize in Kubernetes
Let's compare Helm and Kustomize in Kubernetes by providing examples of how each tool can be used to manage deployments.
1. Helm Example
Let's say you have a web application that consists of a frontend and a backend, each with its own set of Kubernetes resources.
With Helm, you can create a chart for each component and use a parent umbrella chart to manage them both.
my-app/
├── frontend/
│ ├── Chart.yaml
│ ├── values.yaml
│ └── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── ...
├── backend/
│ ├── Chart.yaml
│ ├── values.yaml
│ └── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── ...
└── Chart.yaml (Umbrella Chart)
-
In this example, "my-app" is the umbrella chart, and it contains two sub-charts: "frontend" and "backend."
-
Each sub-chart ("frontend" and "backend") has its own templates that define the Kubernetes resources for the respective components.
-
The umbrella chart allows you to manage and deploy both frontend and backend components together as a single unit.
You can then use Helm commands to install, upgrade, and manage the entire application:
# To install the application
helm install my-app ./my-app
# To upgrade the application with new configuration values
helm upgrade my-app ./my-app --set frontend.replicas=3 --set backend.replicas=2
# To rollback to the previous version
helm rollback my-app 1
2. Kustomize Example
Imagine you have a microservices-based application with multiple services, and you want to deploy the same application to different environments with some environment-specific configurations.
You can use Kustomize to manage these configurations.
my-app/
├── base/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── ...
├── overlays/
│ ├── dev/
│ │ ├── kustomization.yaml
│ │ └── configmap.yaml
│ ├── staging/
│ │ ├── kustomization.yaml
│ │ └── configmap.yaml
│ └── production/
│ ├── kustomization.yaml
│ └── configmap.yaml
└── kustomization.yaml
-
In this example, "my-app" contains the base set of Kubernetes resources ("base") that represent the common configuration shared across different environments.
-
The "overlays" directory contains separate directories for each environment, each with its own "kustomization.yaml" file and environment-specific configurations (e.g., configmaps).
-
Each "kustomization.yaml" file describes the customizations and patches to apply on top of the base resources.
You can use Kustomize commands to build and deploy the application for different environments:
# To build the Kubernetes manifests for the development environment
kustomize build ./my-app/overlays/dev | kubectl apply -f -
# To build the Kubernetes manifests for the staging environment
kustomize build ./my-app/overlays/staging | kubectl apply -f -
# To build the Kubernetes manifests for the production environment
kustomize build ./my-app/overlays/production | kubectl apply -f -
Also Read: Top Microservices Monitoring & Testing Tools
When to Use - Helm vs Kustomize?
In this section, we will briefly explain when to use Helm and when to use Kustomize.
When to Use Helm?
- Packaging Complex Applications: Helm is ideal for packaging and deploying complex applications composed of multiple interdependent Kubernetes resources.
Example: Deploying a microservices-based application with multiple services, each requiring different configurations and dependencies.
- Managing Releases: Helm provides versioning and rollback support, making it suitable for managing application releases and handling rollbacks when needed.
Example: Rolling back to a previous stable version of an application after a failed deployment.
- Centralized Configuration: Helm's values files allow easy customization and centralized configuration management for different environments.
Example: Using different values files to configure application settings for development, staging, and production environments.
When to Use Kustomize?
- Customizing Manifests: Kustomize excels at customizing Kubernetes manifests directly without introducing additional abstraction layers.
Example: Modifying resource names, labels, or annotations for specific environments without modifying the base manifests.
- Multi-Environment Management: Kustomize's overlays enable managing different configurations for various environments in a more organized way.
Example: Customizing resources for development, staging, and production environments using separate overlay directories.
- Simplicity: Kustomize follows a Keep It Simple, Stupid (KISS) approach, making it a suitable choice for simple deployments and avoiding unnecessary complexities.
Example: Deploying a straightforward web application with minimal customization needs.
Also Read: Istio vs Consul vs Linkerd
Can I Use Helm and Kustomize Together?
Yes, you can use Helm and Kustomize together, and they can complement each other in certain scenarios.
They have some overlapping functionalities, but they also have distinct strengths.
Here's how you can use Helm and Kustomize together:
Use Helm for Application Packaging
Helm is great for packaging complex applications as charts. You can define your application's configurations, dependencies, and templates within Helm charts.
Use Kustomize for Customizations
Once you have your application packaged as a Helm chart, you can use Kustomize as an additional layer of customization.
Kustomize allows you to further modify the Kubernetes manifests generated by Helm without modifying the original charts and saving a hell lot of time.
Customize Helm Values with Kustomize
You can use Kustomize overlays to customize the Helm values in the values.yaml
file.
Why?
This allows you to manage environment-specific configurations or make small adjustments to the Helm chart's values for different environments.
Combine Helm and Kustomize Deployments
You can use Helm to deploy the base application chart, and then use Kustomize overlays to customize the deployment for specific environments or scenarios.
This allows you to have more fine-grained control over the deployment process.
Let's look at an example.
Suppose you have a Helm chart for a web application that includes deployment, service, and configuration files.
You can use Kustomize overlays to customize this Helm chart for different environments:
my-app/
├── charts/
│ ├── my-web-app/ (Helm Chart)
│ └── ...
├── kustomize/
│ ├── overlays/
│ │ ├── dev/
│ │ │ ├── kustomization.yaml
│ │ │ └── configmap.yaml
│ │ └── prod/
│ │ ├── kustomization.yaml
│ │ └── configmap.yaml
│ └── kustomization.yaml
└── values.yaml
-
In this example, "my-app" contains a Helm chart named "my-web-app" and a Kustomize directory with two overlays: "dev" and "prod".
-
The Helm chart in the "charts" directory packages the base application.
-
The "kustomize" directory contains Kustomize overlays for customizing the base chart for the development ("dev") and production ("prod") environments.
So there you have it, this has been a long article but I hope you got value out of it. Using Helm and Kustomize in sync can be a little tricky to start with.
When making a decision between Helm and Kustomize, consider the complexity of your project, your team's expertise, and your specific requirements.
For smaller projects with straightforward deployments, Kustomize might be a more straightforward and lightweight choice.
However, for larger and more intricate applications with a need for streamlined versioning and sharing, Helm is likely to provide a more comprehensive solution.
The hybrid approach allows for a scalable and maintainable workflow, optimizing the benefits of both tools.
Ultimately, whether you choose Helm, Kustomize, or a combination of both, the key is to embrace a GitOps mindset and version-controlled approach to Kubernetes configuration management.
Happy chart-ing!
Share with friends