Helm 3 : feedback et migration

8 Avril 2020 • 7 min

Après de longs mois de travail, la version 3 de Helm est sortie fin 2019 ! 

À l’heure ou j’écris ces lignes, nous en sommes déjà à la version 3.1.2. Nous avons donc un peu de recul pour en tirer quelques enseignements et les aborder dans cet article.

Je vais tout d’abord vous présenter les principales nouveautés, et ensuite partager mon retour d’expérience en vous donnant quelques clés pour prendre en main cette version et bien gérer votre migration.

Vous êtes un passionné de Kubernetes vous-aussi ? Allez, regardons de plus près ce Helm 3 ensemble !

Note : dans les exemples ci-dessous, helm signifiera par défaut “helm 3”, quand il s’agit d’autres versions je le préciserai en mettant le suffixe (e.g. helm-2.14).

Quelles nouveautés avec Helm 3 ?

Pour rappel, Helm est un package manager pour Kubernetes. Il permet d’installer des charts (l’équivalent des archives d’installation) en tant que “release” (l’équivalent des paquets une fois installés). 

Helm permet de générer un ensemble de manifests Kubernetes à l’aide de templates et de ‘values’ par défaut qui peuvent êtres personnalisées par l’utilisateur.

Tiller, il faut qu’on parle

Le point majeur de cette version 3 de Helm est la suppression du composant Tiller.

Jusque là, Helm se basait sur ce composant installé au sein du cluster pour opérer les déploiements. La partie client (le binaire helm) s’occupait de transférer les ordres de déploiement (le chart contenant les templates & les valeurs fournies par l’utilisateur), et d’en afficher le résultat. Bien qu’ayant l’avantage du modèle client-server (i.e. je peux lancer un helm install, et une fois les ordres transférés, je peux fermer mon laptop), il avait un inconvénient majeur : une gestion des permissions complexe à prendre en main.

La nature même du travail de Tiller étant le déploiement d’infrastructure dans Kubernetes, il nécessitait une liste de droits conséquente. Et le design de Tiller date d’avant le système de gestion RBAC de kubernetes. Tiller a donc été conçu sans gestion de droit. Avec l’arrivée de RBAC, cela s’est révélé un inconvenient majeur en permettant à quiconque capable d’interagir avec Tiller de l’utiliser pour contourner le niveau de droits auquel il avait été restreint.

Cette absence de gestion des droits a fini par faire de Tiller une “persona non grata”. Il a donc été décidé par la communauté de déplacer le composant d’installation dans le client helm lui-même et d’utiliser directement les droits de l’appelant pour effectuer les installations, avec une gestion des droits directement gérée par Kubernetes.

Monnn secreeet (à lire avec la voix de Gollum)

Le deuxième point fondamental de cette nouvelle version stable de Helm est l’utilisation de secret comme backend de stockage. Avec Helm 2, Tiller utilisait des configmaps pour stocker les informations reçues de l’utilisateur. Ces informations pouvaient contenir les secrets du deployment en cours et donc exposer ces informations à toute personne capable de lire les configmaps de tiller (et ce n’était pas très compliqué…).

Avec Helm 3, le backend utilise maintenant les secrets par defaut, ce qui permet d’utiliser le contrôle d’accès de Kubernetes pour garder ses données sensibles au chaud sans empêcher les personnes avec moins de privilèges de travailler.

Listing par namespace

La gestion des namespace a aussi été revue. Helm ne crée plus les namespaces comme il le faisait dans la version 2. Au passage, les secrets contenant les informations des releases sont maintenant localisés directement dans le namespace utilisé. Cela permet de ne pas surcharger un namespace particulier et de faciliter le nettoyage d’une application. L’installation d’une application dans son namespace se fait désormais de cette façon :

kubectl create namespace myapp
helm install myapp stable/myapp -n myapp

Pour supprimer l’application, à condition que seules des resources localisées dans le namespace aient été utilisées (les exceptions notables sont les CustomResourceDefinition et les ClusterRoles et les ClusterRoleBindings):

kubectl delete namespace

Kubernetes s’occupe de faire le nettoyage de toutes les resources contenues dans le namespace.

Publier sur un registry

La façon traditionnelle de partager un chart avec ses collègues ou la communauté est d’utiliser un “chart repository”. Derrière ce mot un peu mystérieux se cache un serveur web tout bête avec un fichier d’index index.yaml qui ressemble à ça : 

