Helm Charts Basics - q-uest/notes-doc-k8s-docker-jenkins-all-else GitHub Wiki

Helm Charts

The 3 important concepts of Helm:

  1. The chart is a bundle of information necessary to create an instance of a Kubernetes application.
  2. The config contains configuration information that can be merged into a packaged chart to create a releasable object.
  3. 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.


Install/Upgrade a Helm Release

Install first Revision of a release:

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

Install New Release

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.


Rollback

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

Rollback the 2nd revision of the release (called, v2) to its Revision#1.

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
⚠️ **GitHub.com Fallback** ⚠️