Charts

In the previous chapters when dealing with Kubernetes, we learned how to create and manage a bunch of different Kubernetes components and applications by using yaml files. As you can imagine handling multiple yaml files for every single application can get quite cumbersome once you have more than just two or three deployments in parallel. It’s a lot of steps you have to take to get everything up and running, and handling versioning between the different moving parts can be difficult at times.

To make it short: Similar to Docker where we packaged all our dependencies into one Dockerfile, it would be convenient to be able to package all the different components of a kubernetes application (deployment.yaml, service.yaml, …) into one configuration and deploy that configuration as a single step. This is where helm steps in.

Exercise - The components of a helm chart

An empty helm chart has already been created for the postgresdb. You can go ahead and list it’s contents with the tree command.

tree postgresdb/helmchart/

This should display output similar to this:

helmchart
├── charts
├── Chart.yaml
├── templates
└── values.yaml

2 directories, 2 files

As you can see, a minimal helm chart consist of four parts:

  • The Chart.yaml contains metadata like the name of the chart or the version of the application.
  • The values.yaml file is used to store parameters which can later be injected into the template files.
  • The templates directory contains all of your kubernetes .yaml files like deployment and service definitions.
  • The charts directory contains all of the dependencies of your chart.
Info

Don’t worry about the empty templates/ and charts/ directories for now, we are going to put files in there soon!

Exercise - Taking a look at the Chart.yaml file

Let’s start by looking at the Chart.yaml file that is already there.

cat postgresdb/helmchart/Chart.yaml

apiVersion: v1
appVersion: "1.0"
name: postgresdb
description: postgresdb
version: 0.1.0

As you can see there is not much going on in this file. We declare the version of the chart and the application and we give the chart a name and a description.

Exercise - Add templates to our chart

To make the chart do anything we have to provide it with templates. When we finally deploy the chart, helm will look into the templates/ directory and deploy every kubernetes resource definition it finds.

cp postgres.yaml postgresdb/helmchart/templates/

cp postgres-service.yaml postgresdb/helmchart/templates/

Warning

You may still have an instance of a postgres deployment running from previous exercises. To avoid name conflicts please change all postgresdb values of name and app in postgresdb/helmchart/templates/postgres.yaml and postgresdb/helmchart/templates/postgres-service.yaml to helm-postgresdb.

Your postgresdb/helmchart/ directory should look like this now:

postgresdb/helmchart/
├── charts
├── Chart.yaml
├── templates
│   └── postgres-service.yaml
│   └── postgres.yaml
└── values.yaml

2 directories, 4 files

And that’s it, in the next step we can look at deploying the newly created chart!

Exercise - Deploying our first helm chart

In the previous step we created a minimal helm chart with two templates, the postgresdb deployment and the postgresdb service. To install this chart on a kubernetes cluster all we have to do is run the helm install command:

helm install postgres ./postgresdb/helmchart/

Output

You should see console output similar to this:

NAME: postgres
LAST DEPLOYED: Fri Dec  1 13:31:25 2023
NAMESPACE: <your_namespace>
STATUS: deployed
REVISION: 1
TEST SUITE: None

As you can see we successfully deployed a helm chart with the name postgres.

Exercise - Listing helm releases

What we have just created is called a release. A release is just one of many possible deployed instances of a helm chart. We can list all releases by running helm list which in our case should produce output like this:

NAME            NAMESPACE           REVISION        UPDATED                                 STATUS          CHART                   APP VERSION
postgres        <your_namespace>    1               2023-12-01 13:31:25.314616107 +0100 CET deployed        postgresdb-0.1.0        1.0

Exercise - Verifying the release

To verify that the release was installed successfully we can run kubectl get svc,deploy,po and watch helm deploy our database. It should list the following resources:

NAME                      TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)          AGE
service/helm-postgresdb   ClusterIP      10.0.175.71    <none>          5432/TCP         71s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/helm-postgresdb   1/1     1            1           71s

NAME                                   READY   STATUS    RESTARTS      AGE
pod/helm-postgresdb-5446675fd6-tffm7   1/1     Running   0             71s

Alternatively you can use helm status <release name> to show the status of a given release.

Running helm status postgres should render output similar to this:

NAME: postgres
LAST DEPLOYED: Fri Dec  1 13:31:25 2023
NAMESPACE: <your_namespace>
STATUS: deployed
REVISION: 1
TEST SUITE: None

Exercise - Postgres cleanup

Similar to helm install we can run helm uninstall <release name> to uninstall a release. Please go ahead and uninstall our postgresdb release!

