Exercise
Exercise: Helm¶
In this exercise, you will package the VotingApp application into a Helm Chart.
-
Install the Helm Client
If you do not already have the Helm client installed, you can do so using the following command:
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh
-
Creating a Helm Chart
Use the following command to create a Chart named vote.
helm create vote
By default, it includes the following elements:
- a Chart.yaml file that defines the project metadata
- a template for creating a Deployment that manages a single Pod (based on nginx)
- a template for creating a Service to expose this Pod within the cluster
- a template for creating an Ingress resource to expose the service externally
- a values.yaml file used to substitute placeholders in the templates with dynamic values
- a NOTES.txt file that provides information on creating the release and during updates
You can view its contents using the tree command (install it first with "sudo apt install tree"):
$ tree vote/ vote/ ├── Chart.yaml ├── charts ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── hpa.yaml │ ├── ingress.yaml │ ├── service.yaml │ ├── serviceaccount.yaml │ └── tests │ └── test-connection.yaml └── values.yaml
First, in the templates directory, delete the yaml files, the NOTES.txt file, and the test directory.
Next, copy all the manifests from VotingApp into the templates directory.
Also, delete the contents of the values.yaml file but do not delete the file itself.The vote directory will then have the following contents:
$ tree vote/ vote/ ├── Chart.yaml ├── charts ├── templates │ ├── _helpers.tpl │ ├── cronjob.yaml │ ├── deploy-db.yaml │ ├── deploy-redis.yaml │ ├── deploy-result.yaml │ ├── deploy-resultui.yaml │ ├── deploy-vote.yaml │ ├── deploy-voteui.yaml │ ├── deploy-worker.yaml │ ├── ingress.yaml │ ├── pvc-db.yaml │ ├── pvc-redis.yaml │ ├── secret-db.yaml │ ├── svc-db.yaml │ ├── svc-redis.yaml │ ├── svc-result.yaml │ ├── svc-resultui.yaml │ ├── svc-vote.yaml │ └── svc-voteui.yaml └── values.yaml
-
Deploying the Application
From the vote directory, deploy the application using the following command:
helm upgrade --install vote .
You should see a result similar to the one below:
Release "vote" does not exist. Installing it now. NAME: vote LAST DEPLOYED: Tue Feb 13 10:27:48 2024 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None
Then, check that all the Pods of the VotingApp are in the Running status:
$ kubectl get po NAME READY STATUS RESTARTS AGE worker-56b544777-nt6wf 1/1 Running 0 45s result-ui-5cdd74d999-bpwkj 1/1 Running 0 45s vote-6c847fd45-jqvhr 1/1 Running 0 45s vote-ui-74849dd9b4-gbmbp 1/1 Running 0 45s redis-5c4f4598f5-n8kxf 1/1 Running 0 45s result-854cd4779c-w4jhm 1/1 Running 0 45s db-54d89ccb97-nxz7v 1/1 Running 0 45s seed-28463608-dwgst 0/1 Completed 0 34s
Ensure that the application is accessible at http://vote.votingapp.com / http://result.votingapp.com (or at http://vote.IP_OF_YOUR_VM.nip.io / http://result.IP_OF_YOUR_VM.nip.io if you are using the nip.io approach)
-
Using the Helm templating
- Image Tags
You will ensure that image tags are no longer based on latest (which is actually a very bad practice) but on a value specified in the values.yaml file.
First, add the following content to values.yaml:
registry: voting voteui: tag: v1.0.19 vote: tag: v1.0.13 worker: tag: v1.0.15 result: tag: v1.0.16 resultui: tag: v1.0.15 tools: tag: v1.0.4
Then, modify the specifications of the Deployments voteui, vote, worker, result, and resultui so that the image name is generated from the values of the registry property and the corresponding tag for the microservice.
For example, the specification for the voteui Deployment will be modified as follows:
apiVersion: apps/v1 kind: Deployment metadata: labels: app: vote-ui name: vote-ui spec: replicas: 1 selector: matchLabels: app: vote-ui template: metadata: labels: app: vote-ui spec: containers: - image: {{ .Values.registry }}/vote-ui:{{ .Values.voteui.tag }} name: vote-ui
- Regular Vote Generation
You will now configure the creation of 5 dummy votes every 2 minutes.
Add the following content to the end of the values.yaml file:
# Add dummy votes on a regular basis seed: enabled schedule: "*/2 * * * *" number_of_votes: 5
Then, modify the cronjob.yaml specification as follows:
{{ if .Values.seed }}{{ if eq .Values.seed "enabled" }} apiVersion: batch/v1 kind: CronJob metadata: name: seed spec: schedule: "{{ .Values.schedule }}" jobTemplate: metadata: name: seed spec: template: spec: containers: - image: voting/tools:{{ .Values.tools.tag }} name: seed env: - name: NUMBER_OF_VOTES value: "{{ .Values.number_of_votes }}" imagePullPolicy: Always restartPolicy: OnFailure {{ end }}{{ end }}
This specification uses Helm templating language:
- The cronjob is created only if the seed property exists and is equal to "enabled" in the values file
- The schedule for the cronjob is retrieved from the schedule property in the values file
- The number of votes is defined in the NUMBER_OF_VOTES environment variable, with the value also retrieved from the values file
Update the application using the same command used for creation:
helm upgrade --install vote .
Info
the values.yaml file is used by default
The second revision of the application will then be created:
Release "vote" has been upgraded. Happy Helming! NAME: votingapp LAST DEPLOYED: Tue Feb 13 11:05:21 2024 NAMESPACE: default STATUS: deployed REVISION: 2 TEST SUITE: None
You will also see that the different Pods have been recreated to account for the changes made in their specifications:
$ kubectl get po NAME READY STATUS RESTARTS AGE db-54d89ccb97-mp28m 1/1 Running 0 31m redis-5c4f4598f5-wgw2r 1/1 Running 0 31m seed-28463643-s2kzd 0/1 Completed 0 2m34s seed-28463644-n5b4w 0/1 Completed 0 94s seed-28463645-4kmqc 0/1 Completed 0 34s result-ui-76bdf59f99-qks6w 1/1 Running 0 13s vote-779875ff5b-t7drr 1/1 Running 0 13s vote-ui-695759b448-c7jgw 1/1 Running 0 13s result-66f5856c8b-xp9d6 1/1 Running 0 13s worker-6c5d7ddcf5-hprn7 1/1 Running 0 12s
From the result interface, verify that 5 new votes are being created every 2 minutes.
-
Uninstalling the Application
Use the following command to uninstall the application:
helm uninstall vote
-
Distributing the Application
A Helm Chart can easily be packaged and distributed to an OCI registry like DockerHub.
First, use the following command to log in to Docker Hub (if you don't have a Docker Hub account, you can create one for free in just a few minutes):
echo $DOCKERHUB_PASSWORD | helm registry login registry-1.docker.io -u $DOCKERHUB_USERNAME --password-stdin
Then, create a package of the application (specifying version v0.0.1 for the application):
helm package --version v0.0.1 .
You can then push this package to DockerHub:
helm push vote-v0.0.1.tgz oci://registry-1.docker.io/$DOCKERHUB_USERNAME
The application is now available and ready to be retrieved from Docker Hub.