Uploading a Helm Chart

Uploading a Helm Chart

In this blog, we will see how Uploading a Helm chart can be done.

Once we’ve packaged our chart and signed it, it’s time to upload all of our hard work online, so that our users can easily install it with a simple command like helm install my-release our-repo/nginx.

Generally, our chart repositories will contain these things:

  1. The packaged chart. In our case, this is the nginx-0.1.0.tgz file we created earlier.
  2. The index file. An index.yaml file, that we’ll soon create, will contain information about the chart repository, the charts it contains, the checksums for our .tgz files, descriptions and so on. This is the file that Helm will read when we add a new repository with a command like helm repo add our-repo https://example.com/ourcompany/charts. We’ll soon take a look at what contents we have here so that we understand it better.
  3. (Optional) The provenance file we generated earlier, in case users want to verify cryptographic signatures so that they can be sure they download the content that was approved by us, and not some potentially malicious content that some attacker could have uploaded to a compromised server.

If you want a quick intro to Helm concepts and features, check out this video.

Generating the Index File

To generate the index file we first need to know where we will upload our charts. In our exercise, we’ll assume we have a web server accessible at https://example.com and we’ll upload the charts at https://example.com/charts.

Grouping Chart Files in a Local Directory

Let’s create a directory where we can group the files that we’ll upload to our online repository.

mkdir nginx-chart-files

We already have our archived chart and our provenance files so let’s copy those to our directory.

cp nginx-0.1.0.tgz nginx-0.1.0.tgz.prov nginx-chart-files/

Finally, we can generate the index file, which is rather easy:

helm repo index nginx-chart-files/ --url https://example.com/charts

We can see the syntax of the command is straightforward. After repo index we point to the directory that contains our archived charts and provenance files, nginx-chart-files/. Finally, we’ve decided we will be uploading our charts to a location accessible at https://example.com/charts so we pass that to the –url parameter.

We now have this structure in our directory:

├── index.yaml
├── nginx-0.1.0.tgz
└── nginx-0.1.0.tgz.prov

Let’s take a look at the mysterious index.yaml file.

[email protected]:~$ cat nginx-chart-files/index.yaml
apiVersion: v1
  - apiVersion: v2
    appVersion: 1.16.0
    created: "2021-07-03T21:59:00.34571153-04:00"
    description: Basic Nginx website for our company
    digest: b22a325b03c8e88b6a6a8d1a8e79f5d0498813855174a983426466b6de5a5f71
    - email: [email protected]
      name: John Smith
    name: nginx
    type: application
    - https://example.com/charts/nginx-0.1.0.tgz
    version: 0.1.0
generated: "2021-07-03T21:59:00.345199016-04:00"

The info we see here is pretty straightforward. As far as the Helm tool is concerned, the urls: section is the most important. This tells it the locations from where it can download charts whenever users want to install something from this repository.

    - https://example.com/charts/nginx-0.1.0.tgz

Uploading Charts

You are free to upload your charts wherever you want. We recommend a web server that you control or a service like Google Cloud Storage (GCS) bucket, Amazon S3 bucket, DigitalOcean Object Storage, and so on. These services are very cost-effective and super-easy to maintain. You could be uploading the files to GitHub Pages but the process is slightly more complicated (although easy if you’re already familiar with how GitHub operates).

In our case, we can quickly simulate that we have a web server somewhere. We’ll just install a simple Nginx web server locally.

sudo apt update && sudo apt install nginx

Next, we’ll add this line to the end of our /etc/hosts file:       example.com. What this does is instruct our local machine to consider that example.com has the IP address of our local machine (127.0.1.* just points back to our own computer/virtual machine).

sudo sh -c "echo '       example.com' >> /etc/hosts"

Great! Our web server is running and will be accessible (from our local machine) at http://example.com.

To keep things simple, we won’t enable HTTPS on our Nginx web server. For our special case, let’s regenerate the index file to point to http:// instead of https://. But remember, in real scenarios, always use https:// if possible. (With most online web services to host your files, you will have HTTPS available). So if you’re using online service with this available, you can skip directly to the part where we are uploading files).

helm repo index nginx-chart-files/ --url http://example.com/charts

Our Nginx web server, by default, makes files stored in /var/www/html available to web visitors. So let’s create the charts directory there so that Helm can later download its content from http://example.com/charts.

Finally, we can “publish” our chart by copying

  1. the chart .tgz archive
  2. the index.yaml file
  3. and the provenance file to that location.
sudo cp nginx-chart-files/* /var/www/html/charts

And that’s it, job done! Once we have these files online, users can start using them in production.

Using Our Newly Created Helm Repository

Let’s assume we’re one of these users. We want to use this cool new Helm repository. Just like we did with the repository from Bitnami, we just add this with a helm repo add command.

helm repo add our-cool-charts http://example.com/charts

We can now see that this was successfully added to Helm’s list of known online repositories.

[email protected]:~$ helm repo list
NAME           	URL                               
bitnami        	https://charts.bitnami.com/bitnami
our-cool-charts	http://example.com/charts

In a real scenario, before we install a chart we want to make sure we have the latest data available about the repositories’ content (in case updated charts have appeared since we last refreshed this data).

helm repo update

And we can install our nginx chart

helm install my-new-release our-cool-charts/nginx

And kubectl get pods shows us that we achieved our mission: installed a Helm chart from the online repository we created from scratch!

[email protected]:~$ kubectl get pods
NAME                                    READY   STATUS    RESTARTS   AGE
my-new-release-nginx-85cb977469-kwh6b   1/1     Running   0          12s

Uploading New Charts

In a real scenario, we’ll keep updating our charts. When we generate a new index file, this will overwrite the old index file and point to our latest chart. This basically means that a helm install command can only install the latest chart we uploaded, as it does not see the older entries.

Sometimes, though, we may want to give our users the option to download older charts if they still need them. So instead of generating a new index file that points to the latest chart, we want to simply add new content to our existing index file. This way, our older entries remain visible/accessible to Helm.

Let’s imagine we updated our chart, corrected some bugs.

cp nginx-chart-files/nginx-0.1.0.tgz nginx-chart-files/nginx-0.1.1.tgz

We now have a new nginx-0.1.1.tgz an imaginary upgrade to our nginx-0.1.0.tgz chart. Remember, in a real scenario, we would have more work to do like also bumping up the version number in Chart.yaml.

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0 <--This should be changed to 0.1.1 in a real scenario

To let our index file know about the newer entries, but also keep a record of the older ones, we use the extra –merge parameter where we specify the path of the index.yaml file that we want to update with the new info.

helm repo index nginx-chart-files/ --url http://example.com/charts --merge nginx-chart-files/index.yaml

Remember to use –url https:// in production instead of the http:// from this example.
At this point, you would upload your new nginx-0.1.1.tgz chart to example.com/charts, upload the new index.yaml file (overwriting the older one in the process) and your users can now download both versions of the chart, whichever they prefer.

Checkout the Helm for the Absolute Beginners course here

Checkout the Complete Kubernetes learning path here