Introduction
Helm is a package manager for Kubernetes that simplifies the process of defining, installing, and upgrading even the most complex Kubernetes applications. In this post, we’ll explore Helm commands, dive into writing Helm templates, and discuss best practices for using Helm in your Kubernetes workflows.
Why Use Helm?
Before we dive into the technical details, let’s understand why Helm is so valuable:
- Simplifies Complex Deployments: Helm allows you to define, install, and upgrade even the most complex Kubernetes applications.
- Promotes Reusability: With Helm charts, you can package applications and make them easily shareable and reusable.
- Manages Dependencies: Helm can manage charts that depend on each other, simplifying the deployment of applications with multiple components.
- Facilitates Version Control: Helm charts can be version controlled, making it easier to track changes and roll back if necessary.
- Enhances Collaboration: Teams can share and collaborate on Helm charts, standardizing deployment processes across an organization.
Helm vs. Regular Kubernetes YAML Files
While you can deploy applications to Kubernetes using regular YAML files, Helm offers several advantages:
- Templating: Helm allows you to use variables and functions in your YAML files, making them more flexible and reusable.
- Packaging: Helm bundles all related Kubernetes resources into a single package (chart), making it easier to manage and distribute.
- Versioning: Helm charts are versioned, allowing for easier upgrades and rollbacks.
- Lifecycle Management: Helm provides commands for installing, upgrading, and uninstalling applications, simplifying the management of application lifecycles.
Basic Helm Commands
Let’s start with some essential Helm commands:
# Install a chart
helm install [RELEASE_NAME] [CHART]
# Upgrade a release
helm upgrade [RELEASE_NAME] [CHART]
# Rollback a release
helm rollback [RELEASE_NAME] [REVISION]
# List releases
helm list
# Uninstall a release
helm uninstall [RELEASE_NAME]
# Create a new chart
helm create [CHART_NAME]
# Package a chart
helm package [CHART_PATH]
Writing Helm Templates
Helm uses Go templates to create dynamic Kubernetes manifest files. Let’s explore some key concepts in Helm templating.
Variable Declaration
Variables in Helm templates are typically defined in the values.yaml
file and can be accessed using the .Values
object.
# values.yaml
replicaCount: 3
image:
repository: nginx
tag: latest
In your template files, you can reference these values like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-nginx
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
Using Arrays
Arrays in Helm can be defined in the values.yaml
file and iterated over in templates.
# values.yaml
env:
- name: DEBUG
value: "true"
- name: LOG_LEVEL
value: "info"
You can use these in your template like this:
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
Conditions
Conditional statements in Helm templates allow you to include or exclude parts of your manifest based on certain conditions.
{{- if .Values.persistence.enabled }}
volumes:
- name: data
persistentVolumeClaim:
claimName: {{ .Release.Name }}-data
{{- end }}
Loops
Loops in Helm templates allow you to iterate over arrays or maps.
{{- range $key, $value := .Values.configMap }}
{{ $key }}: {{ $value | quote }}
{{- end }}
Best Practices
- Use Named Templates: Break down complex templates into smaller, reusable named templates.
- Leverage Helper Functions: Helm provides many built-in functions. Use them to keep your templates clean and readable.
- Provide Default Values: Always provide sensible default values in your
values.yaml
file. - Use Conditional Blocks Wisely: Use conditions to make your charts more flexible and adaptable to different environments.
- Document Your Chart: Use the
NOTES.txt
file to provide usage instructions and important information about your chart. - Version Your Charts: Use semantic versioning for your charts to make upgrades and rollbacks easier.
Example: A Complete Helm Chart
Let’s put it all together with a simple example of a Helm chart for a web application.
# values.yaml
replicaCount: 2
image:
repository: nginx
tag: latest
service:
type: ClusterIP
port: 80
ingress:
enabled: false
hosts:
- host: chart-example.local
paths: ["/"]
env:
- name: LOG_LEVEL
value: "info"
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mychart.fullname" . }}
labels:
{{- include "mychart.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "mychart.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "mychart.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- name: http
containerPort: 80
protocol: TCP
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
# templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ include "mychart.fullname" . }}
labels:
{{- include "mychart.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "mychart.selectorLabels" . | nindent 4 }}
# templates/ingress.yaml
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "mychart.fullname" . }}
labels:
{{- include "mychart.labels" . | nindent 4 }}
spec:
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ . }}
pathType: Prefix
backend:
service:
name: {{ include "mychart.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}
This example demonstrates the use of variables, arrays, conditions, and loops in a practical Helm chart. It includes a deployment, a service, and an optional ingress, all of which can be customized through the values.yaml
file.
Conclusion
Helm is a powerful tool that can significantly simplify your Kubernetes deployments. By mastering Helm commands and template writing, you can create flexible, reusable charts that make deploying and managing applications on Kubernetes a breeze. Remember to follow best practices, leverage Helm’s built-in functions, and always test your charts thoroughly before using them in production environments.