Le dispositif Helm et ses pièges

Le dispositif Helm et ses pièges
Concept de transporteur de marchandises Typhon, Anton Swanepoel

Je m'appelle Dmitry Sugrobov, je suis développeur chez Leroy Merlin. Dans cet article, je vais vous expliquer pourquoi Helm est nécessaire, comment il simplifie le travail avec Kubernetes, ce qui a changé dans la troisième version et comment l'utiliser pour mettre à jour les applications en production sans temps d'arrêt.

Ceci est un résumé basé sur un discours prononcé lors d'une conférence Conférence @Kubernetes by Solutions Cloud Mail.ru — si vous ne voulez pas lire, regardez la vidéo.

Pourquoi nous utilisons Kubernetes en production

Leroy Merlin est leader sur le marché du bricolage en Russie et en Europe. Notre entreprise compte plus d'une centaine de développeurs, 33 000 collaborateurs internes et un grand nombre de personnes visitant les hypermarchés et le site Internet. Afin de les rendre tous heureux, nous avons décidé de suivre les approches standards de l’industrie. Développer de nouvelles applications en utilisant l'architecture de microservices ; utiliser des conteneurs pour isoler les environnements et assurer une livraison adéquate ; et utilisez Kubernetes pour l'orchestration. Le prix de l’utilisation d’orchestrateurs devient rapidement moins cher : le nombre d’ingénieurs maîtrisant la technologie augmente sur le marché et des fournisseurs apparaissent proposant Kubernetes en tant que service.

Tout ce que fait Kubernetes, bien sûr, peut être fait d'autres manières, par exemple en couvrant certains Jenkins et docker-compose avec des scripts, mais pourquoi se compliquer la vie s'il existe une solution toute faite et fiable ? C'est pourquoi nous avons choisi Kubernetes et l'utilisons en production depuis un an maintenant. Nous disposons actuellement de vingt-quatre clusters Kubernetes, dont le plus ancien a plus d'un an, avec environ deux cents pods.

La malédiction des gros fichiers YAML dans Kubernetes

Pour lancer un microservice dans Kubernetes, nous allons créer au moins cinq fichiers YAML : pour Deployment, Service, Ingress, ConfigMap, Secrets - et les envoyer au cluster. Pour la prochaine application, nous écrirons le même paquet de jambages, avec le troisième nous en écrirons un autre, et ainsi de suite. Si l'on multiplie le nombre de documents par le nombre d'environnements, on obtiendra déjà des centaines de fichiers, et cela ne prend pas encore en compte les environnements dynamiques.

Le dispositif Helm et ses pièges
Adam Reese, responsable principal de Helm, a introduit le concept de "Cycle de développement dans Kubernetes", qui ressemble à ceci :

  1. Copier YAML - copiez un fichier YAML.
  2. Collez YAML - collez-le.
  3. Corriger les retraits - corrige les retraits.
  4. Répétez - répétez encore.

L'option fonctionne, mais vous devez copier les fichiers YAML plusieurs fois. Pour changer ce cycle, Helm a été inventé.

Qu'est-ce que Helm

Tout d'abord, Helm - directeur chargé d'emballage, qui vous aide à trouver et à installer les programmes dont vous avez besoin. Pour installer, par exemple, MongoDB, vous n'avez pas besoin d'aller sur le site officiel et de télécharger les binaires, exécutez simplement la commande helm install stable/mongodb.

Deuxièmement, Helm - moteur de modèle, aide à paramétrer les fichiers. Revenons à la situation des fichiers YAML dans Kubernetes. Il est plus facile d'écrire le même fichier YAML, d'y ajouter des espaces réservés, dans lesquels Helm substituera les valeurs. Autrement dit, au lieu d'un grand ensemble d'échafaudages, il y aura un ensemble de modèles dans lesquels les valeurs requises seront remplacées au bon moment.

Troisièmement, Helm - maître de déploiement. Avec lui, vous pouvez installer, restaurer et mettre à jour des applications. Voyons comment procéder.

Le dispositif Helm et ses pièges

Comment utiliser Helm pour déployer vos propres applications

