Introduction
Helm is a Package manager. Package managers automate the process of installing, configuring, upgrading, and removing computer programs. Examples include the Red Hat® Package Manager (RPM), Homebrew, and Windows® PackageManagement.
An application in Kubernetes typically consists of at least two resource types:
- a deployment resource, which describes a set of pods to be deployed together
- a services resource, which defines endpoints for accessing the APIs in those pods.
The application can also include ConfigMaps, Secrets, and Ingress.
For any deployment, you need several Kubernetes commands (kubectl) to create and configure resources. Instead of manually creating each resource separately, you can create many resources with one command. A Helm chart defines several Kubernetes resources as a set. A default chart has a minimum of a deployment template and a service template.
Helm components and terminology
Helm has two elements, a client (Helm) and a server (Tiller). The server element runs inside a Kubernetes cluster and manages the installation of charts. This diagram shows how Helm components are related to each other:
- Helm: A command-line interface (CLI) that installs charts into Kubernetes, creating a release for each installation. To find new charts, you search Helm chart repositories.
- Chart: An application package that contains templates for a set of resources that are necessary to run the application. A template uses variables that are substituted with values when the manifest is created. The chart includes a values file that describes how to configure the resources.
- Repository: Storage for Helm charts. The namespace of the hub for official charts is stable.
- Release: An instance of a chart that is running in a Kubernetes cluster. You can install the same chart multiple times to create many releases.
- Tiller: The Helm server-side templating engine, which runs in a pod in a Kubernetes cluster. Tiller processes a chart to generate Kubernetes resource manifests, which are YAML-formatted files that describe a resource. YAML is a human-readable structured data format. Tiller then installs the release into the cluster. Tiller stores each release as a Kubernetes ConfigMap.
Why use Helm?
Helm can make deployments easier and repeatable because all resources for an application are deployed by running one command:
helm install <chart>
With Helm, configuration settings are kept separate from the manifest formats. You can edit the configuration values without changing the rest of the manifest. Configuration settings are in a values.yaml file. You update the runtime parameters in that file to deploy each application instance differently.
You can use single commands for installing, upgrading, and deleting releases.
Installing Helm
Helm chart repository
Deploying an application
The Helm install command deploys an application. The command output includes details about the release and resources. For the chart in this example, stable/mysql, the release name is loping-toad. One resource of each type exists, all named loping-toad-mysql:
- Secret
- Service
- Deployment
- PersistentVolumeClaim
$ helm search mysql
NAME VERSION DESCRIPTION
stable/mysql 0.1.1 Chart for MySQL
$ helm install stable/mysql
Fetched stable/mysql to mysql-0.1.1.tgz
NAME: loping-toad
LAST DEPLOYED: Thu Oct 20 14:54:24 2016
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Secret
NAME TYPE DATA AGE
loping-toad-mysql Opaque 2 3s
==> v1/Service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
loping-toad-mysql 192.168.1.5 <none> 3306/TCP 3s
==> extensions/Deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
loping-toad-mysql 1 0 0 0 3s
==> v1/PersistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
loping-toad-mysql Pending
Default and custom deployment values
The default values for a deployment are stored in the values.yaml file in the chart. You can customize aspects of the deployment by overriding those values.
First, the Helm CLI uses the Kubernetes CLI’s configuration(kubectl) to connect to your current cluster.
~/.kube/config
kubectl config view
After it connects to your cluster, you use Helm installation commands to specify the attributes of the release. To specify a release’s name, use the —name flag:
helm install --name CustomerDB stable/mysql
To deploy the release into a Kubernetes namespace, use the —namespace flag:
$ helm install --namespace ordering-system stable/mysql
To override a value, use the —set flag:
helm install --set user.name='student',user.password='passw0rd' stable/mysql
To override values with a values file, use the —values or the —f flag:
helm install --values myvalues.yaml stable/mysql
Helm command reference
Helm provides many commands for managing charts and Helm repositories. This list shows examples of the more common commands. After you configure a connection, you must add the —tls option to Helm commands that access the server through Tiller.
- Install Tiller:
helm init
- Create a chart:
helm create <chart>
- List the repositories:
helm repo list
- Search for a chart:
helm search <keyword>
- Get information about a chart:
helm inspect <chart>
- Deploy a chart (creates a release):
helm install <chart>
- List all releases:
helm list --all
- Get the status of a release:
$ helm status <release>
- Get the details about a release:
helm get <release>
- Upgrade a release:
helm upgrade <release> <chart>
- Roll back a release:
helm rollback <release> <revision>
- Delete a release:
helm delete <release>
Charts and the chart lifecycle
The Helm create command generates a chart with sample files. By default, a chart starts with sample templates for a Kubernetes deployment and service. In the simplest case, you edit the values.yaml file to modify the default configuration for your application.
After you run an installation command in the Helm CLI, these actions occur:
- Helm CLI loads the chart into Tiller.
- Tiller renders the chart templates.
- Each template generates a Kubernetes resource manifest file (YAML). Tiller runs each of the template files, generating the resource files. Tiller then loads the resources as described by the manifests into the Kubernetes cluster.
- Tiller loads the resulting resources into Kubernetes.
- Tiller returns the release data to the client.
- The client exits.
Chart lifecycle hooks
Throughout the steps in the chart lifecycle, you can specify hooks, which are predefined actions to be run at specific times. Hooks can be any Kubernetes resource, often a Kubernetes job. Hooks are in the templates directory of the chart.
For example, Tiller runs preinstall hooks before step 2 of the lifecycle and post-install hooks after step 2. The lifecycle hooks for Helm are as follows:
- Preinstall hooks run after templates are rendered and before any resources are created in Kubernetes.
- Post-install hooks run after all resources are loaded into Kubernetes.
- Pre-delete hooks run before any resources are deleted from Kubernetes.
- Post-delete hooks run after all the release’s resources are deleted.
- Pre-upgrade hooks run after templates are rendered and before any resources are loaded into Kubernetes.
- Post-upgrade hooks run after all resources are upgraded.
- Pre-rollback hooks run after templates are rendered and before any resources are rolled back.
- Post-rollback hooks run after all resources are modified.
Packaging charts
A chart is a directory. A Helm client can use chart directories on the same computer, but it’s difficult to share with other users on other computers.
You package a chart by bundling the chart.yaml and related files into a .tar file and then installing the chart into a chart file:
helm package <chart-path>
helm install <chart-name>.tgz
To add a chart to a repository, copy it to the directory and regenerate the index:
helm repo index <charts-path> # Generates index of the charts in the repo
Templates and settings files
Creating a chart consists of implementing a template and populating a settings file, which is the configuration file that the template uses. Settings files, specifically the values.yaml file, define the chart’s API. The settings files list the variables that the templates can use. For examples of chart templates, see https://github.com/kubernetes/charts/.
Each file is a Golang template. The template includes functions from the Sprig template library. A template can create the manifest for any type of Kubernetes resource.
Each file in a chart’s templates directory is expected to be a template and to generate a Kubernetes resource manifest. The file name can be anything. Ideally, it describes the resource that it defines. A few exceptions exist:
The notes file, NOTES.txt, provides instructions to the chart’s users.
Files whose names begin with an underscore, such as _helpers.tpl, are expected to contain partials. A partial, which is also called a subtemplate, is a template in a file that can be used by other templates. For example, a partial can contain utility functions.
Deployment and service template examples
In these examples, the Helm deployment and service templates are shown with the corresponding Kubernetes manifest files.
Helm deployment template
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: template "fullname" .
labels:
app: template "name" .
chart: .Chart.Name }}-{{ .Chart.Version
heritage: .Release.Service
release: .Release.Name
spec:
replicas: .Values.replicaCount
template:
metadata:
- if .Values.podAnnotations
annotations:
toYaml .Values.podAnnotations | indent 8
- end
labels:
app: template "name" .
release: .Release.Name
spec:
containers:
- name: template "name" .
image: " .Values.image.repository }}:{{ .Values.image.tag "
imagePullPolicy: .Values.image.pullPolicy
ports:
- name: http
containerPort: 80
protocol: TCP
. . .
Kubernetes deployment manifest
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Helm service template
apiVersion: v1
kind: Service
metadata:
- if .Values.service.annotations
annotations: toYaml .Values.service.annotations | indent 4
- end
name: template "fullname" .
labels:
app: template "name" .
chart: .Chart.Name }}-{{ .Chart.Version
heritage: .Release.Service
release: .Release.Name
spec:
selector:
app: template "name" .
release: .Release.Name
ports:
- name: http
protocol: TCP
port: .Values.service.port
targetPort: http
- if (and (eq .Values.service.type "NodePort") ...)
nodePort: .Values.service.nodePort
- end
. . .
Kubernetes service manifest
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
YAML file examples
Helm uses values in the values.yaml and chart.yaml files to populate the chart’s templates.
Values (values.yaml)
The values.yaml file is the chart’s API.
replicaCount: 1
restartPolicy: Never
# Evaluated by the post-install hook
sleepyTime: "10"
index: >-
<h1>Hello</h1>
<p>This is a test</p>
image:
repository: nginx
tag: 1.11.0
pullPolicy: IfNotPresent
service:
annotations: {}
clusterIP: ""
externalIPs: []
loadBalancerIP: ""
loadBalancerSourceRanges: []
type: ClusterIP
port: 8888
nodePort: ""
podAnnotations: {}
resources: {}
nodeSelector: {}
Helm deployment template
. . .
spec:
replicas: .Values.replicaCount
template:
metadata:
- if .Values.podAnnotations
annotations:
toYaml .Values.podAnnotations | indent 8
- end
. . .
Helm service template
. . .
spec:
ports:
- name: http
protocol: TCP
port: .Values.service.port
targetPort: http
- if (and (eq .Values.service.type "NodePort") ...)
nodePort: .Values.service.nodePort
- end
. . .
Chart (chart.yaml)
The chart.yaml file is the chart’s metainformation.
name: nginx
description: A basic NGINX HTTP server
version: 0.1.0
keywords:
- http
- nginx
- www
- web
home: https://github.com/kubernetes/helm
sources:
- https://hub.docker.com/_/nginx/
maintainers:
- name: technosophos
email: mbutcher@deis.com
Helm template
. . .
metadata:
- if .Values.service.annotations
annotations: toYaml .Values.service.annotations | indent 4
- end
name: template "fullname" .
labels:
app: template "name" .
chart: .Chart.Name }}-{{ .Chart.Version
heritage: .Release.Service
release: .Release.Name
. . .
Chart template helper and predefined value examples
This example shows a helper file used by a Helm template to construct the “full name” and “name” of the template. The example shows only part of the Helm template.
Helpers (templates/_helpers.tpl)
/* vim: set filetype=mustache: */
/* Expand the name of the chart. */
- define "name" -
- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -
- end -
/* Create a default fully qualified app name. We truncate at 63 chars because . . . */
- define "fullname" -
- $name := default .Chart.Name .Values.nameOverride -
- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -
- end -
Helm template
. . .
metadata:
name: template "fullname" .
labels:
app: template "name" .
chart: .Chart.Name }}-{{ .Chart.Version
heritage: .Release.Service
release: .Release.Name
. . .
Chart predefined values
This summary shows the predefined values that Helm uses when it renders Kubernetes manifest files.
- Release – Information about the release being created
- Release.Name – The name of the release (not the chart)
- Release.Service – The service that conducted the release, normally Tiller
- Release.Revision – The revision number. Begins at 1, and increments with each helm upgrade
- Chart – The contents of the chart.yaml
- Chart.Name
- Chart.Version
- Chart.Maintainers
- Files – Map of all non-special files in the chart
- Capabilities – Map of info about Kubernetes and Helm
- Capabilities.KubeVersion
- Capabilities.TillerVersion
- Capabilities.APIVersions
- Template – Information about the current template
Helm template
. . .
metadata:
- if .Values.service.annotations
annotations: toYaml .Values.service.annotations | indent 4
- end
name: template "fullname" .
labels:
app: template "name" .
chart: .Chart.Name }}-{{ .Chart.Version
heritage: .Release.Service
release: .Release.Name
. . .