Using Helm with Kubernetes: A Guide to Helm Charts and Their Implementation
Alex Merced
Co-Author of “Apache Iceberg: The Definitive Guide” | Head of DevRel at Dremio | LinkedIn Learning Instructor | Tech Content Creator
Managing applications in Kubernetes can be complex, requiring multiple YAML files to define resources such as Deployments, Services, ConfigMaps, and Secrets. Manually maintaining and updating these configurations as applications scale becomes cumbersome and error-prone. This is where Helm comes in.
Helm is a package manager for Kubernetes that simplifies deployment by bundling application configurations into reusable, version-controlled Helm charts. With Helm, you can deploy applications with a single command, manage updates seamlessly, and roll back to previous versions if needed.
Why Use Helm?
What You’ll Learn in This Guide
In this blog, we’ll cover:
By the end of this guide, you’ll have a strong foundation in Helm and be able to deploy, manage, and scale Kubernetes applications efficiently.
Understanding Helm: The Package Manager for Kubernetes
What is Helm?
Helm is a package manager for Kubernetes that helps deploy, configure, and manage applications in a Kubernetes cluster. Instead of manually writing and applying multiple Kubernetes YAML manifests, Helm allows you to package them into reusable Helm Charts, simplifying deployment and maintenance.
Why Use Helm?
Managing Kubernetes resources can become complex, especially when deploying applications with multiple components (Deployments, Services, ConfigMaps, Secrets, etc.). Helm provides several advantages:
How Does Helm Compare to Traditional Kubernetes Manifests?
+-------------------+-------------------------------------------+-------------------------------------------+
| Feature | Kubernetes YAML Manifests | Helm Charts |
+-------------------+-------------------------------------------+-------------------------------------------+
| Management | Requires manually applying multiple YAML | Uses a single Helm command |
| | files | |
+-------------------+-------------------------------------------+-------------------------------------------+
| Configuration | Static YAML definitions | Dynamic templating via values.yaml |
+-------------------+-------------------------------------------+-------------------------------------------+
| Version Control | Difficult to track changes manually | Built-in versioning & rollback |
+-------------------+-------------------------------------------+-------------------------------------------+
| Reusability | Limited; each deployment needs its own | Reusable and configurable charts |
| | YAML | |
+-------------------+-------------------------------------------+-------------------------------------------+
| Dependencies | Managed manually | Handled via requirements.yaml (deprecated)|
| | | or Chart.yaml |
+-------------------+-------------------------------------------+-------------------------------------------+
How Helm Works
Helm Components and Architecture
Helm follows a client-only architecture in Helm v3, directly interacting with the Kubernetes API server without requiring a backend component like Tiller (which was used in Helm v2). Below are the core elements of Helm:
Helm Workflow: How Helm Manages Deployments
Helm Command Lifecycle
+--------------------------------------------+--------------------------------------------------------------+
| Command | Purpose |
+--------------------------------------------+--------------------------------------------------------------+
| helm repo add <repo-name> <repo-url> | Adds a Helm chart repository |
+--------------------------------------------+--------------------------------------------------------------+
| helm search repo <keyword> | Searches for a chart in repositories |
+--------------------------------------------+--------------------------------------------------------------+
| helm install <release-name> <chart-name> | Installs a Helm chart and creates a release |
+--------------------------------------------+--------------------------------------------------------------+
| helm list | Lists all active Helm releases |
+--------------------------------------------+--------------------------------------------------------------+
| helm status <release-name> | Shows details of a deployed release |
+--------------------------------------------+--------------------------------------------------------------+
| helm upgrade <release-name> <chart-name> | Upgrades an existing release to a new chart version |
+--------------------------------------------+--------------------------------------------------------------+
| helm rollback <release-name> <revision> | Rolls back a release to a previous version |
+--------------------------------------------+--------------------------------------------------------------+
| helm uninstall <release-name> | Deletes a release and removes associated resources |
+--------------------------------------------+--------------------------------------------------------------+
Helm in Action: A Simple Example
Let’s say you want to deploy NGINX using Helm. You can do this with a single command:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-nginx bitnami/nginx
This command:
To check the status of the deployment:
helm list
helm status my-nginx
To uninstall the release:
helm uninstall my-nginx
Installing and Configuring Helm
Before using Helm, install it on your local machine and configure it to work with your Kubernetes cluster. This section will walk through the installation process and initial setup.
Prerequisites
Installing Helm
Helm can be installed on macOS, Linux, and Windows using various package managers.
macOS (Using Homebrew)
brew install helm
Linux (Using Script)
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
Windows (Using Chocolatey)
choco install kubernetes-helm
Verifying the Installation
After installation, verify that Helm is installed correctly by running:
helm version
You should see output similar to:
version.BuildInfo{Version:"v3.x.x", GitCommit:"...", GitTreeState:"clean", GoVersion:"..."}
Configuring Helm
Adding a Helm Repository
Helm uses repositories to store charts. You can add a popular repository, such as the Bitnami Helm charts, using:
helm repo add bitnami https://charts.bitnami.com/bitnami
To confirm the repository has been added:
helm repo list
Updating Helm Repositories
To fetch the latest charts from all added repositories, run:
helm repo update
Searching for Helm Charts
To search for a specific application within your configured repositories:
helm search repo nginx
Installing a Helm Chart
Once Helm is set up, you can deploy an application. For example, to deploy NGINX using the Bitnami Helm chart:
helm install my-nginx bitnami/nginx
This will:
Checking the Installation
List all active Helm releases:
helm list
Check the status of a specific release:
helm status my-nginx
Uninstalling a Helm Release
To remove the my-nginx release and all associated resources:
helm uninstall my-nginx
Understanding Helm Charts
What is a Helm Chart?
A Helm chart is a packaged application definition that contains Kubernetes resource templates and default configuration values. It allows you to deploy complex applications with a single command while keeping configurations modular and reusable.
Each chart defines:
Structure of a Helm Chart
When you create a Helm chart, it follows a specific directory structure:
mychart/
│── charts/ # Directory for chart dependencies (other charts)
│── templates/ # Contains Kubernetes YAML templates
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── _helpers.tpl # Contains reusable template functions
│── Chart.yaml # Metadata about the chart (name, version, description)
│── values.yaml # Default configuration values for the chart
│── README.md # Documentation about the chart
Each file in this structure serves a specific purpose:
Example: Chart.yaml
The Chart.yaml file provides information about the chart:
apiVersion: v2
name: mychart
description: A sample Helm chart for Kubernetes
type: application
version: 1.0.0
appVersion: 1.16.0
name: The chart's name.
description: A brief description of what the chart does.
version: The chart version (used for versioning updates).
appVersion: The application version the chart deploys.
Example: values.yaml
The values.yaml file defines default configuration values:
replicaCount: 2
image:
repository: nginx
tag: latest
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
These values can be overridden when installing the chart using the --set flag or a custom values file.
Example: templates/deployment.yaml
A sample Kubernetes Deployment template using Helm’s templating syntax:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-nginx
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.port }}
In this template:
Rendering Helm Templates
Before applying a Helm chart, you can preview how the templates will render using:
helm template mychart
Writing Your Own Helm Chart
Now that we understand Helm charts and their structure, let’s walk through the process of creating a custom Helm chart from scratch.
Step 1: Create a New Helm Chart
To generate a new Helm chart, use the following command:
helm create mychart
This command creates a new directory mychart/ with the standard Helm chart structure.
Step 2: Modify values.yaml
Open values.yaml and update it with custom values. Let’s modify it to deploy an NGINX web server with a LoadBalancer service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-nginx
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.port }}
Step 3: Customize Deployment Template
Edit templates/deployment.yaml to use Helm’s templating syntax:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-nginx
labels:
app: nginx
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.port }}
Step 4: Customize the Service Template
Edit templates/service.yaml to configure the service:
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-nginx
spec:
type: {{ .Values.service.type }}
selector:
app: nginx
ports:
- protocol: TCP
port: {{ .Values.service.port }}
targetPort: {{ .Values.service.port }}
Step 5: Package the Helm Chart
Once you’ve modified the necessary files, package the chart:
helm package mychart
This creates a .tgz archive of the chart, making it ready for distribution.
Step 6: Install the Chart
Deploy the chart to your Kubernetes cluster:
helm install my-nginx ./mychart
This:
Step 7: Verify the Deployment
Check the deployed resources:
helm list
kubectl get pods
kubectl get svc
Step 8: Uninstall the Chart
To remove the deployment, use:
helm uninstall my-nginx
Deploying Applications with Helm
Once you’ve created or downloaded a Helm chart, you can use Helm to deploy and manage applications in your Kubernetes cluster. This section will review the deployment process, including installation, upgrades, rollbacks, and uninstallation.
Step 1: Installing a Helm Chart
To deploy an application using Helm, use the helm install command:
helm install my-nginx ./mychart
If you are installing a chart from a repository, such as Bitnami, use:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-nginx bitnami/nginx
This command:
Step 2: Verifying the Deployment
Once the chart is installed, verify that the release is active:
helm list
This will output something like:
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-nginx default 1 2024-02-16 10:00:00 deployed nginx-1.2.3 1.21.6
You can check the detailed status of a release:
helm status my-nginx
To view the created Kubernetes resources:
kubectl get pods
kubectl get svc
Step 3: Customizing Helm Releases
Helm allows you to override default values using the --set flag or a custom values file.
Using the --set Flag
You can override individual values like this:
helm install my-nginx bitnami/nginx --set replicaCount=3
Using a Custom values.yaml File
To provide multiple custom values, create a my-values.yaml file:
replicaCount: 3
service:
type: LoadBalancer
port: 8080
Then, deploy the chart with:
helm install my-nginx bitnami/nginx -f my-values.yaml
Step 4: Upgrading a Helm Release
If you need to modify a running deployment, use the helm upgrade command:
helm upgrade my-nginx bitnami/nginx --set replicaCount=5
To upgrade using a modified values file:
helm upgrade my-nginx bitnami/nginx -f my-values.yaml
This updates the deployment while keeping existing resources intact.
Step 5: Rolling Back to a Previous Version
Helm maintains a history of releases, allowing you to roll back if needed.
List the release history:
helm history my-nginx
Roll back to a specific revision:
helm rollback my-nginx 1
Step 6: Uninstalling a Helm Release
To remove a Helm deployment and all its associated resources, run:
helm uninstall my-nginx
To confirm deletion:
helm list
kubectl get all
Helm Best Practices
Using Helm effectively requires following best practices to ensure maintainability, security, and scalability of deployments. This section outlines key strategies for optimizing Helm usage in production environments.
1. Organizing Values in values.yaml for Clarity
A well-structured values.yaml file improves readability and maintainability.
? Good Example: Structured and Documented
replicaCount: 3 # Number of replicas for high availability
image:
repository: nginx
tag: latest
pullPolicy: IfNotPresent # Pull policy to optimize image fetching
service:
type: LoadBalancer
port: 80 # Publicly exposed service port
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 250m
memory: 128Mi
? Bad Example: Unstructured and Unclear
replicaCount: 3
image: nginx:latest
serviceType: LoadBalancer
port: 80
cpu: 500m
memory: 256Mi
2. Using helm dependency for Managing Dependencies
If your chart depends on other charts (e.g., a database), declare them in Chart.yaml:
dependencies:
- name: postgresql
version: "12.1.3"
repository: "https://charts.bitnami.com/bitnami"
Then, update dependencies before installing:
helm dependency update
This ensures that all required subcharts are installed and properly versioned.
3. Leveraging helm secrets for Sensitive Values
Avoid storing credentials in values.yaml. Instead, use Helm Secrets to encrypt sensitive values.
Install the Helm Secrets plugin:
helm plugin install https://github.com/zachomedia/helm-secrets
Encrypt sensitive values using SOPS:
sops --encrypt --in-place my-values.yaml
Install a chart using encrypted values:
helm install my-app ./mychart -f my-values.yaml
This ensures secrets are not stored in plaintext inside version control.
4. Automating Helm Deployments in CI/CD Pipelines
Integrate Helm with CI/CD tools like GitHub Actions, GitLab CI/CD, or ArgoCD to automate deployments.
Example GitHub Actions Workflow for Helm
name: Deploy Helm Chart
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install Helm
run: |
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
- name: Deploy to Kubernetes
run: |
helm upgrade --install my-app ./mychart --namespace prod
This automates deployments whenever code is pushed to the main branch.
5. Keeping Charts Versioned and Documented
#6. Managing Multiple Environments (Dev, Staging, Prod)
Helm allows environment-specific values with separate values files:
helm install my-app ./mychart -f values-dev.yaml
helm install my-app ./mychart -f values-prod.yaml
This ensures different configurations for testing and production.
7. Helm Security Considerations
Summary
Helm in Production: Managing Complexity at Scale
As organizations scale their Kubernetes deployments, managing Helm charts effectively in production becomes crucial. This section explores how Helm integrates with GitOps tools, supports multi-environment management, and follows best practices for high availability and security.
1. Using GitOps with Helm (ArgoCD & Flux)
GitOps enables declarative infrastructure management, where Helm charts are stored in Git repositories and automatically deployed using tools like ArgoCD and Flux.
Deploying Helm Charts with ArgoCD
ArgoCD monitors a Git repository and applies changes automatically.
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Deploy a Helm Chart with ArgoCD:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-helm-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/my-org/helm-charts.git
targetRevision: main
path: mychart
helm:
valueFiles:
- values-prod.yaml
destination:
server: https://kubernetes.default.svc
namespace: prod
Apply the application manifest:
kubectl apply -f my-helm-app.yaml
ArgoCD will now continuously sync the Helm chart with the Kubernetes cluster.
Using FluxCD for Helm Deployments
FluxCD can also automate Helm deployments:
flux create source git my-helm-repo \
--url=https://github.com/my-org/helm-charts.git \
--branch=main
flux create helmrelease my-app \
--source=GitRepository/my-helm-repo \
--chart=mychart \
--namespace=prod
GitOps ensures:
2. Managing Multi-Cluster Deployments
For enterprises running multiple Kubernetes clusters (e.g., dev, staging, prod), Helm enables consistent deployments across environments.
Option 1: Context Switching with kubectl
kubectl config use-context dev-cluster
helm install my-app ./mychart --namespace dev
kubectl config use-context prod-cluster
helm install my-app ./mychart --namespace prod
Option 2: Using Helmfile for Multi-Cluster Deployments
Helmfile allows managing multiple Helm releases in a declarative format.
Example helmfile.yaml:
releases:
- name: my-app-dev
namespace: dev
chart: ./mychart
values:
- values-dev.yaml
- name: my-app-prod
namespace: prod
chart: ./mychart
values:
- values-prod.yaml
Deploy all environments at once:
helmfile apply
3. Ensuring High Availability and Reliability
Use Helm Hooks: Automate pre-install and post-install tasks.
annotations:
"helm.sh/hook": pre-install
Enable Readiness and Liveness Probes to ensure application health:
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
Use Rolling Updates with strategy to prevent downtime:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
4. Helm Security Best Practices for Production
Restrict Helm Permissions using Role-Based Access Control (RBAC):
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: prod
name: helm-user
rules:
- apiGroups: ["*"]
resources: ["deployments", "services"]
verbs: ["get", "list", "create", "update", "delete"]
Avoid Storing Secrets in values.yaml:
Implement Image Scanning:
Regularly Update Helm and Charts:
5. Monitoring and Logging Helm Deployments
Track Helm Releases:
helm list --all-namespaces
Monitor Deployments with Prometheus & Grafana:
Install Prometheus using Helm:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/prometheus
Integrate with Grafana for dashboard visualization.
Use Helm Logs to Debug Issues:
helm get manifest my-app
helm get values my-app
helm get notes my-app
Summary
9. Conclusion and Next Steps
Helm simplifies Kubernetes application deployment, making it easier to manage complex workloads with reusable, version-controlled charts. By leveraging Helm, teams can standardize configurations, automate deployments, and integrate with GitOps workflows to achieve reliable and scalable Kubernetes operations.
Key Takeaways
Next Steps: Continue Learning Helm
Now that you understand Helm’s capabilities, here are some next steps to deepen your knowledge and practical experience:
Final Thoughts
Helm is an essential tool for Kubernetes administrators and DevOps teams looking to optimize deployment workflows. Whether you are deploying simple microservices or complex cloud-native applications, Helm provides the flexibility, automation, and reliability needed to scale efficiently.
Start experimenting with Helm today and take your Kubernetes skills to the next level!
Additional Resources