Installons le client Helm sur votre ordinateur, en suivant les instructions officielles instructions. Ensuite, nous allons créer un ensemble de fichiers YAML. Au lieu de spécifier des valeurs spécifiques, nous laisserons des espaces réservés, que Helm remplira d'informations à l'avenir. Un ensemble de ces fichiers est appelé un diagramme Helm. Il peut être envoyé au client de la console Helm de trois manières :

  • indiquer un dossier avec des modèles ;
  • emballez l'archive dans un fichier .tar et pointez dessus ;
  • placez le modèle dans un référentiel distant et ajoutez un lien vers le référentiel dans le client Helm.

Vous avez également besoin d'un fichier avec des valeurs - valeurs.yaml. Les données à partir de là seront insérées dans le modèle. Créons-le aussi.

Le dispositif Helm et ses pièges
La deuxième version de Helm dispose d'une application serveur supplémentaire - Tiller. Il se bloque en dehors de Kubernetes et attend les demandes du client Helm et, lorsqu'il est appelé, remplace les valeurs requises dans le modèle et l'envoie à Kubernetes.

Le dispositif Helm et ses pièges
Helm 3 est plus simple : au lieu de traiter les modèles sur le serveur, les informations sont désormais entièrement traitées côté client Helm et envoyées directement à l'API Kubernetes. Cette simplification améliore la sécurité du cluster et facilite le schéma de déploiement.

Comment ça fonctionne

Exécutez la commande helm install. Indiquons le nom de la version de l'application et donnons le chemin vers values.yaml. A la fin, nous indiquerons le référentiel dans lequel se trouve le graphique et le nom du graphique. Dans l’exemple, il s’agit respectivement de « lmru » et « bestchart ».

helm install --name bestapp --values values.yaml lmru/bestchart

La commande ne peut être exécutée qu'une seule fois, lorsqu'elle est exécutée à nouveau install besoin d'utiliser upgrade. Pour plus de simplicité, au lieu de deux commandes, vous pouvez exécuter la commande upgrade avec clé supplémentaire --install. Lors de sa première exécution, Helm enverra une commande pour installer la version et la mettra à jour ultérieurement.

helm upgrade --install bestapp --values values.yaml lmru/bestchart

Les pièges du déploiement de nouvelles versions d'une application avec Helm

À ce stade de l'histoire, je joue à Who Wants to Be a Millionaire avec le public et nous cherchons comment amener Helm à mettre à jour la version de l'application. Смотреть видео.

Lorsque j'ai appris comment fonctionne Helm, j'ai été surpris par un comportement étrange lors de la tentative de mise à jour des versions des applications en cours d'exécution. J'ai mis à jour le code de l'application, téléchargé une nouvelle image dans le registre Docker, envoyé la commande de déploiement - et rien ne s'est passé. Vous trouverez ci-dessous quelques méthodes pas entièrement efficaces pour mettre à jour les applications. En étudiant chacun d’eux plus en détail, vous commencez à comprendre la structure interne de l’instrument et les raisons de ce comportement pas évident.

Méthode 1. Ne modifiez pas les informations depuis le dernier lancement

Comme on dit site officiel Helm, "Les graphiques Kubernetes peuvent être volumineux et complexes, donc Helm essaie de ne rien toucher de trop." Par conséquent, si vous mettez à jour la dernière version de l'image de l'application dans le registre Docker et exécutez la commande helm upgrade, alors rien ne se passera. Helm pensera que rien n'a changé et qu'il n'est pas nécessaire d'envoyer une commande à Kubernetes pour mettre à jour l'application.

Ici et ci-dessous, la dernière balise est affichée uniquement à titre d'exemple. Lorsque vous spécifiez cette balise, Kubernetes téléchargera l'image à partir du registre Docker à chaque fois, quel que soit le paramètre imagePullPolicy. L’utilisation des dernières versions de production n’est pas souhaitable et provoque des effets secondaires.

Méthode 2. Mettre à jour LABEL dans l'image

Comme écrit dans le même documentation, "Helm ne mettra à jour une application que si elle a changé depuis la dernière version." Une option logique pour cela semblerait être de mettre à jour le LABEL dans l'image Docker elle-même. Cependant, Helm n'examine pas les images de l'application et n'a aucune idée des modifications qui y sont apportées. Par conséquent, lors de la mise à jour des étiquettes dans l'image, Helm n'en sera pas informé et la commande de mise à jour de l'application ne sera pas envoyée à Kubernetes.

