- What is Helm?
- Using helm
- Exercise: Installing Helm
- Exercise: Helm Repos
- Exercise: Managing the life cycle of my first release
- Exercise: Creating your first helm app
Helm helps you manage Kubernetes applications — Helm Charts help you define, install, and upgrade even the most complex Kubernetes application.
Charts are easy to create, version, share, and publish — so start using Helm and stop the copy-and-paste
Manage Complexity
Charts describe even the most complex apps, provide repeatable application installation, and serve as a single point of authority.
Easy Updates
Take the pain out of updates with in-place upgrades and custom hooks.
Simple Sharing
Charts are easy to version, share, and host on public or private servers.
Rollbacks
Use helm rollback
to roll back to an older version of a release with ease.
Main Helm Commands
- Init: Set up Helm for the first time (
helm init
) - Install: Install a chart (
helm install alpine
) - Get, Status, List: Find out about charts (
helm list
) - Repo Add, List, Remove, Index: Manage your helm repositories (
helm repo list
) - Search: Search repos for charts (
helm search
) - Create, Package: Create and package new charts (
helm create
)
There are various ways to install Helm Client: from binary, from source, using OS package managers or the installation script. You can find the installation details for your system here.
Check is installed
$ helm version
Client: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}
Tiller, the server portion of Helm, typically runs inside of your Kubernetes cluster. But for development, it can also be run locally, and configured to talk to a remote Kubernetes cluster.
Note RBAC is assumed to not be enabled.
Command
$ helm init
Check tiller is running
Command
$ kubectl get pods --show-labels --watch -n kube-system | grep tiller
A Helm repository is a collection of charts (packages) installable using Helm package manager and containing common configuration for Kubernetes apps such as resource definitions to configure the application’s runtime, various dependencies, communication mechanisms, and network settings.
By default, the Helm client interacts with the /stable branch of the official Kubernetes Charts repository that provides ~160 configured apps. The repository contains well-tested and well-maintained charts that comply with basic technical requirements of the Kubernetes. Redis, TensorFlow, NGINX, Apache Hadoop, Fluentd are just some examples of popular software available in this repository.
You can see the list of apps in the /stable repository by running the following command:
$ helm search
To find information about the individual chart, you can run helm inspect <chart-name>
. For example, to learn more about the contents of stable/redis chart, you can do the following:
Command
$ helm inspect stable/redis > redis.yaml
To find a full list of configurable options, you can use helm inspect values <chart-name>
or find the official chart documentation in the chart repository on GitHub.
Command
$ helm inspect values stable/redis > redis-value.yaml
To add new chart repos you can use helm repo add
Command
helm repo add bitnami https://charts.bitnami.com
Objective Learn how to fully manage the life cycle of a given existing chart.
You can customize the chart configuration during the installation. For example, to install the Redis chart with the server password and persistence.enabled
set to false
.
$ helm install --name my-redis-release --set password=yoursecretpassword,persistence.enabled=false stable/redis
As you see, we are using --set flag with a list of key/value pairs for the configuration options. Multiple values can be separated by , characters. So --set a=b,c=d becomes:
a: b
c: d
We can check the current release we have deployed
Command
$ helm list
We can delete the release too:
Command
$ helm delete my-redis-release
$ helm list --deleted
We can delete the release permanently by running:
Command
$ helm delete --purge my-redis-release
Back to the previous example, if you are going to edit multiple configuration fields, it would be a good idea to save them in a file and refer to that file during the installation. For example, let’s create a file with the YAML-formatted configuration for our Redis chart:
password: mypassword
persistence:
enabled: false
master:
resources:
Memory: 300Mi
CPU: 200m
Command
$ sh vi redis-config.yml
First, delete the release running helm delete my-redis-release --purge
and. Then, save the configuration above in the redis-config.yml and install the Redis chart with the following command:
$ helm install --name my-redis-release -f redis-config.yml stable/redis
This will create the Redis release named my-redis-release
. You can give any name to your release using the --name
flag on helm install
Check and discuss the output
As you see, Kubernetes has created a bunch of resources for your Redis app. If you are using Minikube
, open the Kubernetes dashboard with minikube dashboard to see them or use kubectl get commands to display them in your terminal.
Command
$ minikube dashboard
Alternatively you could run the following command ;-)
$ kubectl get all --selector=release=my-redis-release --show-labels
Helm client offers useful tools for managing your releases including upgrades and rollbacks. You may want to upgrade your release when a new version of the chart came out or when you need to change the chart’s configuration. To upgrade the release, you can use the helm upgrade
command. This command will take configuration you provide and try to perform the least invasive upgrade updating only things that have changed since the last release.
To illustrate how the upgrade works, let’s first change our Redis configuration file redis-config.yml
:
password: newpassword
persistence:
enabled: false
master:
resources:
Memory: 300Mi
CPU: 100m
podLabels:
mylabel: my-redis-v2
Now, let’s upgrade the release:
$ helm upgrade -f redis-config.yml my-redis-release stable/redis
Check new release history
$ helm history my-redis-release
Check new values
$ helm get values my-redis-release
Check new helm labels in pods
$ kubectl get pods --selector=release=my-redis-release --show-labels
You can rollback the release with helm rollback [RELEASE] [REVISION]
. Now, let´s do a rollback.
$ helm rollback my-redis-release 1
Check release history
$ helm history my-redis-release
Check old helm labels in pods
$ kubectl get pods --selector=release=my-redis-release --show-labels
Check old values
$ helm get values my-redis-release
Command
$ helm del --purge my-redis-release
Objectives: Our goal for this workshop is to create a Helm chart that takes the voting app demo and installs it in a Kubernetes cluster.
Our application has five parts:
- A front-end for users to vote
- A back-end that tallies votes
- An admin interface to see the results
- A Redis cache
- A PostgreSQL database
-
Deploy the app via manifests
Command
$ kubectl create namespace vote
Command
$ kubectl apply -Rf workshop-09/manifests/voting-app
Wait for the app to start
kubectl get pods -n vote -w
The vote interface is then available on port
31000
on each host of the cluster, the result one is available on port31001
Delete the app
Command
$ kubectl delete -Rf workshop-09/manifests/voting-app
-
Charts usage recap
Helm uses charts as the installable unit. A Chart is a package containing at least three components:
- A Chart.yaml, which describes the chart
- Templates, which Helm transforms into Kubernetes manifests
- A values.yaml file, which defines and describes configurable parameters
These files are all bundled together into an archive that can be moved from one place to another
-
Creating a Chart
Start by running the Helm command to create a new basic chart:
$ helm create voter
It should looks like
├── Chart.yaml ├── charts ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── ingress.yaml │ ├── service.yaml │ └── tests │ └── test-connection.yaml └── values.yaml
We will start by modifying the Chart.yaml
apiVersion: v1 # The chart schema version, always v1 for Helm 2 version: 0.1.0 # The version of the chart. Change this for each release. appVersion: "1.0" # The version of the main app in this chart. OPTIONAL description: An example cloud native voting app name: voter
You can verify that you correctly entered the data by running:
$ helm inspect chart ../voter
-
Templating Charts recap
Helm charts contain templates, which at its core are resource descriptions that Kubernetes can understand.
The Helm template language is written in
gotemplate
, a templating language provided by the Go standard library. Templates can be rendered locally for debugging purposes using thehelm template
command.In the last section, we created a Helm chart that contained three templates:
In the last section, we created a Helm chart that contained three templates:
- A Deployment for running a microservice (deployment.yaml)
- A Service for routing traffic to that microservice (service.yaml)
- An Ingress that can optionally be turn on to allow external traffic to access your app (ingress.yaml)
Let's take a look at a snippet of the Deployment template created in an earlier section:
apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "voter.fullname" . }} labels: {{ include "voter.labels" . | indent 4 }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app.kubernetes.io/name: {{ include "voter.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} template: metadata: labels: app.kubernetes.io/name: {{ include "voter.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: 80 protocol: TCP
As we can see, this looks a bit like a Deployment object in YAML format, sprinked with a few templates from gotemplate. We can see a few unique templates. Let's look at a few in particular:
{{ template "voter.fullname" . }}
{{ template "voter.name" . }}
{{ .Release.Name }}
{{ .Values.replicaCount }}
template
voter.fullname
is a template partial. Template partials arehelper
functions defined within the chart to abstract some common funcion calls to make the templates more easily readable and DRY. When we first created the chart, a file called_helpers.tpl
was created in the templates directory. That file is the default location for template partials, and Helm provides a few template partials out the gate in that file.voter.fullname
accepts one variable as input: the dot variable (.). The dot variable contains all of the variables injected by Helm into the template engine, such as values or information about the cluster.The output of
voter.fullname
is the chart name (voter) and the release name, joined with a hyphen (voter-release-name).voter.name
is just the chart name, sovoter
.In a nutshell, When you provide the following in values.yaml:
image: repository: dockersamples/examplevotingapp_vote
Helm will render that as
.Values.image.repository
to be made available to you in the templates.Run
helm template ./voter
to view the chart fully rendered as YAML manifests. This is what will eventually be supplied to Kubernetes. -
Configuring the Front-End (vote)
Take a look at the
values.yaml
file generated for us.This default values file has standard configurable parameters pre-defined. These parameters are used by files in templates.
The default Helm chart defines three Kubernetes resources:
- A Deployment for running a microservice
- A Service for routing traffic to that microservice
- An Ingress that can optionally be turn on to allow external traffic to access your app
It just so happens that we need these things for our example. So to get started, we'll change the default values to make use of them.
In the images section, make the following changes:
- Point repository to
dockersamples/examplevotingapp_vote
- Set tag to
before
And also change one thing in service:
- port:
5000
- type:
NodePort
- nodePort:
31000
-
Adding Templates for the rest of the voting-app
Copy from workshop-09/manifests/voting-app/ into /templates(Remember to make sure that the name is unique for each installation.)
Try to creata a similar filestructure
├── Chart.yaml ├── templates │ ├── _helpers.tpl │ ├── db │ │ ├── db-deployment.yaml │ │ └── db-service.yaml │ ├── redis │ │ ├── redis-deployment.yaml │ │ └── redis-service.yaml │ ├── result │ │ ├── result-deployment.yaml │ │ └── result-service.yaml │ ├── vote │ │ ├── vote-deployment.yaml │ │ └── vote-service.yaml │ └── worker │ └── worker-deployment.yaml └── values.yaml
Tip You can follow this values.yaml as example to create all the templates
# Default values for voter. # This is a YAML-formatted file. # Declare variables to be passed into your templates. # Voting app vote: replicaCount: 1 image: repository: dockersamples/examplevotingapp_vote tag: before pullPolicy: IfNotPresent imagePullSecrets: [] nameOverride: "" fullnameOverride: "" service: type: NodePort port: 5000 targetPort: 80 nodePort: 31000 ingress: enabled: false annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" hosts: - host: chart-example.local paths: [] tls: [] # - secretName: chart-example-tls # hosts: # - chart-example.local resources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little # resources, such as Minikube. If you do want to specify resources, uncomment the following # lines, adjust them as necessary, and remove the curly braces after 'resources:'. # limits: # cpu: 100m # memory: 128Mi # requests: # cpu: 100m # memory: 128Mi nodeSelector: {} tolerations: [] affinity: {} result: replicaCount: 1 image: repository: dockersamples/examplevotingapp_result tag: before pullPolicy: IfNotPresent service: type: NodePort port: 5001 targetPort: 80 nodePort: 31001 worker: replicaCount: 1 image: repository: dockersamples/examplevotingapp_worker pullPolicy: IfNotPresent redis: replicaCount: 1 image: repository: redis tag: alpine pullPolicy: IfNotPresent service: type: ClusterIP port: 6379 db: replicaCount: 1 image: repository: postgres tag: 9.4 pullPolicy: IfNotPresent service: type: ClusterIP port: 5432
-
Installing the chart
The first time you can install the chart as follows (selecting in which namespace you want)
helm install -n voting-app ./voter --namespace=vote
On every change of the chart you could run the following:
Command
helm upgrade voting-app ./voter --namespace=vote
-
Adding existing chart as dependencies
We were building a chart based on a sample voting app. Here are the images we needed:
- redis:alpine - The Redis server for a work queue
- postgres:9.4 - The persistent data storage
- dockersamples/examplevotingapp_result:before (The admin viewer)
- dockersamples/examplevotingapp_vote:before (The voting frontend)
- dockersamples/examplevotingapp_worker (The queue worker)
Let´s find out if we have any redis or postgres available as charts
$ helm search | grep redis bitnami/redis 8.0.8 5.0.5 Open source, advanced key-value store. It is often referr... incubator/redis-cache 0.4.1 4.0.12-alpine A pure in-memory redis cache, using statefulset and redis... stable/prometheus-redis-exporter 2.0.0 0.28.0 Prometheus exporter for Redis metrics stable/redis 8.0.8 5.0.5 Open source, advanced key-value store. It is often referr... stable/redis-ha 3.5.0 5.0.3 Highly available Kubernetes implementation of Redis
Command
$ helm search | grep postgres bitnami/postgresql 5.3.8 11.3.0 Chart for PostgreSQL, an object-relational database manag... stable/postgresql 5.3.8 11.3.0 Chart for PostgreSQL, an object-relational database manag... stable/prometheus-postgres-exporter 0.6.2 0.4.7 A Helm chart for prometheus postgres-exporter
Looks like we need to take care only of the dockersamples charts.
8.1) Subcharts and requirements.yaml
In Helm, a subchart is a regular Helm chart that is a dependency of your chart. By adding it to a special file called `requirements.yaml`, you can let Helm manage that chart for you.
Let's create a `requirements.yaml` file next to the `Chart.yaml` in our chart. Here's what belongs inside:
```yml
dependencies:
- name: redis # from search results above
version: 8.0.8 # Also from the search results above
repository: https://kubernetes-charts.storage.googleapis.com
```
**Note** that the repository URL comes from running helm repo list and copying the URL for the stable repo, which is where the Redis chart lives.
Next, run helm search postgresql and repeat the above for Postgres. By the end of that step, you should have two items in your dependencies array in requirements.yaml
8.2) Download the Dependencies
Run helm dep up to have Helm fetch those dependencies for you. When completed, you should be able to see two new directories inside of your chart's charts subdirectory.
```sh
$ helm dependency update
```
Your folder should look like this:
```sh
── Chart.yaml
├── charts
│ ├── postgresql-5.3.8.tgz
│ └── redis-8.0.8.tgz
├── requirements.lock
├── requirements.yaml
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
```
Next, we'll start working with Helm templates