Published on

Creating Charts for Helm

Authors

Today I had to work with an existing Helm chart in our codebase. As part of this I better familiarized myself with how Helm charts are composed. I found the best place to start is the page using Helm. This goes through the core Helm concepts and how to use a Helm chart. Based on this I learnt the following:

How Helm Charts are Structured

  • The easiest place to start is run: helm create yourChartName
    • This creates the initial scaffolding for your chart
    • More details on this can be found here
  • Charts will generally live in a directory with the same name as the chart
    • In this directory you will have:
      • .helmignore: Indicate to helm what it should ignore when packaging a chart
      • Chart.yaml: this is where you define your chart information like, name, version as well as the Kubernetes versions it will work with
      • values.yaml: this is the default values to use for template variables you define
      • charts/: a directory of 0 or more charts that your chart depends on
      • templates/: this is where the meat of your chart is
        • This is where you define your Kubernetes infrastructure but you template the parts of it you want to be able to override

How To Install Your Helm Charts

  • Release names change every time the helm install ./yourChart command is run
    • This is done by Helm to differentiate between 2 or more of the same deployment.
      • The --name option can be is used to provide a fixed release name.
    • ./yourChart is the directory created when you originally ran the helm create command
  • Run helm list or helm ls to get a list of releases
  • helm status nameOfRelease: gives more detail about the installed Chart like what makes up the chart what the current status of the chart deployment is and administrator details
  • helm inspect values nameOfChart: gives details on what can be configured in a chart

Overiding Helm Chart Configuration

Sometimes you need to be able to change the values of your Helm charts on the fly. With vanilla Kubernetes you can use Kubernetes patches. With Helm you can do this on the fly:

You can then override any of these settings in a YAML formatted file, and then pass that file during installation.

$ echo '{mariadbUser: user0, mariadbDatabase: user0db}' > config.yaml
$ helm install -f config.yaml stable/mariadb

How To Debug Your Helm Charts

  • To debug/test your chart
    • helm install --dry-run --debug ./mychart
      • This is where mychart is the directory holding the items generated with the create command
      • You need to have this running against a cluster otherwise you get an error similar to: Error: Get https://1.2.3.4:8443/api/v1/namespaces/kube-system/pods?labelSelector=app%3Dhelm%2Cname%3Dtiller: dial tcp 1.2.3.4:8443: connect: no route to host
        • Give your cluster enough time to start up: Error: could not find a ready tiller pod

When running a dry-run of the install you will get something like the following:

> helm install --dry-run --debug ./mychart
[debug] Created tunnel using local port: '38339'

[debug] SERVER: "127.0.0.1:38339"

[debug] Original chart version: ""
[debug] CHART PATH: /home/ymr/code/tmp/helm_chart_own/mychart

NAME:   kissed-peacock
REVISION: 1
RELEASED: Fri Jun  8 16:24:46 2018
CHART: mychart-0.1.0
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
affinity: {}
image:
  pullPolicy: IfNotPresent
  repository: nginx
  tag: stable
ingress:
  annotations: {}
  enabled: false
  hosts:
  - chart-example.local
  path: /
  tls: []
nodeSelector: {}
replicaCount: 1
resources: {}
service:
  port: 80
  type: ClusterIP
tolerations: []

HOOKS:
MANIFEST:

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: kissed-peacock-mychart
  labels:
    app: mychart
    chart: mychart-0.1.0
    release: kissed-peacock
    heritage: Tiller
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: mychart
    release: kissed-peacock
---
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: kissed-peacock-mychart
  labels:
    app: mychart
    chart: mychart-0.1.0
    release: kissed-peacock
    heritage: Tiller
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mychart
      release: kissed-peacock
  template:
    metadata:
      labels:
        app: mychart
        release: kissed-peacock
    spec:
      containers:
        - name: mychart
          image: "nginx:stable"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {}

code/tmp/helm_chart_own