Méthode 3 : utiliser une clé --force

Le dispositif Helm et ses pièges
Tournons-nous vers les manuels et recherchons la clé requise. La clé a le plus de sens --force. Malgré le nom évident, le comportement est différent de celui attendu. Au lieu de forcer une mise à jour de l'application, son véritable objectif est de restaurer une version dont l'état est FAILED. Si vous n'utilisez pas cette clé, vous devez exécuter les commandes séquentiellement helm delete && helm install --replace. Il est suggéré d'utiliser la clé à la place --force, qui automatise l'exécution séquentielle de ces commandes. Plus d'informations dans ce demande de tirage. Afin de dire à Helm de mettre à jour la version de l'application, cette clé ne fonctionnera malheureusement pas.

Méthode 4. Modifier les étiquettes directement dans Kubernetes

Le dispositif Helm et ses pièges
Mise à jour du label directement dans le cluster à l'aide de la commande kubectl edit - mauvaise idée. Cette action entraînera une incohérence des informations entre l’application en cours d’exécution et celle initialement envoyée pour déploiement. Le comportement de Helm lors du déploiement dans ce cas diffère de sa version : Helm 2 ne fera rien, et Helm 3 déploiera la nouvelle version de l'application. Pour comprendre pourquoi, vous devez comprendre comment fonctionne Helm.

Comment fonctionne Helm ?

Pour déterminer si une application a changé depuis sa dernière version, Helm peut utiliser :

  • exécuter une application dans Kubernetes ;
  • nouveaux valeurs.yaml et graphique actuel ;
  • Informations sur la version interne de Helm.

Pour les plus curieux : où Helm stocke-t-il les informations internes sur les versions ?En exécutant la commande helm history, nous obtiendrons toutes les informations sur les versions installées à l'aide de Helm.

Le dispositif Helm et ses pièges
Il existe également des informations détaillées sur les modèles et les valeurs envoyés. Nous pouvons le demander :

Le dispositif Helm et ses pièges
Dans la deuxième version de Helm, ces informations se trouvent dans le même espace de noms où Tiller est exécuté (kube-system par défaut), dans le ConfigMap, marqué du label « OWNER=TILLER » :

Le dispositif Helm et ses pièges
Lorsque la troisième version de Helm est apparue, les informations ont été déplacées vers les secrets et vers le même espace de noms où l'application était exécutée. Grâce à cela, il est devenu possible d'exécuter plusieurs applications simultanément dans différents espaces de noms avec le même nom de version. Dans la deuxième version, c'était un sérieux casse-tête lorsque les espaces de noms sont isolés mais peuvent s'influencer mutuellement.

Le dispositif Helm et ses pièges

Le deuxième Helm, lorsqu'il essaie de comprendre si une mise à jour est nécessaire, utilise uniquement deux sources d'informations : ce qui lui est fourni actuellement et les informations internes sur les versions, qui se trouvent dans le ConfigMap.

Le dispositif Helm et ses pièges
Le troisième Helm utilise une stratégie de fusion à trois voies : en plus de ces informations, il prend également en compte l'application qui s'exécute actuellement dans Kubernetes.

Le dispositif Helm et ses pièges
Pour cette raison, l'ancienne version de Helm ne fera rien, puisqu'elle ne prend pas en compte les informations de l'application dans le cluster, mais Helm 3 recevra les modifications et enverra la nouvelle application pour déploiement.

Méthode 5. Utilisez le commutateur --recreate-pods

