{"id":53120,"date":"2019-11-24T00:00:00","date_gmt":"2019-11-23T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/3-way-merge-v-werf-deploj-v-kubernetes-s-helm-na-steroidah"},"modified":"2020-02-18T14:00:59","modified_gmt":"2020-02-18T11:00:59","slug":"3-way-merge-v-werf-deploj-v-kubernetes-s-helm-na-steroidah","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/3-way-merge-v-werf-deploj-v-kubernetes-s-helm-na-steroidah","title":{"rendered":"Fusion en 3 \u00e9tapes avec werf : d\u00e9ploiement dans Kubernetes avec Helm \u00ab sous st\u00e9ro\u00efdes \u00bb","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Il s'est pass\u00e9 ce que nous (et pas seulement nous) avons longtemps attendu : <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/\">werf<\/a><\/noindex>, notre outil Open Source pour la construction d'applications et leur d\u00e9ploiement dans Kubernetes prend d\u00e9sormais en charge la mise en \u0153uvre de modifications gr\u00e2ce \u00e0 des patches en 3-way-merge ! En plus de cela, il est maintenant possible d'adopter des ressources K8s existantes dans des releases Helm sans avoir \u00e0 recr\u00e9er ces ressources.<\/p>\n<p><img decoding=\"async\" alt=\"Fusion en 3 \u00e9tapes avec werf : d\u00e9ploiement dans Kubernetes avec Helm \u00ab sous st\u00e9ro\u00efdes \u00bb\" src=\"\/wp-content\/uploads\/2019\/11\/e5be3544c201f7b2c97fba216a49506d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPour faire court, on met <code>WERF_THREE_WAY_MERGE=enabled<\/code> \u2014 on obtient un d\u00e9ploiement \u00ab comme dans <code>kubectl apply<\/code>\u00bb, compatible avec les installations existantes sur Helm 2 et m\u00eame un peu plus.<\/p>\n<p>Mais commen\u00e7ons par la th\u00e9orie : qu'est-ce que les patches en 3-way-merge, comment les gens en sont-ils arriv\u00e9s \u00e0 cette approche pour leur g\u00e9n\u00e9ration et pourquoi sont-ils importants dans les processus CI\/CD avec une infrastructure bas\u00e9e sur Kubernetes ? Ensuite, nous verrons ce qu'est r\u00e9ellement le 3-way-merge dans werf, quels modes sont utilis\u00e9s par d\u00e9faut et comment les g\u00e9rer.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Qu'est-ce qu'un patch en 3-way-merge ?<\/h2>\n<p>\nAlors, commen\u00e7ons par la t\u00e2che de d\u00e9ploiement des ressources d\u00e9crites dans des manifestes YAML dans Kubernetes.<\/p>\n<p>Pour travailler avec les ressources, l'API Kubernetes propose les op\u00e9rations principales suivantes : create, patch, replace et delete. Il est pr\u00e9vu que celles-ci permettent de construire un d\u00e9ploiement continu des ressources dans le cluster. Comment ?<\/p>\n<h3>Commandes imp\u00e9ratives kubectl<\/h3>\n<p>\nLa premi\u00e8re approche pour g\u00e9rer des objets dans Kubernetes consiste \u00e0 utiliser des commandes kubectl imp\u00e9ratives pour cr\u00e9er, modifier et supprimer ces objets. En d'autres termes :<\/p>\n<ul>\n<li> la commande <code>kubectl run<\/code> peut lancer un Deployment ou un Job :\n<pre><code class=\"bash\">kubectl run --generator=deployment\/apps.v1 NOM_DU_DEPLOIEMENT --image=IMAGE<\/code><\/pre>\n<\/li>\n<li> la commande <code>kubectl scale<\/code> \u2014 changer le nombre de r\u00e9plicas :\n<pre><code class=\"bash\">kubectl scale --replicas=3 deployment\/mysql<\/code><\/pre>\n<\/li>\n<li>etc.<\/li>\n<\/ul>\n<p>\nCette approche peut sembler pratique au premier abord. Cependant, il y a des probl\u00e8mes : <\/p>\n<ol>\n<li> Il est difficile de <b>l'automatiser<\/b>.<\/li>\n<li> Comment <b>de refl\u00e9ter la configuration<\/b> dans Git ? Comment faire une revue des modifications qui se produisent dans le cluster ?<\/li>\n<li> Comment assurer <b>la reproductibilit\u00e9<\/b> de la configuration lors du red\u00e9marrage ?<\/li>\n<li>\u2026<\/li>\n<\/ol>\n<p>\nIl est clair que cette approche s'accorde mal avec le stockage du code de l'application et de l'infrastructure comme code (IaC ; ou m\u00eame <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/458878\/\">GitOps<\/a><\/noindex> comme une variante plus moderne, en gagnant en popularit\u00e9 dans l'\u00e9cosyst\u00e8me Kubernetes). C'est pourquoi ces commandes n'ont pas \u00e9t\u00e9 davantage d\u00e9velopp\u00e9es dans kubectl.<\/p>\n<h3>Op\u00e9rations create, get, replace et delete<\/h3>\n<p>\nAvec la cr\u00e9ation initiale, <b>c'est simple : on envoie le manifeste \u00e0 l'op\u00e9ration<\/b> au kube api et la ressource est cr\u00e9\u00e9e. La repr\u00e9sentation YAML du manifeste peut \u00eatre stock\u00e9e dans Git, et pour la cr\u00e9ation, on utilise la commande <code>create<\/code> kubectl create -f manifest.yaml <code>pour la suppression,<\/code>.<\/p>\n<p>Avec <b>c'est aussi simple : on passe le m\u00eame<\/b> manifest.yaml <code>de Git \u00e0 la commande<\/code> kubectl delete -f manifest.yaml <code>Op\u00e9ration<\/code>.<\/p>\n<p>Op\u00e9ration <b><code>remplacer<\/code><\/b> permet de remplacer compl\u00e8tement la configuration d'une ressource par une nouvelle, sans recr\u00e9er la ressource. Cela signifie qu'avant de modifier la ressource, il est logique de demander la version actuelle par l'op\u00e9ration <code>obtenir<\/code>, de la modifier et de mettre \u00e0 jour avec l'op\u00e9ration <code>remplacer<\/code>. Dans kube apiserver, il y a une int\u00e9gration de <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Optimistic_concurrency_control\">verrouillage optimiste<\/a><\/noindex> et, si apr\u00e8s l'op\u00e9ration <code>obtenir<\/code> l'objet a chang\u00e9, alors l'op\u00e9ration <code>remplacer<\/code> \u00e9chouera.<\/p>\n<p>Pour stocker la configuration dans Git et mettre \u00e0 jour en utilisant replace, il faut effectuer l'op\u00e9ration <code>obtenir<\/code>, fusionner la configuration de Git avec celle que nous avons re\u00e7ue, et ex\u00e9cuter <code>remplacer<\/code>. Par d\u00e9faut, kubectl permet seulement d'utiliser la commande <code>kubectl replace -f manifest.yaml<\/code>, o\u00f9 <code>de Git \u00e0 la commande<\/code> \u2014 un manifeste d\u00e9j\u00e0 enti\u00e8rement pr\u00e9par\u00e9 (dans notre cas \u2014 fusionn\u00e9) qui doit \u00eatre install\u00e9. En fin de compte, l'utilisateur doit r\u00e9aliser la fusion des manifestes, ce qui n'est pas trivial...<\/p>\n<p>Il convient \u00e9galement de noter que bien que <code>de Git \u00e0 la commande<\/code> soit stock\u00e9 dans Git, nous ne pouvons pas savoir \u00e0 l'avance s'il faut cr\u00e9er l'objet ou le mettre \u00e0 jour \u2014 cela doit \u00eatre fait par le logiciel utilisateur.<\/p>\n<p>Total : <b>pouvons-nous construire un d\u00e9ploiement continu<\/b> uniquement avec create, replace et delete, en garantissant le stockage de la configuration de l'infrastructure dans Git avec le code et un CI\/CD convivial ?<\/p>\n<p>En principe, oui... Pour cela <b>il faudra impl\u00e9menter l'op\u00e9ration de fusion<\/b> des manifestes et une certaine enveloppe qui:<\/p>\n<ul>\n<li> v\u00e9rifie la pr\u00e9sence de l'objet dans le cluster,<\/li>\n<li> effectue la cr\u00e9ation initiale de la ressource,<\/li>\n<li> la met \u00e0 jour ou la supprime.<\/li>\n<\/ul>\n<p>\nLors de la mise \u00e0 jour, il faut prendre en compte que <i>la ressource a pu changer<\/i> depuis la derni\u00e8re <code>obtenir<\/code> et traiter automatiquement le cas de verrouillage optimiste \u2014 en faisant des tentatives de mise \u00e0 jour \u00e0 nouveau.<\/p>\n<p>Mais pourquoi r\u00e9inventer la roue quand kube-apiserver propose une autre m\u00e9thode de mise \u00e0 jour des ressources : l'op\u00e9ration <code>patch<\/code>, qui soulage l'utilisateur de certaines des probl\u00e9matiques d\u00e9crites ?<\/p>\n<h3>Patch<\/h3>\n<p>\nNous voil\u00e0 arriv\u00e9s aux patchs.<\/p>\n<p>Les patchs sont le moyen principal d'appliquer des modifications aux objets existants dans Kubernetes. L'op\u00e9ration <code>patch<\/code> fonctionne de telle mani\u00e8re que :<\/p>\n<ul>\n<li> l'utilisateur du kube-apiserver doit envoyer un patch au format JSON et indiquer l'objet,<\/li>\n<li> et l'apiserver s'occupera de l'\u00e9tat actuel de l'objet et le mettra dans l'\u00e9tat requis.<\/li>\n<\/ul>\n<p>\nLe verrouillage optimiste n'est pas n\u00e9cessaire ici. Cette op\u00e9ration est plus d\u00e9clarative par rapport \u00e0 replace, bien que cela puisse d'abord para\u00eetre contraire.<\/p>\n<p>Ainsi :<\/p>\n<ul>\n<li> avec l'op\u00e9ration <code>create<\/code> nous cr\u00e9ons un objet \u00e0 partir du manifeste de Git,<\/li>\n<li> \u00e0 l'aide de <code>supprimer<\/code> \u2014 nous le supprimons, si l'objet n'est plus n\u00e9cessaire,<\/li>\n<li> \u00e0 l'aide de <code>patch<\/code> \u2014 nous modifions l'objet pour le mettre dans l'\u00e9tat d\u00e9crit dans Git.<\/li>\n<\/ul>\n<p>\nCependant, pour ce faire, il est n\u00e9cessaire de cr\u00e9er <i>un correctif appropri\u00e9<\/i>!<\/p>\n<h3>Comment fonctionnent les correctifs dans Helm 2 : 2-way-merge<\/h3>\n<p>\nLors de la premi\u00e8re installation d'une version, Helm effectue une op\u00e9ration <code>create<\/code> pour les ressources du chart.<\/p>\n<p>Lors de la mise \u00e0 jour d'une version, Helm pour chaque ressource :<\/p>\n<ul>\n<li> calcule le correctif entre la version de la ressource de l'ancien chart et la version actuelle du chart,<\/li>\n<li> applique ce correctif.<\/li>\n<\/ul>\n<p>\nNous appellerons ce correctif <b>le correctif 2-way-merge<\/b>, car sa cr\u00e9ation implique 2 manifestes :<\/p>\n<ul>\n<li> le manifeste de la ressource de l'ancienne version,<\/li>\n<li> le manifeste de la ressource de la version actuelle.<\/li>\n<\/ul>\n<p>\nLors de la suppression, l'op\u00e9ration <code>supprimer<\/code> dans kube apiserver est appel\u00e9e pour les ressources qui ont \u00e9t\u00e9 d\u00e9clar\u00e9es dans l'ancienne version, mais ne sont pas d\u00e9clar\u00e9es dans la version actuelle.<\/p>\n<p>L'approche avec le correctif 2-way-merge a un probl\u00e8me : elle entra\u00eene <b>une d\u00e9synchronisation entre l'\u00e9tat r\u00e9el de la ressource dans le cluster et le manifeste dans Git.<\/b>.<\/p>\n<h3>Illustration du probl\u00e8me avec un exemple<\/h3>\n<p><\/p>\n<ul>\n<li> Dans Git, le chart contient un manifeste o\u00f9 le champ <code>image<\/code> du Deployment a la valeur <code>ubuntu:18.04<\/code>.<\/li>\n<li> L'utilisateur a chang\u00e9 la valeur de ce champ en <code>kubectl edit<\/code> ubuntu:19.04 <code>Lors de la r\u00e9installation du chart Helm,<\/code>.<\/li>\n<li> aucun correctif n'est g\u00e9n\u00e9r\u00e9 <i>, car le champ<\/i>dans la version pr\u00e9c\u00e9dente de la version et dans le chart actuel sont identiques. <code>image<\/code> Apr\u00e8s la r\u00e9installation,<\/li>\n<li> il reste <code>image<\/code> , bien que le chart indique <code>Lors de la r\u00e9installation du chart Helm,<\/code>Nous avons obtenu une d\u00e9synchronisation et perdu la d\u00e9clarativit\u00e9. <code>ubuntu:18.04<\/code>.<\/li>\n<\/ul>\n<p>\nQu'est-ce qu'une ressource synchronis\u00e9e ?<\/p>\n<h3>En g\u00e9n\u00e9ral,<\/h3>\n<p>\nil est impossible d'obtenir une <i>correspondance compl\u00e8te<\/i> entre le manifeste de la ressource dans le cluster en fonctionnement et le manifeste de Git. Car dans le manifeste r\u00e9el, il peut y avoir des annotations\/labels de service, des conteneurs suppl\u00e9mentaires et d'autres donn\u00e9es ajout\u00e9es et supprim\u00e9es dynamiquement par certains contr\u00f4leurs. Ces donn\u00e9es, nous ne pouvons pas et ne voulons pas les garder dans Git. Cependant, nous voulons que lors du d\u00e9ploiement, les champs que nous avons explicitement sp\u00e9cifi\u00e9s dans Git prennent des valeurs correspondantes.<\/p>\n<p>On obtient donc cette r\u00e8gle g\u00e9n\u00e9rale <b>d'une ressource synchronis\u00e9e<\/b>: lors du d\u00e9ploiement d'une ressource, il est possible de modifier ou de supprimer uniquement les champs qui sont explicitement indiqu\u00e9s dans le manifeste de Git (ou qui ont \u00e9t\u00e9 indiqu\u00e9s dans la version pr\u00e9c\u00e9dente, mais maintenant supprim\u00e9s).<\/p>\n<h3>3-way-merge patch<\/h3>\n<p>\nL'id\u00e9e principale <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Merge_(version_control)#Three-way_merge\">3-way-merge patch<\/a><\/noindex>: g\u00e9n\u00e8re un correctif entre la derni\u00e8re version appliqu\u00e9e du manifeste de Git et la version cible du manifeste de Git, en tenant compte de la version actuelle du manifeste dans le cluster en fonctionnement. Le correctif final doit respecter la r\u00e8gle de la ressource synchronis\u00e9e :<\/p>\n<ul>\n<li> Les nouveaux champs ajout\u00e9s \u00e0 la version cible sont int\u00e9gr\u00e9s via un patch;<\/li>\n<li> Les champs pr\u00e9c\u00e9demment existants dans la derni\u00e8re version appliqu\u00e9e et qui n'existent pas dans la cible sont remis \u00e0 z\u00e9ro via un patch;<\/li>\n<li> Les champs de la version actuelle de l'objet, qui diff\u00e8rent de la version cible du manifeste, sont mis \u00e0 jour via un patch.<\/li>\n<\/ul>\n<p>\nC'est exactement selon ce principe que les patches sont g\u00e9n\u00e9r\u00e9s. <code>kubectl apply<\/code>:<\/p>\n<ul>\n<li> La derni\u00e8re version appliqu\u00e9e du manifeste est conserv\u00e9e dans l'annotation de l'objet lui-m\u00eame, <\/li>\n<li> la cible est extraite du fichier YAML sp\u00e9cifi\u00e9,<\/li>\n<li> la version actuelle provient du cluster en fonctionnement.<\/li>\n<\/ul>\n<p>\nMaintenant que nous avons compris la th\u00e9orie, il est temps de parler de ce que nous avons fait dans werf.<\/p>\n<h2>Application des changements dans werf<\/h2>\n<p>\nAuparavant, werf, tout comme Helm 2, utilisait des patches de fusion \u00e0 deux voies.<\/p>\n<h3>Patch de r\u00e9paration<\/h3>\n<p>\nPour passer \u00e0 un nouveau type de patches \u2014 fusion \u00e0 trois voies \u2014 la premi\u00e8re \u00e9tape a \u00e9t\u00e9 d'introduire ce que l'on appelle des <b>patches de r\u00e9paration.<\/b>.<\/p>\n<p>Lors du d\u00e9ploiement, un patch de fusion \u00e0 deux voies standard est utilis\u00e9, mais werf g\u00e9n\u00e8re en plus un patch qui synchronise l'\u00e9tat r\u00e9el de la ressource avec ce qui est \u00e9crit dans Git (ce patch est cr\u00e9\u00e9 en utilisant la m\u00eame r\u00e8gle de ressource synchronis\u00e9e d\u00e9crite ci-dessus).<\/p>\n<p>En cas de d\u00e9synchronisation, \u00e0 la fin du d\u00e9ploiement, l'utilisateur re\u00e7oit un AVERTISSEMENT avec un message correspondant et un patch qui doit \u00eatre appliqu\u00e9 pour ramener la ressource \u00e0 un \u00e9tat synchronis\u00e9. Ce patch est \u00e9galement not\u00e9 dans une annotation sp\u00e9ciale <code>werf.io\/repair-patch<\/code>. Il est pr\u00e9vu que l'utilisateur <b>lui-m\u00eame<\/b> applique ce patch : werf ne l'appliquera pas en principe.<\/p>\n<p>La g\u00e9n\u00e9ration de patches de r\u00e9paration est une mesure temporaire qui permet de tester la cr\u00e9ation de patches selon le principe de la fusion \u00e0 trois voies, mais sans appliquer automatiquement ces patches. Actuellement, ce mode de fonctionnement est activ\u00e9 par d\u00e9faut.<\/p>\n<h3>Patch de fusion \u00e0 trois voies uniquement pour les nouvelles versions<\/h3>\n<p>\n\u00c0 partir du 1er d\u00e9cembre 2019, les versions beta et alpha de werf commencent <b>par d\u00e9faut<\/b> \u00e0 utiliser des patches de fusion \u00e0 trois voies complets pour l'application des changements uniquement pour les nouvelles versions Helm d\u00e9ploy\u00e9es via werf. Les versions existantes continueront \u00e0 utiliser l'approche avec des patches de fusion \u00e0 deux voies et des patches de r\u00e9paration.<\/p>\n<p>Ce mode de fonctionnement peut \u00eatre activ\u00e9 explicitement par la configuration <code>WERF_THREE_WAY_MERGE_MODE=onlyNewReleases<\/code> d\u00e8s maintenant.<\/p>\n<p><i><b>Remarque<\/b>: la fonctionnalit\u00e9 a \u00e9t\u00e9 introduite dans werf au fil de plusieurs versions : dans le canal alpha, elle est devenue pr\u00eate avec la version <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/werf\/releases\/tag\/v1.0.5-alpha.19\">v1.0.5-alpha.19<\/a><\/noindex>, et dans le canal beta \u2014 avec <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/werf\/releases\/tag\/v1.0.4-beta.20\">v1.0.4-beta.20<\/a><\/noindex>.<\/i><\/p>\n<h3>patch de fusion \u00e0 trois voies pour toutes les versions.<\/h3>\n<p>\n\u00c0 partir du 15 d\u00e9cembre 2019, les versions beta et alpha de werf commenceront \u00e0 utiliser par d\u00e9faut des patchs de fusion 3 voies pour appliquer des modifications \u00e0 toutes les versions.<\/p>\n<p>Ce mode de fonctionnement peut \u00eatre activ\u00e9 explicitement par la configuration <code>WERF_THREE_WAY_MERGE_MODE=enabled<\/code> d\u00e8s maintenant.<\/p>\n<h3>Comment g\u00e9rer l'autoscaling des ressources ?<\/h3>\n<p>\nDans Kubernetes, il existe deux types d'autoscaling : HPA (horizontal) et VPA (vertical).<\/p>\n<p>L'horizontal choisit automatiquement le nombre de r\u00e9plicas, le vertical d\u00e9termine la quantit\u00e9 de ressources. Tant le nombre de r\u00e9plicas que les exigences relatives aux ressources sont sp\u00e9cifi\u00e9s dans le manifeste des ressources (voir <code>spec.replicas<\/code> ou <code>spec.containers[].resources.limits.cpu<\/code>, <code>spec.containers[].resources.limits.memory<\/code> et <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/manage-compute-resources-container\/#resource-requests-and-limits-of-pod-and-container\">autres<\/a><\/noindex>).<\/p>\n<p>Probl\u00e8me : si un utilisateur configure une ressource dans le chart de mani\u00e8re \u00e0 ce que des valeurs sp\u00e9cifiques pour les ressources ou les r\u00e9plicas soient indiqu\u00e9es et que des autoscalers soient activ\u00e9s pour cette ressource, alors \u00e0 chaque d\u00e9ploiement, werf remettra ces valeurs \u00e0 celles inscrites dans le manifeste du chart.<\/p>\n<p>Il existe deux solutions au probl\u00e8me. Tout d'abord, il est pr\u00e9f\u00e9rable de ne pas indiquer explicitement les valeurs autoscalables dans le manifeste du chart. Si toutefois cette option n'est pas envisageable pour une raison ou une autre (par exemple, parce qu'il est pratique de d\u00e9finir les limites de ressources initiales et le nombre de r\u00e9plicas dans le chart), werf propose les annotations suivantes :<\/p>\n<ul>\n<li> <code>werf.io\/set-replicas-only-on-creation=true<\/code><\/li>\n<li> <code>werf.io\/set-resources-only-on-creation=true<\/code><\/li>\n<\/ul>\n<p>\nAvec cette annotation, werf ne remettra pas \u00e0 z\u00e9ro les valeurs correspondantes \u00e0 chaque d\u00e9ploiement, mais les d\u00e9finira uniquement lors de la cr\u00e9ation initiale de la ressource.<\/p>\n<p>Pour plus de d\u00e9tails, voir la documentation du projet sur <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/resources_update_methods_and_adoption.html#deal-with-hpa\">HPA<\/a><\/noindex> et <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/resources_update_methods_and_adoption.html#deal-with-vpa\">VPA<\/a><\/noindex>.<\/p>\n<h3>Interdire l'utilisation des patchs de fusion 3 voies<\/h3>\n<p>\nPour l'instant, l'utilisateur peut interdire l'utilisation des nouveaux patchs dans werf \u00e0 l'aide de la variable d'environnement <code>WERF_THREE_WAY_MERGE_MODE=disabled<\/code>. Cependant, \u00e0 partir <b>du 1er mars 2020, cette interdiction cessera d'\u00eatre effective<\/b> et seuls des patchs de fusion 3 voies seront utilisables.<\/p>\n<h2>Adoption des ressources dans werf<\/h2>\n<p>\nLa ma\u00eetrise de la m\u00e9thode d'application des modifications par patchs de fusion 3 voies nous a permis de mettre en \u0153uvre imm\u00e9diatement une fonctionnalit\u00e9 telle que l'adoption des ressources existantes dans le cluster dans un Helm release.<\/p>\n<p>Helm 2 a un probl\u00e8me : on ne peut pas ajouter dans les manifestes du chart une ressource qui existe d\u00e9j\u00e0 dans le cluster sans recr\u00e9er cette ressource de z\u00e9ro (voir <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/helm\/helm\/issues\/6031#issuecomment-531579500\">#6031<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/helm\/helm\/issues\/3275\">#3275<\/a><\/noindex>). Nous avons appris \u00e0 werf \u00e0 accepter les ressources existantes dans le release. Pour cela, vous devez ajouter \u00e0 la version actuelle de la ressource du cluster en fonctionnement une annotation (par exemple, \u00e0 l'aide de <code>kubectl edit<\/code>):<\/p>\n<pre><code class=\"plaintext\">\"werf.io\/allow-adoption-by-release\": RELEASE_NAME<\/code><\/pre>\n<p>\nVous devez maintenant d\u00e9crire la ressource dans le chart et lors du prochain d\u00e9ploiement avec werf de la version portant le nom correspondant, la ressource existante sera accept\u00e9e dans cette version et restera sous sa gestion. De plus, au cours de l'adoption de la ressource dans la version, werf mettra l'\u00e9tat actuel de la ressource \u00e0 partir du cluster fonctionnel dans l'\u00e9tat d\u00e9crit dans le chart, en utilisant les m\u00eames patches de fusion \u00e0 3 voies et la r\u00e8gle de ressource synchronis\u00e9e.<\/p>\n<p><i><b>Remarque<\/b>: configuration <code>WERF_THREE_WAY_MERGE_MODE<\/code> n'affecte pas l'adoption des ressources \u2014 en cas d'adoption, un patch de fusion \u00e0 3 voies est toujours utilis\u00e9.<\/i><\/p>\n<p>Les d\u00e9tails sont dans <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/resources_update_methods_and_adoption.html#resources-adoption\">documentation<\/a><\/noindex>.<\/p>\n<h2>Conclusions et plans futurs<\/h2>\n<p>\nJ'esp\u00e8re qu'apr\u00e8s cet article, il est devenu plus clair ce que sont les patches de fusion \u00e0 3 voies et pourquoi ils ont \u00e9t\u00e9 introduits. D'un point de vue pratique, le d\u00e9veloppement de werf a vu leur mise en \u0153uvre comme une \u00e9tape suppl\u00e9mentaire vers l'am\u00e9lioration du d\u00e9ploiement similaire \u00e0 Helm. On peut d\u00e9sormais oublier les probl\u00e8mes de synchronisation de la configuration qui se produisaient souvent avec Helm 2. En parall\u00e8le, une nouvelle fonctionnalit\u00e9 utile d'adoption des ressources Kubernetes d\u00e9j\u00e0 r\u00e9cup\u00e9r\u00e9es dans les releases Helm a \u00e9t\u00e9 ajout\u00e9e.<\/p>\n<p>Dans le d\u00e9ploiement similaire \u00e0 Helm, certaines probl\u00e9matiques et difficult\u00e9s demeurent, telles que l'utilisation de mod\u00e8les Go, et nous continuerons \u00e0 les r\u00e9soudre.<\/p>\n<p>Des informations sur les m\u00e9thodes de mise \u00e0 jour des ressources et d'adoption sont \u00e9galement disponibles sur <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/resources_update_methods_and_adoption.html\">cette page de documentation<\/a><\/noindex>.<\/p>\n<h3>Helm 3<\/h3>\n<p>\nIl convient de noter s\u00e9par\u00e9ment <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/news\/t\/475722\/\">la nouvelle version majeure de Helm \u2014 v3, \u2014 qui utilise \u00e9galement des patches de fusion \u00e0 3 voies et \u00e9limine Tiller. Cette nouvelle version d'Helm n\u00e9cessite<\/a><\/noindex> une migration <noindex><a rel=\"nofollow\" href=\"https:\/\/helm.sh\/docs\/topics\/v2_v3_migration\/\">des installations existantes pour les convertir au nouveau format de stockage des releases.<\/a><\/noindex> Werf, de son c\u00f4t\u00e9, s'est d\u00e9j\u00e0 d\u00e9barrass\u00e9 de l'utilisation de Tiller, a opt\u00e9 pour la fusion \u00e0 3 voies et ajout\u00e9<\/p>\n<p>beaucoup d'autres fonctionnalit\u00e9s <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/differences_with_helm.html\">, tout en restant compatible avec les installations existantes sur Helm 2 (aucun script de migration n'est n\u00e9cessaire). Par cons\u00e9quent, tant que werf n'est pas pass\u00e9 \u00e0 Helm 3, les utilisateurs de werf ne perdent pas les principaux avantages de Helm 3 par rapport \u00e0 Helm 2 (ceux-ci sont \u00e9galement pr\u00e9sents dans werf).<\/a><\/noindex>Cependant, la transition de werf vers le code de Helm 3 est in\u00e9vitable et se produira dans un avenir proche. Cela devrait se faire lors des versions werf 1.1 ou 1.2 (actuellement, la version principale de werf est 1.0 ; pour plus de d\u00e9tails sur le syst\u00e8me de versionnage de werf, voir<\/p>\n<p>). D'ici l\u00e0, Helm 3 devrait avoir stabilis\u00e9. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/werf#backward-compatibility-promise\">ici<\/a><\/noindex>Cycle de notes sur les nouvelles fonctionnalit\u00e9s dans werf :<\/p>\n<h2>P.S.<\/h2>\n<p>\nLisez aussi dans notre blog :<\/p>\n<ul>\n<li> Utilisation de werf pour le d\u00e9ploiement de charts Helm complexes\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/468049\/\">Utilisation de werf pour le d\u00e9ploiement de charts Helm complexes<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/465131\/\">Support monorepo et multirepo dans werf et quel rapport avec Docker Registry<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/463613\/\">Il est d\u00e9sormais possible de cr\u00e9er des images Docker dans werf en utilisant un Dockerfile classique.<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/460351\/\">werf est notre outil pour CI\/CD dans Kubernetes (aper\u00e7u et vid\u00e9o de la pr\u00e9sentation).<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/469541\/\">Construction et d\u00e9ploiement de microservices similaires avec werf et GitLab CI.<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/453734\/\">Introduction \u00e0 Helm 3.<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/476646\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0421\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u043e, \u0447\u0435\u0433\u043e \u043c\u044b (\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u044b) \u0434\u043e\u043b\u0433\u043e \u0436\u0434\u0430\u043b\u0438: werf, \u043d\u0430\u0448\u0430 Open Source-\u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u0438\u0445 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0432 Kubernetes, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e 3-way-merge-\u043f\u0430\u0442\u0447\u0435\u0439! \u0412 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u044d\u0442\u043e\u043c\u0443, \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c adoption\u2019\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 K8s-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0432 Helm-\u0440\u0435\u043b\u0438\u0437\u044b \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432. \u0415\u0441\u043b\u0438 \u0441\u043e\u0432\u0441\u0435\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u043e, \u0442\u043e \u0441\u0442\u0430\u0432\u0438\u043c WERF_THREE_WAY_MERGE=enabled \u2014 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0435\u043f\u043b\u043e\u0439 \u00ab\u043a\u0430\u043a \u0432 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":53121,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-53120","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0421\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u043e, \u0447\u0435\u0433\u043e \u043c\u044b (\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u044b) \u0434\u043e\u043b\u0433\u043e \u0436\u0434\u0430\u043b\u0438: werf, \u043d\u0430\u0448\u0430 Open Source-\u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u0438\u0445 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0432 Kubernetes, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/3-way-merge-v-werf-deploj-v-kubernetes-s-helm-na-steroidah\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd473-way merge \u0432 werf: \u0434\u0435\u043f\u043b\u043e\u0439 \u0432 Kubernetes \u0441 Helm \u00ab\u043d\u0430 \u0441\u0442\u0435\u0440\u043e\u0438\u0434\u0430\u0445\u00bb | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0421\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u043e, \u0447\u0435\u0433\u043e \u043c\u044b (\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u044b) \u0434\u043e\u043b\u0433\u043e \u0436\u0434\u0430\u043b\u0438: werf, \u043d\u0430\u0448\u0430 Open Source-\u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u0438\u0445 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0432 Kubernetes, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/3-way-merge-v-werf-deploj-v-kubernetes-s-helm-na-steroidah\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-11-23T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:00:59+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47 Fusion \u00e0 3 voies dans werf : d\u00e9ploiement dans Kubernetes avec Helm \u00ab sous st\u00e9ro\u00efdes \u00bb | ProHoster","description":"C'est arriv\u00e9, ce que nous (et pas seulement nous) attendions depuis longtemps : werf, notre outil Open Source pour la construction d'applications et leur d\u00e9ploiement dans Kubernetes, prend maintenant en charge.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/3-way-merge-v-werf-deploj-v-kubernetes-s-helm-na-steroidah","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd473-way merge \u0432 werf: \u0434\u0435\u043f\u043b\u043e\u0439 \u0432 Kubernetes \u0441 Helm \u00ab\u043d\u0430 \u0441\u0442\u0435\u0440\u043e\u0438\u0434\u0430\u0445\u00bb | ProHoster","og:description":"\u0421\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u043e, \u0447\u0435\u0433\u043e \u043c\u044b (\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u044b) \u0434\u043e\u043b\u0433\u043e \u0436\u0434\u0430\u043b\u0438: werf, \u043d\u0430\u0448\u0430 Open Source-\u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 \u0438\u0445 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0432 Kubernetes, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442.","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/3-way-merge-v-werf-deploj-v-kubernetes-s-helm-na-steroidah","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-11-23T21:00:00+00:00","article:modified_time":"2020-02-18T11:00:59+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"53120","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-24 06:11:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:31:28","updated":"2026-01-24 06:11:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/53120","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=53120"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/53120\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/53121"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=53120"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=53120"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=53120"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}