Introduction
As you have probably already read, Helm 2 has been replaced by Helm 3 which comes with a lot of major changes, the biggest being that the Tiller pod has been removed. This is a great security improvement since Tiller was a pod running with a lot of privileges on the cluster and was major point of vulnerability.
Also, support and upgrades to Helm 2 stopped since November 13, 2020. More information can be found here. So now is a good time, to finally make that move to Helm 3.
Setup & Overview
The basic flow of the migration will be as follows
- Backup data
- Let Helm 2 continue to handled the Releases
- Install Helm 3 client and configure it to be able to access the Helm 2 Releases
- Run a Helm 3 upgrade dry run on the Releases and fix any conflicts
-
Finally run a Helm 3 upgrade on the Releases and if successful, delete Helm 2 & Tiller configuration from the cluster
Install the v2 and v3 clients on your machine
- Download and save the Helm 3 binary from here and save it in your binary path as
helm3
. For example,mv helm-v3.4.2-darwin-amd64/helm /usr/local/bin/helm3
It’s important to name this as helm3 so that you don’t confuse the two versions while performing the migration. -
Similarly, download and save the most recent Helm 2 binary from the releases page and save it as
helm2
in your binary path. Then runhelm2 list
to see if the version is compatible with your Tiller version. If not, then download a older helm2 version accordingly.Backup
- Install the backup plugin using helm2
helm plugin install https://github.com/maorfr/helm-backup
- Next, backup all the namespaces where Helm Releases exist using
helm backup <namespace>
Migration
- Install the migration plugin using helm3
https://github.com/helm/helm-2to3
- There are two major steps to the migration.
- Move Config: This copies the configuration of the Releases into the Helm3 config directory.
- Convert: This will create links to the Helm2 Releases in the Helm3 config directory so that
helm3
can access them. After thishelm3 list
should show the currently deployed Releases
- So first, run
helm3 2to3 move config --dry-run
to make sure there are no errors and then subsequently run it without the –dry-run flag. - Next, run
helm3 2to3 convert <release-name> --dry-run
to ensure a error-free run and then execute the command without the –dry-run flag - You should now be able to list the Releases using
helm3 list
- As a safety check, do a
kubectl get pods,svc
on the resources running under the Helm2 Releases. Check the Age of these resources to make sure that they weren’t redeployed.
It’s important to note that this migration tool only migrates the Helm2 configuration, not the Kubernetes Resources themselves
Upgrade Conflicts
Now that you have successfully “copied” the Releases from Helm2 to Helm3, it’s time to test how well the migration worked. In my personal experience, some of the Releases work out of the box with Helm3, i.e, running helm3 upgrade <release>
works as expected and upgrades the Release without anything breaking.
However, for some Releases, especially the older ones and outdated ones which have gone through several version upgrades that have Breaking Changes, I saw peculiar issues like these.
Some upgrades failed because of outdated annotations added to the K8S objects by the Helm2 client. To fix this, run helm3 upgrade grafana stable/grafana --dry-run
and then manually annotate the Objects that are shown as incorrectly annotated as follows in the case of a Grafana chart
kubectl annotate Deployment grafana "meta.helm.sh/release-name=grafana" "meta.helm.sh/release-namespace=default" --overwrite
kubectl label ServiceAccount grafana-test "app.kubernetes.io/managed-by=Helm"
Similary, run helm3 upgrade grafana stable/grafana --dry-run
again until the errors disappear and finally run the upgrade without the –dry-run flag
Conclusion
So while migrating the Releases to Helm3 from Helm2 is pretty much non-breaking and safe to perform, the real challenge is making these migrated Releases compatible with Helm3. Helm3 also uses custom chart repository instead of the old stable/charts central repository. This means that you will have to look up the latest repo URL for your chart and add them Helm3 using helm repo add <repo-name> <repo-url>
.
As a best practice, please make sure to go through the Breaking Changes if any of whatever app you are trying to upgrade. Also, perform minor point version upgrades and slowly get to the version you are comfortable with or is stable.
Things get more complicated when upgrading Releases which have Persistent Storage or stuff like MongoDB Deployments. These should be handled much more carefully, making sure to take backups and doing a dry run on a identical setup on a non-production cluster.
Some Deployments like Nginx-Ingress might be too outdated to be able to maintain them using Helm3. In such cases, it makes sense to create a new Helm Release from scratch rather than spend a lot of hours trying to do a in-place upgrade.
Comments