Join us
@squadcast ăť Mar 05,2022 ăť 11 min read ăť 877 views ăť Originally posted on www.squadcast.com
Deploying applications to Kubernetes can be complex as you may be required to create multiple interdependent resources. This blog explains how Helm can help software professionals to package, configure and deploy applications onto Kubernetes.
Helm is an open source package manager for Kubernetes. Most software development processes need a package manager which can simplify installation and maintenance. However, with increase in the number of components in an infrastructure, managing clusters in Kubernetes can become very complicated. This is where Helm comes into the picture as it wraps up all the components in a single package. It also helps automate software installation, configure software deployments and fetch relevant data. Let's take an example of an app that needs:
Now, every object of the application requires a separate 'yaml' file. To create these objects, we need to run the 'kubectl' command. Complications may arise in situations where a bug is introduced or we need to modify the value of secrets. In these situations, we need to rollback, which requires revisiting every file individually to keep them in a particular order.
This problem can be solved by creating one huge file and defining all the object resources in it. By doing this, we can avoid frequent rollbacks. But think in terms of the need to modify values in a large file. For example, what if we need to modify the persistent volume size from 10GB to 100GB?. Given the size of the file, we would need to make sure we are making changes in the right place, and also not introduce any new bugs.
Let's take the example of rpm. An application consists of configuration files, binary files, etc. Rather than placing all these files in an individual directory of our system, we can run one rpm command, which will take care of installing all configuration and binary files in an appropriate directory. Helm takes a similar approach to solve this problem in the previous scenario.
It wraps together all the necessary components (deployments, services, secrets, persistent volume) in a single package. Whenever we need to install these resources, we just need to trigger the requirement in Helm to install a package, and it will install all the corresponding resources. Also, we only need to modify a single file (values.yaml) to update all the resources that are packaged using Helm.
Prerequisites
Installation
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
Downloading https://get.helm.sh/helm-v3.7.2-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
helm version
version.BuildInfo{Version:"v3.7.2", GitCommit:"663a896f4a815053445eec4153677ddc24a0a361", GitTreeState:"clean", GoVersion:"go1.16.10"}
To install Helm on all the supported platforms, check the following documentation.
Helm uses a command-line utility on your local system to perform Helm actions like install, upgrade, or rollback charts. Let us first understand what is a chart? Helm bundles all your related manifests into a chart, such as deployments, services, and pods. This chart contains all of Helm's instructions to create a Kubernetes object in your cluster.
When you install a chart, a release is created. Within each release, you can have multiple revisions. This chart is then passed to Helm, and it connects to Kubernetes API using kubeconfig (~/.kube/config) to create Kubernetes objects. Now, the next question is where does Helm store the metadata information (such as the installed release, the chart used, revision state), and the answer to that question is inside your Kubernetes cluster in the form of a secret.
kubectl get secret
sh.helm.release.v1.mysql-db.v1 helm.sh/release.v1 1 13s
The way we can find docker images in a DockerHub, we can also find the Helm chart in a repository called ArtifactHUB.
> helm repo add bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories
> helm repo list
NAME URL
bitnami https://charts.bitnami.com/bitnami
helm install my-release bitnami/mysql
NAME: my-release
LAST DEPLOYED: Tue Dec 14 08:05:20 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: mysql
CHART VERSION: 8.8.16
APP VERSION: 8.0.27
** Please be patient while the chart is being deployed **
Tip:
Watch the deployment status using the command: kubectl get pods -w --namespace default
Services:
echo Primary: my-release-mysql.default.svc.cluster.local:3306
Execute the following to get the administrator credentials:
echo Username: root
MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default my-release-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode)
To connect to your database:
1. Run a pod that you can use as a client:
kubectl run my-release-mysql-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mysql:8.0.27-debian-10-r35 --namespace default --command -- bash
NOTE: After you have installed the chart, you will also get some useful information like how to use this chart.
2. To connect to primary service (read/write):
mysql -h my-release-mysql.default.svc.cluster.local -uroot -p"$MYSQL_ROOT_PASSWORD"
To upgrade this helm chart:
1. Obtain the password as described on the 'Administrator credentials' section and set the 'root.password' parameter as shown below:
ROOT_PASSWORD=$(kubectl get secret --namespace default my-release-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode)
helm upgrade --namespace default my-release bitnami/mysql --set auth.rootPassword=$ROOT_PASSWORD
> helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-release default 1 2021-12-14 08:05:20.931154 -0800 PST deployed mysql-8.8.16 8.0.27
> helm search hub mysql
URL CHART VERSION APP VERSION DESCRIPTION
https://artifacthub.io/packages/helm/bitnami/mysql 8.8.16 8.0.27 Chart to create a Highly available MySQL cluster
> helm search repo mysql
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/mysql 8.8.16 8.0.27 Chart to create a Highly available MySQL cluster
helm uninstall my-release
release "my-release" uninstalled
helm repo remove bitnami
"bitnami" has been removed from your repositories
Previously, we installed the chart using the default value. But that may not be your requirement all the time. Hence, you may also pull the chart and then modify 'values.yaml' file according to your requirements.
helm pull bitnami/mysql
ls -l mysql-8.8.16.tgz
helm pull --untar bitnami/mysql
cat mysql/values.yaml
rootPassword: "abc123"
helm install mydb ./mysql
helm install set rootPassword="abc123" mydb bitnami/mysql
cat mysql/myvalue.yaml
rootPassword: "abc123"
helm install --value mysql/myvalue.yaml mydb bitnami/mysql
So far you have learned how to install an existing chart from ArtifactHUB and modify the values in those charts. In the next section, we will learn how to build our chart from scratch.
In previous steps you have installed or modified a chart created by someone else, which is fine in most scenarios. But in cases where you have a custom application, or you need to customize your chart, you will be required to create your own custom chart.
The easiest way to get started with charts is by using âhelm createâ command. This will create a chart structure for you.
> helm create mydemochart
Creating mydemochart
> tree mydemochart
mydemochart
âââ Chart.yaml
âââ charts
âââ templates
â âââ NOTES.txt
â âââ _helpers.tpl
â âââ deployment.yaml
â âââ hpa.yaml
â âââ ingress.yaml
â âââ service.yaml
â âââ serviceaccount.yaml
â âââ tests
â âââ test-connection.yaml
âââ values.yaml
apiVersion: When Helm3 was introduced, it came as a field 'apiVersion' to differentiate between Helm v2 vs. Helm v3 chart. For example, Helm v3 has field dependencies not present in Helm v2. So the general rule now is, all the charts built for Helm2 have the field set to v1 and for Helm3 it is v2.
appVersion: This is the version of the application that's inside your chart. For example, if you are installing MySQL, it is the version of the MySQL database. This field is for informational purposes only.
version: The version field holds the value of a chart's version which is independent of the app's version that you have deployed. This is independent of the version of the app you have deployed. This field helps you to keep track of the changes in the chart.
name: This field represents the name of the chart.
description: This field holds the description of your chart.
type: There are two types of charts: applications (default) and library. The application chart is used to build applications, whereas the library chart is used to provide utilities that help build charts.
apiVersion: v2
name: mydemochart
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.16.0"
templates: Itâs the most critical directory and contains Kubernetes resource definitions, for example; deployments, services, etc.
> rm -rf mydemochart/templates
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml >> mydemochart/templates/deployments.yaml
kubectl expose deploy nginx --port 80 --type NodePort --dry-run=client -o yaml >> mydemochart/templates/service.yam
Error from server (NotFound): deployments.apps "nginx" not found
NOTE: We are trying to expose the deployment which doesnât exist. Letâs create it temporarily as we want to create it via Helm.
> kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
> kubectl expose deploy nginx --port 80 --type NodePort --dry-run=client -o yaml >> mydemochart/templates/service.yaml
> kubectl delete deploy nginx
deployment.apps "nginx" deleted
This is all we need at this stage. Our Helm chart is ready to go. But before that, let's verify the files we created in the earlier steps, for example, 'deployments.yaml'. As you can see in deployments, all the values are static, for example, name: nginx, replicas: 1, or image, name: nginx.
> cat mydemochart/templates/deployments.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
Name: {{ .Release.Name }}-nginx
helm install my-demo-chart ./mydemochart
> cat mydemochart/values.yaml
replicaCount: 1
image:
repository: nginx
replicas: {{ .Values.replicaCount }}
Image: {{ .Values.image.repository }}
By now you must be eager to run your first Helm chart but before doing that, check if your chart is working as expected. There are three ways of doing that:
> helm lint ./mydemochart
==> Linting ./mydemochart
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
> helm template ./mydemochart
---
# Source: mydemochart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: NodePort
status:
loadBalancer: {}
---
# Source: mydemochart/templates/deployments.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
> helm install my-demo-chart ./mydemochart --dry-run
NAME: my-demo-chart
LAST DEPLOYED: Wed Dec 15 11:20:52 2021
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mydemochart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: NodePort
status:
loadBalancer: {}
---
# Source: mydemochart/templates/deployments.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
helm install my-demo-chart ./mydemochart
> helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-demo-chart default 1 2021-12-15 14:34:07.058598 -0800 PST deployed mydemochart-0.1.0 1.16.0
> helm uninstall my-demo-chart
release "my-demo-chart" uninstalled
Once the chart is ready, we can share it with other team members or even globally, to promote collaboration. Developers on a global scale can help enhance the chart and fix bugs. In the next section, we will learn how to package a chart.
We have our chart ready, but if you want to share it with the rest of the team or the rest of the world, you need to package it.
> helm package ./mydemochart
Successfully packaged chart and saved it to: /Users/plakhera/mydemochart-0.1.0.tgz
> ls -l /Users/plakhera/mydemochart-0.1.0.tgz
-rw-r--r-- 1 plakhera staff 831 Dec 15 14:40 /Users/plakhera/mydemochart-0.1.0.tgz
Now that we have packaged our chart, itâs time to upload it to online repositories like GitHub or a bucket in S3, etc. These are the steps we need to follow:
> mkdir my-demo-chart-repo
> cp mydemochart-0.1.0.tgz my-demo-chart-repo
> helm repo index my-demo-chart-repo --url https://example.com/charts
> cat my-demo-chart-repo/index.yaml
apiVersion: v1
entries:
mydemochart:
- apiVersion: v2
appVersion: 1.16.0
created: "2021-12-15T14:55:52.841062-08:00"
description: A Helm chart for Kubernetes
digest: 2826d2bda666a88321b5de5d652710ace81076c2d9f3d86d17413c111b05fccf
name: mydemochart
type: application
urls:
- https://example.com/charts/mydemochart-0.1.0.tgz
version: 0.1.0
generated: "2021-12-15T14:55:52.840324-08:00"
In this blog, we have learned the basics of Helm and how to create a Helm chart. Helm is a powerful tool, and it greatly simplifies how package management works with Kubernetes.
â
Squadcast is an incident management tool thatâs purpose-built for SRE. Your team can get rid of unwanted alerts, receive relevant notifications, work in collaboration using the virtual incident war rooms, and use automated tools like runbooks to eliminate toil. Start now for Free.
Join other developers and claim your FAUN account now!
Influence
Total Hits
Posts
Only registered users can post comments. Please, login or signup.