How to deal with Helm charts using deprecated K8s API
Introduction
Imagine, you are navigating through a millennia-old Kubernetes cluster. Somehow its guardian is in an even older slumber, lost within the realm of dreams. It is now your task to take over its duties. You launch towards the nearest console, removing the dust from the screen and keyboard, and start assessing the situation, for you are the new Guardian.
You are somehow familiar with the technology, and discover Helm 3 is installed by looking through the secrets of some namespaces. You decide to upgrade the charts you find are outdated, everything goes smoothly until you hit this error:
Error: failed decoding reader into objects: unable to recognize "": no matches for kind "Deployment" in version "apps/v1beta2"
Prerequisite
To be able to get this message and to solve it, you will need the following components:
- A K8s cluster running on the v1.16 or newer version.
- Helm 3.
Error explanation
This is the kind of error that you will find using helm charts that have not been updated to follow the version of the cluster. In this case, the release of this chart has not been touched since quite the v1beta1
version of the apps object in the K8s API was still around and commonly used.
Deprecated APIs Removed In 1.16: Here's What You Need To Know
Deployment in the extensions/v1beta1, apps/v1beta1, and apps/v1beta2 API versions is no longer served
Migrate to use the apps/v1 API version, available since v1.9. Existing persisted data can be retrieved/updated via the new version.
According to the Helm documentation, the error will occur because of the following course of events:
Helm fails in this scenario because it attempts to create a diff patch between the current deployed release (which contains the Kubernetes APIs that are removed in this Kubernetes version) against the chart you are passing with the updated/supported API versions. The underlying reason for failure is that when Kubernetes removes an API version, the Kubernetes Go client library can no longer parse the deprecated objects and Helm therefore fails when calling the library. Helm unfortunately is unable to recover from this situation and is no longer able to manage such a release.
Cf. https://helm.sh/docs/topics/kubernetes_apis/
How to fix the API version of the chart
You can follow the procedure from the Helm documentation, which can be quite arduous when you are not familiar with Helm's underbelly. Or you can use some tools created by the community to make the modification less painful (which is what this article is about).
Installing the mapkubeapis
plugin
MapkubeAPIs is a plugin that will check for any deprecated version of the API used by the manifests of a Helm chart and modify them to use its latest version. You can learn more about it using this link: https://github.com/hickeyma/helm-mapkubeapis.
To install it, we will use the following command:
$ helm plugin install <https://github.com/hickeyma/helm-mapkubeapis>
Downloading and installing helm-mapkubeapis v0.0.15 ...
<https://github.com/hickeyma/helm-mapkubeapis/releases/download/v0.0.15/helm-mapkubeapis_0.0.15_darwin_amd64.tar.gz>
Installed plugin: mapkubeapis
You can now check if the plugin is showing on Helm's list:
$ helm plugin list
NAME VERSION DESCRIPTION
mapkubeapis 0.0.15 Map release deprecated Kubernetes APIs in-place
Upgrading the manifests to a new API version
We can now focus on changing the version of the API used by the manifest to a supported one. We will use the plugin we just installed by using its dry-run feature:
$ helm mapkubeapis test-release --namespace test-namespace --dry-run
2020/11/13 11:20:33 NOTE: This is in dry-run mode, the following actions will not be executed.
2020/11/13 11:20:33 Run without --dry-run to take the actions described below:
2020/11/13 11:20:33
2020/11/13 11:20:33 Release 'test-release' will be checked for deprecated or removed Kubernetes APIs and will be updated if necessary to supported API versions.
2020/11/13 11:20:33 Get release 'test-release' latest version.
2020/11/13 11:20:33 Check release 'test-release' for deprecated or removed APIs...
2020/11/13 11:20:34 Found deprecated or removed Kubernetes API:
"apiVersion: apps/v1beta2
kind: Deployment"
Supported API equivalent:
"apiVersion: apps/v1
kind: Deployment"
2020/11/13 11:20:34 Finished checking release 'test-release' for deprecated or removed APIs.
2020/11/13 11:20:34 Deprecated or removed APIs exist, updating release: eslog-metrics.
2020/11/13 11:20:34 Set status of release version 'test-release.v2' to 'superseded'.
2020/11/13 11:20:34 Release version 'test-release.v2' updated successfully.
2020/11/13 11:20:34 Add release version 'test-release.v3' with updated supported APIs.
2020/11/13 11:20:34 Release version 'test-release.v3' added successfully.
2020/11/13 11:20:34 Release 'test-release' with deprecated or removed APIs updated successfully to new version.
2020/11/13 11:20:34 Map of release 'test-release' deprecated or removed APIs to supported versions, completed successfully.
We can see no error message, so we can now move forward changing the API:
$ helm mapkubeapis test-release --namespace test-namespace
2020/11/13 11:25:56 Release 'test-release' will be checked for deprecated or removed Kubernetes APIs and will be updated if necessary to supported API versions.
2020/11/13 11:25:56 Get release 'test-release' latest version.
2020/11/13 11:25:56 Check release 'test-release' for deprecated or removed APIs...
2020/11/13 11:25:56 Found deprecated or removed Kubernetes API:
"apiVersion: apps/v1beta2
kind: Deployment"
Supported API equivalent:
"apiVersion: apps/v1
kind: Deployment"
2020/11/13 11:25:56 Finished checking release 'test-release' for deprecated or removed APIs.
2020/11/13 11:25:56 Deprecated or removed APIs exist, updating release: eslog-metrics.
2020/11/13 11:25:56 Set status of release version 'test-release.v2' to 'superseded'.
2020/11/13 11:25:57 Release version 'test-release.v2' updated successfully.
2020/11/13 11:25:57 Add release version 'test-release.v3' with updated supported APIs.
2020/11/13 11:25:57 Release version 'test-release.v3' added successfully.
2020/11/13 11:25:57 Release 'test-release' with deprecated or removed APIs updated successfully to new version.
2020/11/13 11:25:57 Map of release 'test-release' deprecated or removed APIs to supported versions, completed successfully.
We can now upgrade the chart to a newer version (in this case the 2.1.1):
helm upgrade test-release stable/test-chart --version="2.1.1" --namespace test-namespace -f ~/path/to/chart/values/values.yaml
Happy Helming!