Avec une clé --recreate-pods vous pouvez réaliser ce que vous aviez initialement prévu de réaliser avec la clé --force. Les conteneurs redémarreront et, selon la stratégie imagePullPolicy: Always pour la dernière balise (plus d'informations à ce sujet dans la note de bas de page ci-dessus), Kubernetes téléchargera et lancera une nouvelle version de l'image. Cela ne se fera pas de la meilleure des manières : sans prendre en compte le StrategyType de déploiement, cela désactivera brusquement toutes les anciennes instances d'application et commencera à en lancer de nouvelles. Lors du redémarrage, le système ne fonctionnera pas, les utilisateurs en souffriront.

Dans Kubernetes lui-même, un problème similaire existe depuis longtemps. Et maintenant, 4 ans après l'ouverture Question, le problème a été résolu et à partir de la version 1.15 de Kubernetes, la possibilité de redémarrer les pods apparaît.

Helm désactive simplement toutes les applications et lance de nouveaux conteneurs à proximité. Vous ne pouvez pas faire cela en production, afin de ne pas provoquer de temps d’arrêt des applications. Ceci n’est nécessaire que pour les besoins de développement et ne peut être effectué que dans des environnements de scène.

Comment mettre à jour la version de l'application à l'aide de Helm ?

Nous modifierons les valeurs envoyées à Helm. Généralement, ce sont des valeurs qui remplacent la balise d'image. Dans le cas de Latest, qui est souvent utilisé pour des environnements improductifs, les informations modifiables sont une annotation inutile pour Kubernetes lui-même, et pour Helm, elles serviront de signal pour la nécessité de mettre à jour l'application. Options pour renseigner la valeur de l'annotation :

  1. Valeur aléatoire en utilisant la fonction standard - {{ randAlphaNum 6 }}.
    Il y a une mise en garde : après chaque déploiement utilisant un graphique avec une telle variable, la valeur de l'annotation sera unique et Helm supposera qu'il y a des changements. Il s'avère que nous redémarrerons toujours l'application, même si nous n'avons pas modifié sa version. Ce n'est pas critique, puisqu'il n'y aura pas de temps d'arrêt, mais cela reste désagréable.
  2. Coller le courant date et l'heure - {{ .Release.Date }}.
    Une variante est similaire à une valeur aléatoire avec une variable unique en permanence.
  3. Une manière plus correcte consiste à utiliser sommes de contrôle. Il s'agit du SHA de l'image ou du SHA du dernier commit dans le git - {{ .Values.sha }}.
    Ils devront être comptés et envoyés au client Helm côté appelant, par exemple dans Jenkins. Si l'application a changé, la somme de contrôle changera. Par conséquent, Helm ne mettra à jour l’application qu’en cas de besoin.

Résumons nos tentatives

  • Helm effectue les modifications de la manière la moins invasive possible, de sorte que toute modification au niveau de l'image de l'application dans le registre Docker n'entraînera pas de mise à jour : rien ne se passera après l'exécution de la commande.
  • clé --force utilisé pour restaurer les versions problématiques et n’est pas associé à des mises à jour forcées.
  • clé --recreate-pods mettra à jour de force les applications, mais le fera de manière vandale : il éteindra brusquement tous les conteneurs. Les utilisateurs en souffriront ; vous ne devriez pas faire cela en production.
  • Apportez directement des modifications au cluster Kubernetes à l'aide de la commande kubectl edit ne le faites pas : nous romprons la cohérence et le comportement différera selon la version de Helm.
  • Avec la sortie de la nouvelle version de Helm, de nombreuses nuances sont apparues. Les problèmes du référentiel Helm sont décrits dans un langage clair, ils vous aideront à comprendre les détails.
  • L'ajout d'une annotation modifiable à un graphique le rendra plus flexible. Cela vous permettra de déployer l'application correctement, sans temps d'arrêt.

Une pensée de « paix mondiale » qui fonctionne dans tous les domaines de la vie : lisez la notice avant utilisation, pas après. Ce n'est qu'avec des informations complètes qu'il sera possible de construire des systèmes fiables et de satisfaire les utilisateurs.

Autres liens connexes :

  1. Rencontrez le Casque 3
  2. Site officiel de Helm
  3. Dépôt Helm sur GitHub
  4. 25 outils Kubernetes utiles : déploiement et gestion

Ce rapport a été présenté pour la première fois à Conférence @Kubernetes par Mail.ru Cloud Solutions. Regarder vidéo d'autres performances et abonnez-vous aux annonces d'événements sur Telegram Autour de Kubernetes chez Mail.ru Group.

Source: habr.com

Ajouter un commentaire