In this lab, you will build your own Helm chart. Helm simplifies the deployment and management of applications on Kubernetes by providing a template engine and a robust release management system. You will create a Helm Chart that includes a Deployment, Service, and Ingress object to deploy and expose your application.
To begin, create a dedicated directory for this lab and switch into it:
cd ~
mkdir helm-charts && cd helm-charts
Creating the Initial Scaffolding #
Let’s create scaffolding for the chart with the following command:
helm create random-facts-app
This will create the structure for your chart and some initial templates. For this lab, we are going to remove all of the templates that were created for us and start from scratch. You can remove them with the following command:
rm -rf random-facts-app/templates/*
rm random-facts-app/values.yaml
In the templates directory, create the first template called deployment.yaml.
# random-facts-app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-deployment
namespace: {{ .Release.Namespace }}
labels:
lab: {{ .Release.Name }}-helm
spec:
selector:
matchLabels:
lab: {{ .Release.Name }}-helm
template:
metadata:
labels:
lab: {{ .Release.Name }}-helm
spec:
containers:
- name: {{ .Release.Name }}
image: {{ .Values.image.repository }}:{{ .Values.image.tag | default "latest" }}
ports:
- containerPort: {{ .Values.service.port }}
serviceAccountName: {{ .Release.Name }}-sa
Here is the break down of the template directives used:
{{ .Release.Name }}: injects the release name into the template{{ .Release.Namespace }}: injects the namespace name into the template{{ .Values.* }}: injects the values specified in thevalues.yamlfile
Now let’s create a ServiceAccount template called serviceaccount.yaml:
# random-facts-app/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Release.Name }}-sa
Next, let’s create a Service template called service.yaml:
# random-facts-app/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-service
namespace: {{ .Release.Namespace }}
labels:
lab: {{ .Release.Name }}-helm
spec:
selector:
lab: {{ .Release.Name }}-helm
ports:
- name: http
port: {{ .Values.service.port }}
protocol: TCP
targetPort: {{ .Values.service.targetPort }}
type: {{ .Values.service.type }}
Next, let’s create a Service template called ingress.yaml:
# random-facts-app/templates/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-ingress
namespace: {{ .Release.Namespace }}
annotations:
cert-manager.io/cluster-issuer: {{ .Values.ingress.clusterIssuer }}
spec:
ingressClassName: {{ .Values.ingress.className }}
rules:
- host: {{ .Values.ingress.hostName }}
http:
paths:
- path: {{ .Values.ingress.path }}
pathType: {{ .Values.ingress.pathType }}
backend:
service:
name: {{ .Release.Name }}-service
port:
number: {{ .Values.service.port }}
tls:
- hosts:
- {{ .Values.ingress.hostName }}
secretName: {{ .Release.Name }}-tls
Default Values File #
With our templates in place, we can build out the default values.yaml. The values object provides access to values passed into the chart. Use the following YAML file as a starting point to build a values.yaml file that will live at random-facts-app/values.yaml.
Note: Ensure that you create a value for all .Values specified in the above templates. You do not need to set default values for .Release.Name or .Release.Namespace.
Hint: Leverage your already created objects from the Understanding Kubernetes Networking and Ingress and Understanding Kubernetes Deployments to feed your default values.
# random-facts-app/values.yaml
ingress:
className: nginx
hostname: random-facts-app.example.com
path: '/'
Once completed, you can test that your Helm chart properly renders with the following command:
helm template --namespace random-facts-app-helm random-facts-app random-facts-app/
Sift through the Kubernetes manifests that are generated and validate that all fields are filled out. You can then deploy your app via your Helm chart with the following command:
helm install --create-namespace \
--namespace random-facts-app-helm \
random-facts-app random-facts-app/
You can now view your Helm install with the following command:
helm status random-facts-app --namespace random-facts-app-helm
Overriding Your Default Values #
In the previous exercise, you defined a default values.yaml in your Helm chart. This provides a convenient way to set defaults for your Helm chart but in most cases, consumers of your Helm chart will need to override these defaults.
Ensure you are at the root of your helm-charts directory and create a new values.yaml beside your Helm chart. In your new values.yaml, override the Ingress hostname to your appropriate domain name (ie. random-facts-app-helm.<YOUR_STUDENT_ID>.<RANDOM_ID>.workshops.acceleratorlabs.ca).
Once done, you can first uninstall your previous Helm deployment with the following command:
helm uninstall random-facts-app --namespace random-facts-app-helm
You can then redeploy your application with the override values:
helm install --create-namespace \
--namespace random-facts-app-helm \
random-facts-app random-facts-app/ \
--values values.yaml
Validate your Helm Chart and deployment with an instructor before proceeding to the next lab.