Helm Charts Basics - q-uest/notes-doc-k8s-docker-jenkins-all-else GitHub Wiki
The 3 important concepts of Helm:
- The chart is a bundle of information necessary to create an instance of a Kubernetes application.
- The config contains configuration information that can be merged into a packaged chart to create a releasable object.
- A release is a running instance of a chart, combined with a specific config.
- Install Helm
wget https://get.helm.sh/helm-v3.8.0-linux-amd64.tar.gz
gunzip helm-v3.8.0-linux-amd64.tar.gz
tar -xvf helm-v3.8.0-linux-amd64.tar
sudo mv ./linux-amd64/helm /usr/local/bin/helm
====
- Create Helm Chart for the application:
Command Syntax:
helm create <Name>
This command creates a chart directory along with the common files and directories used in a chart.
Example:
helm create nginx
This generates templates in the current working directory under a directory name, "nginx"
- Install/Rollout Release to K8s cluster:
helm install <RELEASE_NAME> <HELM-CHART-PATH>
helm install frstrel ./nginx
This renders the values, generates manifest files (if none is there in the given path) and executes the same onto the cluster.
- List the Helm Releases in the current Namespace(qa):
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
frstrel qa 1 2022-02-12 22:17:08.2694875 +0530 IST deployed nginx-0.1.0 1.16.0
- List all helm releases in ALL the Namespaces:
helm list -A
- Check the changes rolled-out on to the cluster
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/frstrel-nginx-78d694b884-2cfbf 1/1 Running 0 85s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/frstrel-nginx ClusterIP 10.111.40.33 <none> 8080/TCP 85s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/frstrel-nginx 1/1 1 1 85s
NAME DESIRED CURRENT READY AGE
replicaset.apps/frstrel-nginx-78d694b884 1 1 1 85s
Note: The Release_Name & the chart name (given in Charts.yaml) are prefixed with the objects created by the Helm Chart.
helm install v1 --set image.repository=10.182.0.16:8082/appointme-admin-api --set image.tag=89-DEV ./appointme/
In the above, passing the "image name" and the "tag name" which will over-ride what is provided in values.yaml. Here the release name is, "v1". The CHART and APP VERSION (getting to see in the output of the "helm list") are derived from the Chart.yaml.
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
v1 default 1 2022-07-27 08:17:37.974960453 +0000 UTC deployed charname-0.1.0 1.16.0
kubectl get pod
NAME READY STATUS RESTARTS AGE
v1-charname-9df648d74-7tq4k 1/1 Running 0 88s
Install with "--wait" option:
If "--wait" is set, it will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout value provided. Without "--wait" option in place, it will skip the check of ensuring the release objects are successfully created and returns back to command prompt immediately after executing the command.
In case of any errors/failures, it returns the below message:
Error: INSTALLATION FAILED: timed out waiting for the condition
It shows the STATUS as "failed" when the deployment was unsuccessful.
helm install v3 --set image.repository=10.182.0.16:8082/appointme-admin-api --set image.tag=90-DEV-QA ./appointme/ --wait
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
v6 default 1 2022-07-27 11:31:17.025906191 +0000 UTC failed charname-0.1.0 1.16.0
The above pod/deployment was not getting through because of the failures with Readiness probe/Liveness probes. The error messages logged are as below:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Unhealthy 54m (x192 over 115m) kubelet Readiness probe failed: Get "http://10.112.1.9:80/": dial tcp 10.112.1.9:80: connect: connection refused
Warning BackOff 9m56s (x347 over 109m) kubelet Back-off restarting failed container
Warning Unhealthy 4m55s (x107 over 114m) kubelet Liveness probe failed: Get "http://10.112.1.9:80/": dial tcp 10.112.1.9:80: connect: connection refused
Upgrade the v1 Release (Revision 2):
helm upgrade v1 --set image.repository=10.182.0.16:8082/appointme-admin-api --set image.tag=92-DEV ./appointme/```
In the above new revision's (of the release - V1) image has been changed (from 91-DEV to 92-DEV as given in "image.tag" above)
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
v1 default 2 2022-07-27 08:20:05.083021034 +0000 UTC deployed charname-0.1.0 1.16.0
When the above release upgrade performed, the pods of the first revision get deleted and new pods of revision#2 get created.
kubectl get pod
NAME READY STATUS RESTARTS AGE
v1-charname-5c5d4b8544-zjtxl 1/1 Running 0 88s
helm install v2 --set image.repository=10.182.0.16:8082/appointme-admin-api --set image.tag=91-DEV ./appointme/
List Helm Release:
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
v1 default 2 2022-07-27 08:20:05.083021034 +0000 UTC deployed charname-0.1.0 1.16.0
v2 default 1 2022-07-27 08:23:02.548161022 +0000 UTC deployed charname-0.1.0 1.16.0
List Pods:
kubectl get pod
NAME READY STATUS RESTARTS AGE
v1-charname-5c5d4b8544-zjtxl 1/1 Running 0 54m
v2-charname-65ccbd6bc6-kws64 1/1 Running 0 51m
Now, both the releases are running in parallel on the cluster.
For the purpose of this testing, we going to change the Service's Port# (of the second release) of the ClusterIP from 6060 to 7070.
This is how the services look currently before the planned change:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.116.0.1 <none> 443/TCP 3h46m
v1-charname ClusterIP 10.116.11.172 <none> 6060/TCP 8m25s
v2-charname ClusterIP 10.116.2.141 <none> 6060/TCP 3m
Changed service.port to 7070 in "values.yaml". Let's upgrade the release (v2) and see how it looks like,
helm upgrade v2 ./appointme/
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
v1 default 2 2022-07-27 08:20:05.083021034 +0000 UTC deployed charname-0.1.0 1.16.0
v2 default 2 2022-07-27 08:29:00.299064941 +0000 UTC deployed charname-0.1.0 1.16.0
It does not do anything to Pods, but the Service v2-charname's (of v2 release) changed from 6060 to 7070 as below.
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.116.0.1 <none> 443/TCP 4h32m
v1-charname ClusterIP 10.116.11.172 <none> 6060/TCP 53m
v2-charname ClusterIP 10.116.2.141 <none> 7070/TCP 48m
Helm Release History:
Release -v1:
helm history v1
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Wed Jul 27 08:17:37 2022 superseded charname-0.1.0 1.16.0 Install complete
2 Wed Jul 27 08:20:05 2022 deployed charname-0.1.0 1.16.0 Upgrade complete```
Release -v2:
helm history v2
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Wed Jul 27 08:23:02 2022 superseded charname-0.1.0 1.16.0 Install complete
2 Wed Jul 27 08:29:00 2022 deployed charname-0.1.0 1.16.0 Upgrade complete
Usage: helm rollback [REVISION] [flags]
helm rollback v2 1
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
v1 default 2 2022-07-27 08:20:05.083021034 +0000 UTC deployed charname-0.1.0 1.16.0
v2 default 3 2022-07-27 09:21:13.345281686 +0000 UTC deployed charname-0.1.0 1.16.0
helm history v2
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Wed Jul 27 08:23:02 2022 superseded charname-0.1.0 1.16.0 Install complete
2 Wed Jul 27 08:29:00 2022 superseded charname-0.1.0 1.16.0 Upgrade complete
3 Wed Jul 27 09:21:13 2022 deployed charname-0.1.0 1.16.0 Rollback to 1
The second release has got 3 revisions so far. Read the DESCRIPTION column to see what happened.
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.116.0.1 <none> 443/TCP 4h44m
v1-charname ClusterIP 10.116.11.172 <none> 6060/TCP 66m
v2-charname ClusterIP 10.116.2.141 <none> 6060/TCP 60m
The Port# is changed back to 6060 (as it was in Revision#1)
What Deployment Strategy that Helm will follow while upgrading a release? Rolling Update or Recreate?
It uses the strategy defined in the deployment manifest.
Technically the update strategy defined in the deployment manifest is applied every time the PodSpec changes, no matter whether it changes through helm or kubectl or something else. And only if the PodSpec changes.
- Generating templates
Usage: helm template [NAME] [CHART] [flags]
helm template <release_name> <helm-chart-path>
helm template newrel ./nginx
The objects will be named with the concatenation of the given (release) Name and the Chart name specified in the "Chart.yaml" in the given path (.nginx above).
**This renders the templates **
- Example 2 for Rollbacks
helm install secondrel ./nginx
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/dest-nginx 1/1 Running 1 9h
pod/frstrel-nginx-78d694b884-2cfbf 1/1 Running 1 8h
pod/secondrel-nginx-5ffc7cddc8-nmvn4 1/1 Running 0 27s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/frstrel-nginx ClusterIP 10.111.40.33 <none> 8080/TCP 8h
service/secondrel-nginx ClusterIP 10.96.0.164 <none> 8080/TCP 28s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/frstrel-nginx 1/1 1 1 8h
deployment.apps/secondrel-nginx 1/1 1 1 28s
NAME DESIRED CURRENT READY AGE
replicaset.apps/frstrel-nginx-78d694b884 1 1 1 8h
replicaset.apps/secondrel-nginx-5ffc7cddc8 1 1 1 28s
There are currently 2 releases installed.
For this test, edit "values.yaml" in the chart directory to change the container's port# now from 8080 to 90.
helm upgrade secondrel ./nginx
This installs a new revision of "secondrel".
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/dest-nginx 1/1 Running 1 9h
pod/frstrel-nginx-78d694b884-2cfbf 1/1 Running 1 8h
pod/secondrel-nginx-5ffc7cddc8-nmvn4 1/1 Running 0 9m11s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/frstrel-nginx ClusterIP 10.111.40.33 <none> 8080/TCP 8h
service/secondrel-nginx ClusterIP 10.96.0.164 <none> 90/TCP 9m11s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/frstrel-nginx 1/1 1 1 8h
deployment.apps/secondrel-nginx 1/1 1 1 9m11s
NAME DESIRED CURRENT READY AGE
replicaset.apps/frstrel-nginx-78d694b884 1 1 1 8h
replicaset.apps/secondrel-nginx-5ffc7cddc8 1 1
This command rolls-back not only the deployments, but also the application level changes done (like changing the port#)
** Made another revision/change to the service's port, this time, changing the port# from 90 to 9090 in "values.yaml"**
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
frstrel qa 1 2022-02-12 22:17:08.2694875 +0530 IST deployed nginx-0.1.01.16.0
secondrel qa 3 2022-02-13 07:14:34.0461201 +0530 IST deployed nginx-0.2.01.17.1
Rollback to the first Revision
helm rollback <RELEASE_NAME> <REVISION#>
helm rollback secondrel 1
Check the helm list
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
frstrel qa 1 2022-02-12 22:17:08.2694875 +0530 IST deployed nginx-0.1.01.16.0
secondrel qa 4 2022-02-13 07:18:01.5227246 +0530 IST deployed nginx-0.2.01.17.0
Check to see whether the service port# is changed to how it was with revision#1, when it was rolled out:
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frstrel-nginx ClusterIP 10.111.40.33 <none> 8080/TCP 9h
secondrel-nginx ClusterIP 10.96.0.164 <none> 8080/TCP 17m
- Checking revision history or the current status of a particular Release
helm history secondrel
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Sun Feb 13 07:00:28 2022 superseded nginx-0.2.0 1.17.0 Install complete
2 Sun Feb 13 07:04:12 2022 superseded nginx-0.2.0 1.17.0 Upgrade complete
3 Sun Feb 13 07:14:34 2022 superseded nginx-0.2.0 1.17.1 Upgrade complete
4 Sun Feb 13 07:18:01 2022 deployed nginx-0.2.0 1.17.0 Rollback to 1
- Uninstall/Delete Releases
helm uninstall/del <RELEASE_NAME>:
It removes all of the resources associated with the last release of the chart as well as the release history, freeing it up for future use.
helm del frstrel
- Command to Upgrade a Release, only if it is there already, else Install it:
helm upgrade --install firsthelm ./nginx
This command is very helpful to use from your ci/cd pipelines....
- Add Jenkins to Helm Charts Repo:
helm repo add jenkinsci https://charts.jenkins.io
helm repo list
helm repo update
- Get the Chart Name by Searching the Repo for Jenkins which only could be used to pass on to the pull command to Download scripts:
helm search repo jenkinsci
helm pull jenkinsci/jenkins