Building your own Helm Charts
If you have not installed helm yet, do so by using
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
helm
Part I - Generating a Chart with One Service
Create a namespace and switch to it
kubectl create namespace dev
kubectl config set-context --current --namespace=dev
kubectl config get-contexts
Generate a helm chart scaffold and change into the directory created to create a copy of values.yaml
cd ~
helm create instavote
cd instavote/
cp values.yaml values.dev.yaml
Edit values.dev.yaml
to update replicaCount, image and tag as
replicaCount: 4
image:
repository: schoolofdevops/vote
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "v5"
Update service type to Node Port
service:
type: NodePort
port: 80
nodePort: 30300
Also update the service.yaml
template with the additional property for nodePort
defined as ,
File : service.yaml
apiVersion: v1
kind: Service
metadata:
name: vote
labels:
{{- include "instavote.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
nodePort: {{ .Values.service.nodePort }}
selector:
{{- include "instavote.selectorLabels" . | nindent 4 }}
Install this chart with helm to deploy the vote
service as:
helm install instavote -n dev --values=values.dev.yaml . --dry-run
helm install instavote -n dev --values=values.dev.yaml .
Validate with
helm list -A
kubectl get all
Part II - Adding support for More Microservices
Create copy of the templates so that you could add support for one more service e.g. redis
cd templates/
mkdir vote redis
mv deployment.yaml hpa.yaml ingress.yaml service.yaml vote/
cp vote/*.yaml redis/
You will start editing the templates so that template variables such as Values.replicaCount
will be replaced with Values.vote.replicaCount
. Thats the theme you will have to follow from here on.
e.g. this is the exisinng code
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
which should be changes to
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.vote.replicaCount }}
{{- end }}
To make it easier, you could use text replacement feature of sed
cd templates/vote/
sed -i 's/Values./Values.vote./g' deployment.yaml
sed -i 's/Values./Values.vote./g' service.yaml
and then
cd templates/redis/
sed -i 's/Values./Values.redis./g' deployment.yaml
sed -i 's/Values./Values.redis./g' service.yaml
You will also need to change a few things in the deployments and services including,
- change the name in the metadata field for the deplyoments and services for both apps
- remove nodePort configuration from service spec of redis
- update the
spec.template.spec.labels
as well asspec.selectors.labelSelectors
with application specific labels for both apps - update the
spec.selectors
and add the same label in the services as well
e.g.
update
templates/vote/deployment.yaml
templates/vote/service.yaml
from
metadata:
name: {{ include "instavote.fullname" . }}
to
metadata:
name: vote
And similarly in the following files
templates/redis/deployment.yaml
templates/redis/service.yaml
from
metadata:
name: {{ include "instavote.fullname" . }}
to
metadata:
name: redis
Also change the selector in templates/redis/deployment.yaml
along with template labels as,
selector:
matchLabels:
{{- include "instavote.selectorLabels" . | nindent 6 }}
app: redis
template:
metadata:
{{- with .Values.redis.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "instavote.labels" . | nindent 8 }}
{{- with .Values.redis.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
app: redis
and selector spec in templates/redis/service.yaml
as,
spec:
type: {{ .Values.redis.service.type }}
ports:
- port: {{ .Values.redis.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "instavote.selectorLabels" . | nindent 4 }}
app: redis
Now update instavote/values.yaml
to support multiple services
- add
vote
as top level key - indent all properties so that those become sub properties of key added above i.e. vote
- copy over and create blocks for redis
Use this file as a reference values.yaml
Now go ahead and deploy by
- Creating your own copy of values.yaml
- Providing values specific to those services
You could download this file with sample values values.dev.yaml using the following command :
wget -c https://gist.githubusercontent.com/initcron/67e104f3a2949f20c2da06e19c854faa/raw/90c7b0c330f133efae43ea71efb1beba314ea451/values.dev.yaml
And apply
helm uninstall instavote
helm install instavote -n dev --values=values.dev.yaml .
helm list -A
kubectl get all
Validate that vote and redis are running with the values that you provided.
Part III : Overriding Values, Rollbacks
Lets learn how to override values from the command line. To do so, lets add one property
File : templates/vote/deployment.yaml
containers:
- name: vote
env:
- name: OPTION_A
value: {{ .Values.vote.options.A }}
- name: OPTION_B
value: {{ .Values.vote.options.B }}
This will read from values file and set those as environmnt variables. Lets set the default values.
File: values.dev.yaml
vote:
replicaCount: 2
options:
A: MacOS
B: Windows
now upgrade the release as
helm upgrade instavote -n dev --values=values.dev.yaml .
Check the application to see the default values being visible.
You could override the values from the command line as
helm upgrade instavote --values values.dev.yaml --set vote.options.A=Green --set vote.options.B=Yellow .
check the web app now
try one more time
helm upgrade instavote --values values.dev.yaml --set vote.options.A=Orange --set vote.options.B=Blue .
you should see the values change every time.
Check the release now
helm list -A
[sample output]
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
instavote dev 7 2024-05-14 03:31:34.717912894 +0000 UTC deployed instavote-0.1.0 1.16.0
try rolling back a version
e.g.
helm rollback instavote
you could also go back to a specific version using the revision number as
helm rollback instavote xx
where replace xx
with the revision number you wish to roll back to.
Exercise
Now that you have deployed vote and redis, go ahead and add the code to deploy worker, db and result as well.