Solution
release "postgres" uninstalled

Exercise - Helm repositories

We already learned about the concept of repositories in the Docker section where we used repositories to store our images and make them accessible for the public. Helm uses the same concept to manage charts and allows us to use

helm install

to install a chart from a public repository.

For reference, the CNCF is building a web-based application that enables finding, installing, and publishing packages and configurations for CNCF projects, also including Helm charts. It is called Artifact Hub .

To install a helm chart from a remote source we have to take a few steps:

  1. Add the helm repository with helm repo add <repository url>
  2. Fetch updates from the remote repositories with helm repo update
  3. Install the chart with helm install <repository/chart>

Please run the following commands to install a simple WordPress deployment from its public repository:

  1. helm repo add bitnami https://charts.bitnami.com/bitnami

    Output
    "bitnami" has been added to your repositories
  2. helm repo update

    Output
    Hang tight while we grab the latest from your chart repositories...
    ...Successfully got an update from the "bitnami" chart repository
    Update Complete. ⎈ Happy Helming!⎈
  3. helm search repo wordpress

    Output
    NAME                    CHART VERSION   APP VERSION     DESCRIPTION
    bitnami/wordpress       23.0.9          6.6.0           WordPress is the world's most popular blogging ...
    bitnami/wordpress-intel 2.1.31          6.1.1           DEPRECATED WordPress for Intel is the most popu...
  4. helm search repo --versions bitnami/wordpress

    Output
    ... a long list of possible versions ...
  5. helm install wordpress bitnami/wordpress --version 22.3.1

    Output
    NAME: wordpress
    LAST DEPLOYED: Mon Jul 22 14:05:22 2024
    NAMESPACE: <your_namespace>
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    CHART NAME: wordpress
    CHART VERSION: 22.3.1
    APP VERSION: 6.5.3
    
    ** Please be patient while the chart is being deployed **
    
    Your WordPress site can be accessed through the following DNS name from within your cluster:
    
        wordpress.<your_namespace>.svc.cluster.local (port 80)
    
    To access your WordPress site from outside the cluster follow the steps below:
    
    1. Get the WordPress URL by running these commands:
    
      NOTE: It may take a few minutes for the LoadBalancer IP to be available.
            Watch the status with: 'kubectl get svc --namespace <your_namespace> -w wordpress'
    
      export SERVICE_IP=$(kubectl get svc --namespace <your_namespace> wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
      echo "WordPress URL: http://$SERVICE_IP/"
      echo "WordPress Admin URL: http://$SERVICE_IP/admin"
    
    2. Open a browser and access WordPress using the obtained URL.
    
    3. Login with the following credentials below to see your blog:
    
      echo Username: user
      echo Password: $(kubectl get secret --namespace <your_namespace> wordpress -o jsonpath="{.data.wordpress-password}" | base64 -d)

Why this specific version? Well, this version was last tested by us, and we don’t want to just blindly install latest, do we?

Again, you can verify the proper creation of the deployment by running kubectl get svc,deploy,po, which among other things should list the following:

Output
NAME                        TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
service/wordpress           LoadBalancer   10.0.69.199    51.138.102.51   80:31746/TCP,443:32731/TCP   2m11s
service/wordpress-mariadb   ClusterIP      10.0.141.83    <none>          3306/TCP                     2m11s

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/wordpress     1/1     1            1           2m10s

NAME                              READY   STATUS    RESTARTS      AGE
pod/wordpress-5f54dc8bd6-ctsp2    1/1     Running   1 (39s ago)   2m10s
pod/wordpress-mariadb-0           1/1     Running   0             2m10s

You can now access your WordPress site in your browser or by running

curl --silent http://<your_wordpress_LoadBalancer_IP>/ | grep "<title>"

using the IP declared by the service/wordpress. The curl statement should output

<title>User&#039;s Blog!</title>

Exercise - Wordpress cleanup

Congratulations, you just deployed a helm chart from a public chart repository! In the next chapter we are going to look at configuring charts via command line parameters and custom values files. For now you can go ahead and uninstall the wordpress release again.

helm uninstall wordpress

Watch via kubectl get svc,deploy,po how the resources will get deleted. Does anything remain?

Solution

Well, yes. Per default the wordpress chart will persist the database storage, cf. kubectl get pvc. This normally makes sense, but here in our context it will prevent a clean reinstallation of this chart, so now let’s ensure the storage gets dropped as well:

kubectl delete pvc data-wordpress-mariadb-0