Introduction to

Helm and Charts

Definitions

Charts are packages of pre-configured Kubernetes resources.

Helm is a tool for managing Kubernetes charts.

Release ​is a collection of Kubernetes resources deployed to the cluster using Helm.

Helm

Installation

To install Helm client in MacOS, simply use Homebrew:

brew install kubernetes-helm

Afterward, we need to deploy Tiller to our Kubernetes cluster. This can be done with command:

helm init

The previous command will deploy Tiller in current active kubectl context.

Usage - Finding Charts

To see what charts are available, we can use:

helm search

To search for specific charts, use:

helm search mysql

To see what's inside a chart:

helm inspect stable/mariadb

Usage - Repositories

To view existing repositories:

helm repo list

To add new repository:

helm repo add coreos https://s3-eu-west-1.amazonaws.com/coreos-charts/stable/

Usage - Installing Charts

To install a chart:

helm install <release-name> 

Advanced usage:

helm install <release-name> --name <k8s-label> --namespace <k8s-namespace>

Example with Prometheus:

helm install coreos/prometheus-operator --name prometheus-operator --namespace monitoring
helm install coreos/kube-prometheus --name kube-prometheus --set global.rbacEnable=true --namespace monitoring

To delete an installed chart (or a release):

helm delete <release-name>

The deleted release still can be seen with:

helm list --deleted

To purge it:

helm delete --purge <release-name>

Usage - Deleting Charts

Charts

Creating a Simple Chart (1)

A skeleton:

mkdir hello-world-chart
cd hello-world-chart
mkdir templates
touch Chart.yml

A chart must at least have two things, a definition file and a template.

Creating a Simple Chart (2)

A definition file must at least define two properties, name and version. Put this in our Chart.yaml file:

name: hello-world-chart
version: 1.0.0

Creating a Simple Chart (3)

Now, let's create a k8s deployment resource template. Put this block of codes in templates/deployment.yaml:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-world
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
        - name: hello-world
          image: gcr.io/google-samples/node-hello:1.0
          ports:
            - containerPort: 8080
              protocol: TCP

Creating a Simple Chart (4)

Then, we'll create a k8s service resource that will expose our node-hello app. Put this one in templates/service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: hello-world
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    protocol: TCP
  selector:
    app: hello-world

Values (1)

We can store values and pass them as variables in Charts. To store values, write them in values.yaml file:

image:
  repository: gcr.io/google-samples/node-hello
  tag: '1.0'

Then we can use it as variable, for instance:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-world
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
        - name: hello-world
          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
          ports:
            - containerPort: 8080
              protocol: TCP

Values (2)

Values can be overwritten when we run Helm commands. For instance:

helm install --set image.tag='latest' .

Partials (1)

We can create partials by writing files in "templates/" folder with "_" prefix and ".tpl" extension. For example, we can write "_helpers.tpl" and fill it with:

{{- define "hello-world.release_labels" }}
app: {{ printf "%s-%s" .Release.Name .Chart.Name | trunc 63 }}
version: {{ .Chart.Version }}
release: {{ .Release.Name }}
{{- end }}
{{- define "hello-world.full_name" -}}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 -}}
{{- end -}}

Partials (2)

Now we can use our partials like this:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: {{ template "hello-world.full_name" . }}
  labels:
    {{- include "hello-world.release_labels" . | indent 4 }}
spec:
  replicas: 1
  template:
    metadata:
      labels:
        {{- include "hello-world.release_labels" . | indent 8 }}
    spec:
      containers:
        - name: hello-world
          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
          ports:
            - containerPort: 8080
              protocol: TCP

Partials (3)

And this:

apiVersion: v1
kind: Service
metadata:
  name: {{ template "hello-world.full_name" . }}
  labels:
    {{- include "hello-world.release_labels" . | indent 4 }}
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    protocol: TCP
  selector:
    app: {{ template "hello-world.full_name" . }}

Charts Repository

Preparing Google Bucket

First, we need a Google Bucket. For this tutorial, we'll use "gopay-helm-charts" bucket from our GCP. If we make a new one, make sure its permission is public.

Packaging Our Chart

First, we need a folder for our local chart repository. For this session, I'll just use existing one named "gopay-helm-charts" in my local machine.

Then, we need to package our chart:

helm package hello-world-chart

And move the generated tgz file into our folder:

mv hello-world-chart-1.0.0.tgz gopay-helm-charts

Then index it:

helm repo index gopay-helm-charts  --url https://gopay-helm-charts.storage.googleapis.com

Sync It with Google Bucket

When we're ready, we can use gsutil to dry run the sync process with Google Bucket:

gsutil rsync -d -n gopay-helm-charts/ gs://gopay-helm-charts

If all looks well, we can sync it:

gsutil rsync -d gopay-helm-charts/ gs://gopay-helm-charts

Introduction to Helm & Charts

By qblfrb

Introduction to Helm & Charts

  • 293