apiVersion: v1
entries:
myproject:
- apiVersion: v1
appVersion: 1.4.0
created: 2018-12-12T22:49:45.712832629Z
description: A Helm chart for myproject
digest: 47cf0dbd343af946c79b5074a5cc1e3345903566f33dc2c99ab43d7d1c489bc5
name: myproject
urls:
- https://github.com/myaccount/myproject/releases/download/v0.0.10/myproject-0.0.10.tgz
version: 0.0.10
- apiVersion: v1
appVersion: 1.4.0
created: 2018-12-12T22:06:26.51358245Z
description: A Helm chart for myproject
digest: f331824809aa438ffecf8835f248d84a6d36bb4326496b707d13c706fc03fff1
name: myproject
urls:
- https://github.com/myaccount/myproject/releases/download/v0.0.9/myproject-0.0.9.tgz
version: 0.0.9

Le contenu des charts (myproject-*.tgz) peut être hébergé sur le même serveur ou sur un serveur distant.

Le point intéressant c’est que la release de Helm 3 marque l’apparition du support (encore expérimentale) des “OCI registry” comme lieu d’hébergement.

Pour ceux qui se demandent ce qu’est un “OCI registry”, rappelons qu’OCI signifie Open Container Initiative , consortium œuvrant pour la standardisation de l’écosystème technologique autour des conteneurs. Un OCI registry est donc un dépôt pour des images de conteneurs respectant le standard défini par l’OCI. Il trouve assez logiquement ses origines dans la registry Docker.

Le format de conteneur OCI s’étant largement popularisé, il est devenu le standard de-facto de l’industrie. Ceci a ainsi permis de voir fleurir les projets dans l’écosystème d'“OCI registry”. On pense à Docker distribution, Harbor ou encore Gitlab pour ne citer que les plus connus.

Les régressions/les contournements

Lors de mes divers tests et migrations sur nos infrastructures Enix pour le compte de nos clients, j’ai rencontré quelques problèmes dont j’aimerais partager les solutions avec vous. Par exemple, Helm 3 est encore jeune et n’est donc pas dénué de petits bugs :

$ helm create myproj
$ helm template myproj # les manifests s'affichent
$ sed -i myproj/templates/deployment.yaml -e 's!\(protocol: TCP\)! \1!' # On crée une erreur d'indentation dans le yaml
$ helm template myproj # erreur ligne 35 alors que la ligne changée est la ligne 33

Heureusement, ce bug est facilement contournable … en appelant Helm 2.14 à la rescousse :

$ helm-2.14 template myproj
[...]
ports:
- name: http
containerPort: 80
protocol: TCP ## mauvaise indentation yaml

À noter cette étrangeté en terme de rétro-compatibilité, j’ai remarqué que helm-2.16 refuse de travailler sur un chart version 3, alors que la version 2.14 accepte. Ça vous fera peut-être gagner du temps !

À noter aussi que cela est corrigé en version 3.2 qui est la prochaine version mineure de Helm.

La dynamique du projet… quand migrer ?

Le projet Helm possède une grande communauté et un haut niveau d’adoption parmi les utilisateurs de Kubernetes. Ceci présente l’avantage de voir les bugs fixés rapidement. Il est donc raisonnable de migrer sur la dernière version stable de Helm 3 dès aujourd’hui.

Cependant, si vous utilisez Helm à travers un autre outil (par exemple Terraform, ou un opérateur Kubernetes), assurez-vous que cet outil est compatible avec Helm 3 . Par exemple, terraform supporte helm 3 depuis la version 1.0.0 du provider sorti début février.

Faites également attention aux shell scripts, les arguments de la ligne de commande ont parfois un peu changé. Par exemple en helm 2, le nom de la release est optionel et est donné via l’arguement “–name” (si on ne le met pas, un nom aléatoire est généré), alors qu’avec helm3 ça ne fonctionnera pas si on ne le met pas !

De plus, il est possible d’utiliser en parallèle les releases helm 2 et helm 3 sur le même cluster, ce qui simplifie grandement la migration.

Attention toutefois à ne pas faire gérer des ressources simultanément par une release helm 2 et par une release helm 3, les conséquences pourraient être désastreuses.

Comment migrer sur Helm 3 ?

C’est bon, vous avez décidé d’adopter helm 3 ? Vous avez encore des releases gérées par helm 2 et vous souhaitez entierement passer sur helm 3 pour simplifier votre outillage ?

Helm 3 est capable de s’occuper de la migration grâce à un plugin qui s’installe facilement :

helm plugin install https://github.com/helm/helm-2to3.git
helm 2to3 convert <ma_release>

Il ne reste alors plus qu’à supprimer les configmaps qui se trouvent dans le namespace où se trouve Tiller et à supprimer Tiller lui-même à la fin de la migration de toutes les releases.

Voilà pour ce petit tour concernant Helm 3. A bientôt !


Ne ratez pas nos prochains articles DevOps et Cloud Native! Suivez Enix sur Twitter!