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.
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.
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
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/
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>
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.
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
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
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
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 can be overwritten when we run Helm commands. For instance:
helm install --set image.tag='latest' .
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 -}}
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
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" . }}
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.
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
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