De Flux v1 à flux v2 : retour d'expérience de migration à grande échelle

7 Septembre 2023 • 6 min

Dans la première partie, nous avions évoqué la méthode officielle pour migrer progressivement de Flux v1 à Flux v2. Dans cette seconde partie, nous allons présenter les éléments auxquels il faut prêter attention et notre retour d’expérience sur un mode de migration plus pertinent pour des migrations à grande échelle.

HelmRelease

La custom resource HelmRelease décrit le déploiement d’un chart Helm par Flux. Avec Flux v1, c’était un composant séparé (le helm-operator), sur Flux v2 c’est désormais un controller intégré à Flux.

Schema Helm controller

Puisque que c’est une custom resource différente, l'API spec change et il faut migrer les manifests au nouveau format avec l’aide du guide de migration qui est plutôt complet.

Le but de la migration pour les HelmRelease, c’est de faire en sorte que le nouveau helm-controller prenne le relai du helm-operator pour la gestion des Helm déployés dans le cluster. Pour ça, il suffit de :

  • Stopper le helm-operator
  • Déployer les nouvelles custom resources HelmRepository/HelmRelease
  • Laisser le helm-controller redéployer le chart pour s’approprier tous les manifests générés par Helm

Release name du HelmRelease

Il faut bien faire attention au release name du chart. S’il était déjà présent dans le HelmRelease, aucun problème. Sinon, la manière de générer le nom par défaut a changé et doit être prise en compte.

Avec Flux v1, le helm-operator utilise {{spec.targetNamespace}}-{{metadata.name}} (avec spec.targetNamespace qui vaut metadata.namespace si non précisé).

Avec Flux v2, c’est pareil sauf si spec.targetNamespace == metadata.namespace : dans ce cas-là, la valeur est {{metadata.name}}. Dans ce cas, il faut explicitement mettre le même release name pour que le helm-controller re-déploie le chart au lieu de déployer une nouvelle instance.

Image Update Automation

L'image update automation n’est généralement pas la partie la plus connue de Flux, elle permet de mettre à jour les images des containers lorsqu’une nouvelle version est disponible sur la registry.

Le fonctionnement global est le suivant :

  • On définit la registry où chercher les nouvelles images (avec un critère de sélection des images)
  • On indique dans les manifests Kubernetes gérés par Flux quelles sont les images à mettre à jour automatiquement
  • Quand une nouvelle image est disponible sur la registry, Flux modifie le manifest pour mettre à jour l’image et pousse le changement sur le dépôt git pour que le nouveau manifest soit déployé au prochain reconcile de Flux

Avec Flux v1, la configuration se faisait via des annotations sur les manifests à mettre à jour automatiquement.

Sous Flux v2, il y a désormais plusieurs custom resources pour gérer ceci de manière beaucoup plus fine. Une fois de plus, le guide de migration contient toute les informations nécessaires.

ImageUpdateAutomation et namespaces

Contrairement aux autres custom resources de Flux, celles-ci ne sont pas (encore ?) cross-namespace. Donc si on veut placer dans le même namespace les workloads, ImageRepository et ImagePolicy, ça va coincer, parce qu’ils doivent être dans le même namespace que l'ImageUpdateAutomation et le GitRepository associés.

Deux options sont possibles : mettre ces custom resources dans le même namespace, ou en dupliquer une partie.

Trier les tags des images

Un changement important qui peut nécessiter une adaptation des pipelines de build, c’est la manière dont Flux trie les images récupérées sur la registry pour déterminer les versions plus récentes.

Flux v1 utilisait le build time de l’image par défaut, alors que ce n’est plus possible avec Flux v2. Il faut désormais trier les tags avec l’une des méthodes suivantes :

  • Alphabétiquement
  • Numériquement
  • Via semantic versionning

Il y a un guide dédié pour rendre les images triables si besoin.

L’accès aux registry privées

Le secret de pull n’est plus récupéré automatiquement depuis le workload, il faut le préciser explicitement dans l'ImageRepository. Il y a des exemples utiles dans la documentation pour différents fournisseurs cloud.

Migration à Flux v2 version black-belt

Les nouveaux déploiements sont bloqués pendant le temps de migration de chaque manifest Flux. Quand on a de nombreux HelmRelease, dont les versions d’image sont régulièrement mises à jour par Flux, l’approche de migrer progressivement les manifests de Flux v1 à Flux v2 comme indiquée dans la méthode de migration officielle s’avère fastidieuse et peu souhaitable.

Pour certains de nos clients, il nous a donc semblé plus pertinent de bloquer une courte période sans nouveau déploiement et de mettre à jour tous les manifests en une seule fois en conservant le même dépôt git. Voici comment nous avons procédé !

Automatiser la mise à jour des manifests

Avec une centaine de HelmRelease à mettre à jour sur une dizaine de clusters, automatiser la mise à jour des manifests était devenu indispensable.

Pour les HelmRelease, en plus des modifications d'API spec, il faut générer deux manifests au lieu d’un pour sortir le repository dans sa custom resource dédiée.

Pour les ImageUpdateAutomation, ça demande de convertir les annotations en custom resources équivalents et de placer les commentaires au bon endroit dans le manifest pour indiquer le champ à mettre à jour.

Appliquer la migration à Flux v2

Une fois que l’on a créé notre moulinette pour convertir tous les manifests dans leur version Flux v2, dérouler le plan de migration devient la partie facile 🙂

  1. On scale à 0 le Deployment Flux v1 et le helm-operator
  2. On applique les manifests Flux v2 généré par flux install --export
  3. Une fois que les controllers sont démarrés, on kubectl apply le GitRepository et le Kustomization qui correspond à notre dépôt git avec tous nos manifests
  4. On génère la nouvelle version des manifests avec notre moulinette
  5. Et on git commit et git push toutes nos modifications

Il ne reste qu’à vérifier que tout se passe bien avec un flux get all -A 😎 : chaque élément va passer à Ready=True au fur à mesure que Flux v2 appliquera le contenu.

Normalement, rien ne devrait changer sur le cluster vu que Flux se contente d’appliquer les mêmes manifests Kubernetes qu’auparavant. Une petite différence est possible pour les HelmRelease : la première fois, le helm-controller effectue un helm upgrade, ce qui pourrait déclencher un redéploiement (dans le cas où le chart génère des valeurs par exemple).

Quand tout est au status ready, c’est presque fini !

Il reste à vérifier que chaque HelmRelease autrefois géré par le CRD helmreleases.helm.fluxcd.io est désormais bien visible avec la commande flux get helmreleases -A.

On peut alors supprimer le Deployement Flux v1 et helm-operator puis la CRD helmreleases.helm.fluxcd.io (⚠️ attention à ne pas supprimer la nouvelle !).

C’est terminé, il ne vous reste plus qu’à profiter de toutes les belles nouveautés Flux v2 !


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