Devember2021: Helm chart update checker

Hi everyone,

I’m really bad at just installing helm charts and leaving them running in my k8s cluster. I have a lot of deployed charts that are very out of date. I also don’t really know the nitty-gritty of how helm 3 works.

I figured a good way to remedy both of these things was to build something to keep tabs on the charts I have deployed and if there’s a newer version available.

I’m not really sure what this will require. I’ll update this post when I have more concrete plans

I’m still mapping this out, but my hope is to do this without helm itself. I think this would be quick work if I just wrap helm. I want to understand how helm works, and that feels like cheating.

At the end of Devember, at the minimum, I hope to have:

  • A Python script that can:
    • Read a configuration file to know what clusters and namespaces to check, and what helm repos
    • Pull chart deployment information from clusters
    • Read chart repos to find updates
    • Report out of date charts and apps to the console and via a discord webhook
  • A container to package the python script in
  • A helm chart that can install the container along with things it will need; like a service account

I’m not sure how quickly I can achieve this. If it ends up being too easy, I may try to adapt my work into a service hosting a dashboard. use argocd with my script to keep everything up to date.

I plan to track my work here: GitHub - OneMoreByte/chartered

have you considered taking a look at argocd ?

Nope! Haven’t heard of that. On a quick pass it looks pretty cool! Are you suggesting I maybe use that when I find out of date helm charts?

I learned what I wanted to about helm!

I’ve never tried to make a helm chart repo, so I didn’t know how helm interacted with a chart repo. I found out a helm repos are really simple.

A yaml file named index.yaml is downloaded when you add a repo.
Something like:

helm repo add k8s-at-home https://k8s-at-home.com/charts/

would download https://k8s-at-home.com/charts/index.yaml.

This file has all the charts that can be downloaded and looks something like this:

apiVersion: v1
entries:
  adguard-home:
  - apiVersion: v2
    appVersion: v0.106.3
    created: "2021-11-22T12:48:02.341434533Z"
    dependencies:
    - name: common
      repository: https://library-charts.k8s-at-home.com
      version: 4.2.0
    description: DNS proxy as ad-blocker for local network
    digest: fe8ed81e0a0f5083e63aa82c00712fe5e7a6846062ce2ce212924c9063d05452
    home: https://github.com/k8s-at-home/charts/tree/master/charts/stable/adguard-home
    icon: https://avatars3.githubusercontent.com/u/8361145?s=200&v=4?sanitize=true
    keywords:
    - adguard-home
    - adblock
    - dns
    kubeVersion: '>=1.16.0-0'
    maintainers:
    - email: [email protected]
      name: billimek
    name: adguard-home
	  sources:
    - https://github.com/AdguardTeam/AdGuardHome
    urls:
    - https://github.com/k8s-at-home/charts/releases/download/adguard-home-5.1.0/adguard-home-5.1.0.tgz
    version: 5.1.0

Of interest to my script, each entry has a version and appVersion. version is the version of the chart, and appVersion is the tag of the image pulled by the chart. There are multiple chart entries for the same chart (the older versions and current one).

When helm runs upgrade or install, it creates a secret in the namespace it deploys the release to. It has a type of helm.sh/release.v1 and has a predictible name of sh.helm.release.v1.<release name>.v<release revision>.
An example would be sh.helm.release.v1.nextcloud.v8.

The secrets have one value stored in them, named release. This has all the data about a version of a deployed helm chart. It’s compressed and stored as a base64 string.
It has everything about the helm chart; templated files, vaules passed into the chart, metadata about the chart, and metadata about the release itself.

This data looks something like this (I ommited a lot):

{
  "name": "nextcloud",
  "info": {
    "first_deployed": "2021-08-17T19:35:05.043010973-05:00",
    "last_deployed": "2021-08-17T20:04:22.557244059-05:00",
    "deleted": "",
    "description": "Upgrade complete",
    "status": "superseded",
    "notes": "1. Get the nextcloud URL by running:\n\n  export POD_NAME=$(kubectl get pods --namespace nextcloud -l \"app.kubernetes.io/name=nextcloud\" -o jsonpath=\"{.items[0].metadata.name}\")\n  echo http://127.0.0.1:8080/\n  kubectl port-forward $POD_NAME 8080:80\n\n2. Get your nextcloud login credentials by running:\n\n  echo User:     admin\n  echo Password: $(kubectl get secret --namespace nextcloud nextcloud -o jsonpath=\"{.data.nextcloud-password}\" | base64 --decode)\n"
  },
  "chart": {
    "metadata": {
      "name": "nextcloud",
      "home": "https://nextcloud.com/",
      "sources": [
        "https://github.com/nextcloud/helm",
        "https://github.com/nextcloud/docker"
      ],
      "version": "2.7.3",
      "description": "A file sharing server that puts the control and security of your own data back into your hands.",
        ...
      "appVersion": "20.0.11",
  ...
}

I’ll need the .info.status value to tell which one of the deployment revisions is the current active one. From there I can use the data in .chart.metadata.version and .chart.metadata.appVersion to see if I my chart is out of date!