{"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\/cs\/blog\/administrirovanie\/3-way-merge-v-werf-deploj-v-kubernetes-s-helm-na-steroidah","title":{"rendered":"3-way merge v werf: nasazen\u00ed do Kubernetes s Helm \"na steroidech\"","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Stalo se to, na co jsme (a nejen my) dlouho \u010dekali: <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/\">werf<\/a><\/noindex>, na\u0161e Open Source utilita pro sestaven\u00ed aplikac\u00ed a jejich nasazen\u00ed do Kubernetes nyn\u00ed podporuje aplikaci zm\u011bn pomoc\u00ed 3-way-merge patch\u016f! Krom\u011b toho jsme p\u0159idali mo\u017enost adopce st\u00e1vaj\u00edc\u00edch K8s zdroj\u016f do Helm release bez nutnosti jejich p\u0159etvo\u0159en\u00ed.<\/p>\n<p><img decoding=\"async\" alt=\"3-way merge v werf: nasazen\u00ed do Kubernetes s Helm &quot;na steroidech&quot;\" src=\"\/wp-content\/uploads\/2019\/11\/e5be3544c201f7b2c97fba216a49506d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPokud to shrneme, nastavte <code>WERF_THREE_WAY_MERGE=enabled<\/code> \u2014 obdr\u017e\u00edte nasazen\u00ed \u201ejako v <code>kubectl apply<\/code>\u201c, kompatibiln\u00ed se st\u00e1vaj\u00edc\u00edmi instalacemi na Helm 2 a je\u0161t\u011b v\u00edce.<\/p>\n<p>Ale za\u010dn\u011bme teori\u00ed: co vlastn\u011b jsou 3-way-merge patche, jak lid\u00e9 dosp\u011bli k p\u0159\u00edstupu jejich generace a pro\u010d jsou d\u016fle\u017eit\u00e9 v CI\/CD procesech s infrastrukturou postavenou na Kubernetes? A pot\u00e9 se pod\u00edv\u00e1me, co 3-way-merge v werf p\u0159edstavuje, jak\u00e9 re\u017eimy jsou implicitn\u011b pou\u017e\u00edv\u00e1ny a jak je \u0159\u00eddit.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Co je to 3-way-merge patch?<\/h2>\n<p>\nTak\u017ee za\u010dn\u011bme \u00fakolem nasazen\u00ed zdroj\u016f popsan\u00fdch v YAML manifestech do Kubernetes.<\/p>\n<p>Pro pr\u00e1ci se zdroji Kubernetes API nab\u00edz\u00ed tyto z\u00e1kladn\u00ed operace: create, patch, replace a delete. P\u0159edpokl\u00e1d\u00e1 se, \u017ee s jejich pomoc\u00ed je t\u0159eba konstruovat pohodln\u00e9 kontinu\u00e1ln\u00ed nasazen\u00ed zdroj\u016f do clusteru. Jak?<\/p>\n<h3>Imperativn\u00ed p\u0159\u00edkazy kubectl<\/h3>\n<p>\nPrvn\u00ed p\u0159\u00edstup k \u0159\u00edzen\u00ed objekt\u016f v Kubernetes je pou\u017eit\u00ed imperativn\u00edch p\u0159\u00edkaz\u016f kubectl pro vytv\u00e1\u0159en\u00ed, zm\u011bnu a odstra\u0148ov\u00e1n\u00ed t\u011bchto objekt\u016f. Jin\u00fdmi slovy:<\/p>\n<ul>\n<li> p\u0159\u00edkazem <code>kubectl run<\/code> m\u016f\u017eete spustit Deployment nebo Job:\n<pre><code class=\"bash\">kubectl run --generator=deployment\/apps.v1 DEPLOYMENT_NAME --image=IMAGE<\/code><\/pre>\n<\/li>\n<li> p\u0159\u00edkazem <code>kubectl scale<\/code> \u2014 zm\u011bnit po\u010det replik:\n<pre><code class=\"bash\">kubectl scale --replicas=3 deployment\/mysql<\/code><\/pre>\n<\/li>\n<li>atd.<\/li>\n<\/ul>\n<p>\nTento p\u0159\u00edstup se na prvn\u00ed pohled m\u016f\u017ee zd\u00e1t pohodln\u00fd. Nicm\u00e9n\u011b jsou zde probl\u00e9my: <\/p>\n<ol>\n<li> Jak t\u011b\u017ek\u00e9 je <b>automatizovat<\/b>.<\/li>\n<li> Jak <b>odrazit konfiguraci<\/b> v Gitu? Jak prov\u00e1d\u011bt revizi zm\u011bn, kter\u00e9 prob\u00edhaj\u00ed s clusterem?<\/li>\n<li> Jak zajistit <b>reprodukovatelnost<\/b> konfigurace p\u0159i restartu?<\/li>\n<li>\u2026<\/li>\n<\/ol>\n<p>\nJe jasn\u00e9, \u017ee tento p\u0159\u00edstup \u0161patn\u011b lad\u00ed s uchov\u00e1v\u00e1n\u00edm spolu s k\u00f3dem aplikace a infrastrukturou jako k\u00f3dem (IaC; nebo dokonce <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/458878\/\">GitOps<\/a><\/noindex> jako modern\u011bj\u0161\u00ed variantou, kter\u00e1 z\u00edsk\u00e1v\u00e1 popularitu v Kubernetes ekosyst\u00e9mu). Proto tyto p\u0159\u00edkazy v kubectl nedostaly dal\u0161\u00ed v\u00fdvoj.<\/p>\n<h3>Operace create, get, replace a delete<\/h3>\n<p>\nSe z\u00e1kladn\u00edm <b>vytvo\u0159en\u00edm<\/b> je to jednoduch\u00e9: ode\u0161lete manifest do operace <code>\u2013 vytvo\u0159en\u00ed instance,<\/code> u kube api a zdroj je vytvo\u0159en. YAML reprezentace manifestu m\u016f\u017ee b\u00fdt ulo\u017een na Gitu a pro vytvo\u0159en\u00ed lze pou\u017e\u00edt p\u0159\u00edkaz <code>kubectl create -f manifest.yaml<\/code>.<\/p>\n<p>S <b>odstran\u011bn\u00ed<\/b> je tak\u00e9 jednoduch\u00e9: pou\u017eijte stejn\u00fd <code>manifest.yaml<\/code> z Gitu v p\u0159\u00edkazu <code>kubectl delete -f manifest.yaml<\/code>.<\/p>\n<p>Operace <b><code>replace<\/code><\/b> umo\u017e\u0148uje \u00faplnou v\u00fdm\u011bnu konfigurace zdroje za novou, ani\u017e by bylo pot\u0159eba vytv\u00e1\u0159et nov\u00fd zdroj. To znamen\u00e1, \u017ee p\u0159ed proveden\u00edm zm\u011bny na zdroji je logick\u00e9 vy\u017e\u00e1dat si aktu\u00e1ln\u00ed verzi operac\u00ed <code>z\u00edskat<\/code>, zm\u011bnit ji a aktualizovat pomoc\u00ed operace <code>replace<\/code>. V kube apiserveru je zabudov\u00e1no <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Optimistic_concurrency_control\">optimistick\u00e9 zamyk\u00e1n\u00ed<\/a><\/noindex> , a pokud se po operaci <code>z\u00edskat<\/code> objekt zm\u011bnil, tak operace <code>replace<\/code> neprob\u011bhne.<\/p>\n<p>Abychom mohli uchov\u00e1vat konfiguraci v Gitu a aktualizovat pomoc\u00ed replace, mus\u00edme prov\u00e9st operaci <code>z\u00edskat<\/code>, slou\u010dit konfiguraci z Gitu s t\u00edm, co jsme obdr\u017eeli, a prov\u00e9st <code>replace<\/code>. Standardn\u011b kubectl umo\u017e\u0148uje pouze pou\u017e\u00edvat p\u0159\u00edkaz <code>kubectl replace -f manifest.yaml<\/code>, kde <code>manifest.yaml<\/code> \u2014 ji\u017e pln\u011b p\u0159ipraven\u00fd (v na\u0161em p\u0159\u00edpad\u011b \u2014 slou\u010den\u00fd) manifest, kter\u00fd je t\u0159eba nainstalovat. Z toho vypl\u00fdv\u00e1, \u017ee u\u017eivatel mus\u00ed realizovat slou\u010den\u00ed manifest\u016f, co\u017e je \u00fakol, kter\u00fd nen\u00ed trivi\u00e1ln\u00ed\u2026<\/p>\n<p>Tak\u00e9 je t\u0159eba poznamenat, \u017ee i kdy\u017e <code>manifest.yaml<\/code> je uchov\u00e1v\u00e1no v Gitu, nem\u016f\u017eeme p\u0159edem v\u011bd\u011bt, zda je t\u0159eba objekt vytvo\u0159it nebo aktualizovat \u2014 to mus\u00ed prov\u00e1d\u011bt u\u017eivatelsk\u00fd software.<\/p>\n<p>Celkem: <b>m\u016f\u017eeme-li budovat kontinu\u00e1ln\u00ed nasazen\u00ed<\/b> pouze pomoc\u00ed create, replace a delete, zaji\u0161\u0165uj\u00edc\u00ed uchov\u00e1v\u00e1n\u00ed konfigurace infrastruktury v Gitu spolu s k\u00f3dem a pohodln\u00fd CI\/CD?<\/p>\n<p>V z\u00e1sad\u011b m\u016f\u017eeme\u2026 K tomu <b>bude t\u0159eba realizovat operaci slou\u010den\u00ed<\/b> manifest\u016f a n\u011bjak\u00e9 obvaz, kter\u00e9:<\/p>\n<ul>\n<li> kontroluje existenci objektu v clusteru,<\/li>\n<li> prov\u00e1d\u00ed prim\u00e1rn\u00ed vytvo\u0159en\u00ed zdroje,<\/li>\n<li> aktualizuje nebo jej odstra\u0148uje.<\/li>\n<\/ul>\n<p>\nP\u0159i aktualizaci je t\u0159eba vz\u00edt v \u00favahu, \u017ee <i>zdroj se mohl zm\u011bnit<\/i> od posledn\u00edho <code>z\u00edskat<\/code> a automaticky zpracov\u00e1vat p\u0159\u00edpad optimistick\u00e9ho zamyk\u00e1n\u00ed \u2014 prov\u00e1d\u011bt opakovan\u00e9 pokusy o aktualizaci.<\/p>\n<p>Nicm\u00e9n\u011b, pro\u010d vynal\u00e9zat kolo, kdy\u017e kube-apiserver nab\u00edz\u00ed jin\u00fd zp\u016fsob, jak aktualizovat zdroje: operaci <code>patch<\/code>, kter\u00e1 u\u017eivateli odstran\u00ed \u010d\u00e1st popsan\u00fdch probl\u00e9m\u016f?<\/p>\n<h3>Patch<\/h3>\n<p>\nA jsme u patch\u016f.<\/p>\n<p>Patchy jsou hlavn\u00edm zp\u016fsobem, jak aplikovat zm\u011bny na existuj\u00edc\u00ed objekty v Kubernetes. Operace <code>patch<\/code> funguje tak, \u017ee:<\/p>\n<ul>\n<li> u\u017eivatel kube-apiserver mus\u00ed poslat patch ve form\u00e1tu JSON a uv\u00e9st objekt,<\/li>\n<li> a apiserver s\u00e1m zjist\u00ed aktu\u00e1ln\u00ed stav objektu a p\u0159ivede ho do po\u017eadovan\u00e9ho stavu.<\/li>\n<\/ul>\n<p>\nOptimistick\u00e9 zamyk\u00e1n\u00ed v tomto p\u0159\u00edpad\u011b nen\u00ed vy\u017eadov\u00e1no. Tato operace je v\u00edce deklarativn\u00ed ve srovn\u00e1n\u00ed s replace, i kdy\u017e se to na prvn\u00ed pohled m\u016f\u017ee zd\u00e1t naopak.<\/p>\n<p>T\u00edmto zp\u016fsobem:<\/p>\n<ul>\n<li> pomoc\u00ed operace <code>\u2013 vytvo\u0159en\u00ed instance,<\/code> vytv\u00e1\u0159\u00edme objekt podle manifestu z Gitu,<\/li>\n<li> prost\u0159ednictv\u00edm <code>odstranit<\/code> \u2014 odstra\u0148ujeme, pokud objekt nen\u00ed v\u00edce pot\u0159eba,<\/li>\n<li> prost\u0159ednictv\u00edm <code>patch<\/code> \u2014 m\u011bn\u00edme objekt, p\u0159iv\u00e1d\u00edme ho do podoby, jakou popisuje Git.<\/li>\n<\/ul>\n<p>\nAby to bylo mo\u017en\u00e9, je nutn\u00e9 vytvo\u0159it <i>spr\u00e1vn\u00fd patch<\/i>!<\/p>\n<h3>Jak funguj\u00ed patche v Helmu 2: dvoucestn\u00e9 slou\u010den\u00ed<\/h3>\n<p>\nP\u0159i prvn\u00ed instalaci vyd\u00e1n\u00ed Helm prov\u00e1d\u00ed operaci <code>\u2013 vytvo\u0159en\u00ed instance,<\/code> pro zdroje chartu.<\/p>\n<p>P\u0159i aktualizaci vyd\u00e1n\u00ed Helm pro ka\u017ed\u00fd zdroj:<\/p>\n<ul>\n<li> zjist\u00ed patch mezi verz\u00ed zdroje z p\u0159edchoz\u00edho chartu a aktu\u00e1ln\u00ed verz\u00ed chartu,<\/li>\n<li> aplikuje tento patch.<\/li>\n<\/ul>\n<p>\nTakov\u00fd patch naz\u00fdv\u00e1me <b>dvoucestn\u00fdm slou\u010den\u00edm<\/b>, proto\u017ee p\u0159i jeho tvorb\u011b se pod\u00edlej\u00ed 2 manifesty:<\/p>\n<ul>\n<li> manifest zdroje z p\u0159edchoz\u00edho vyd\u00e1n\u00ed,<\/li>\n<li> manifest zdroje z aktu\u00e1ln\u00edho zdroje.<\/li>\n<\/ul>\n<p>\nP\u0159i odstran\u011bn\u00ed se operace <code>odstranit<\/code> v kube apiserveru vol\u00e1 pro zdroje, kter\u00e9 byly deklarov\u00e1ny v minul\u00e9m vyd\u00e1n\u00ed, ale nejsou uvedeny v aktu\u00e1ln\u00edm.<\/p>\n<p>P\u0159\u00edstup s dvoucestn\u00fdm slou\u010den\u00edm m\u00e1 probl\u00e9m: vede k <b>desynchronizaci skute\u010dn\u00e9ho stavu zdroje v clusteru a manifestu v Gitu<\/b>.<\/p>\n<h3>Ilustrace probl\u00e9mu na p\u0159\u00edkladu<\/h3>\n<p><\/p>\n<ul>\n<li> V Gitu, v chartu se nach\u00e1z\u00ed manifest, v n\u011bm\u017e pole <code>obr\u00e1zek<\/code> u nasazen\u00ed m\u00e1 hodnotu <code>ubuntu:18.04<\/code>.<\/li>\n<li> U\u017eivatel prost\u0159ednictv\u00edm <code>kubectl edit<\/code> zm\u011bnil hodnotu tohoto pole na <code>ubuntu:19.04<\/code>.<\/li>\n<li> P\u0159i op\u011btovn\u00e9m nasazen\u00ed chartu Helm <i>negeneruje patch<\/i>, proto\u017ee pole <code>obr\u00e1zek<\/code> v p\u0159edchoz\u00ed verzi vyd\u00e1n\u00ed a v aktu\u00e1ln\u00edm chartu jsou stejn\u00e1.<\/li>\n<li> Po op\u011btovn\u00e9m nasazen\u00ed <code>obr\u00e1zek<\/code> z\u016fst\u00e1v\u00e1 <code>ubuntu:19.04<\/code>, i kdy\u017e v chartu je naps\u00e1no <code>ubuntu:18.04<\/code>.<\/li>\n<\/ul>\n<p>\nDostali jsme desynchronizaci a ztr\u00e1tu deklarativnosti.<\/p>\n<h3>Co je to synchronizovan\u00fd zdroj?<\/h3>\n<p>\nObecn\u011b \u0159e\u010deno, <i>\u00dapln\u00e9<\/i> shodov\u00e1n\u00ed manifestu zdroje v b\u011b\u017e\u00edc\u00edm clusteru a manifestu z Gitu nen\u00ed mo\u017en\u00e9. Proto\u017ee v re\u00e1ln\u00e9m manifestu mohou b\u00fdt servisn\u00ed anotace\/\u0161t\u00edtky, dal\u0161\u00ed kontejnery a dal\u0161\u00ed data, kter\u00e1 jsou dynamicky p\u0159id\u00e1v\u00e1na a odstra\u0148ov\u00e1na z zdroje n\u011bjak\u00fdmi controllery. Tato data nem\u016f\u017eeme a ani nechceme m\u00edt v Git. Nicm\u00e9n\u011b chceme, aby p\u0159i nasazen\u00ed ta pole, kter\u00e1 jsme v\u00fdslovn\u011b uvedli v Git, p\u0159ij\u00edmala odpov\u00eddaj\u00edc\u00ed hodnoty.<\/p>\n<p>Vznik\u00e1 tedy takov\u00e9 obecn\u00e9 <b>pravidlo synchronizovan\u00e9ho zdroje<\/b>: p\u0159i nasazen\u00ed zdroje lze m\u011bnit nebo odstra\u0148ovat pouze ta pole, kter\u00e1 jsou v\u00fdslovn\u011b uvedena v manifestu z Gitu (nebo byla uvedena v p\u0159edchoz\u00ed verzi a nyn\u00ed byla odstran\u011bna).<\/p>\n<h3>t\u0159\u00edcestn\u00e9 slou\u010den\u00ed<\/h3>\n<p>\nHlavn\u00ed my\u0161lenka <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Merge_(version_control)#Three-way_merge\">t\u0159\u00edcestn\u00e9 slou\u010den\u00ed<\/a><\/noindex>: generujeme patch mezi posledn\u00ed aplikovanou verz\u00ed manifestu z Gitu a c\u00edlovou verz\u00ed manifestu z Gitu s ohledem na aktu\u00e1ln\u00ed verzi manifestu z b\u011b\u017e\u00edc\u00edho clusteru. Kone\u010dn\u00fd patch by m\u011bl vyhovovat pravidlu synchronizovan\u00e9ho zdroje:<\/p>\n<ul>\n<li> nov\u00e1 pole, p\u0159idan\u00e1 v c\u00edlov\u00e9 verzi, jsou p\u0159id\u00e1na pomoc\u00ed patch.<\/li>\n<li> d\u0159\u00edve existuj\u00edc\u00ed pole ve posledn\u00ed aplikovan\u00e9 verzi a neexistuj\u00edc\u00ed v c\u00edlov\u00e9 \u2014 se nuluj\u00ed pomoc\u00ed patche;<\/li>\n<li> pole v aktu\u00e1ln\u00ed verzi objektu, kter\u00e1 se li\u0161\u00ed od c\u00edlov\u00e9 verze manifestu, \u2014 se aktualizuj\u00ed pomoc\u00ed patche.<\/li>\n<\/ul>\n<p>\nPodle tohoto principu se generuj\u00ed patche <code>kubectl apply<\/code>:<\/p>\n<ul>\n<li> posledn\u00ed aplikovan\u00e1 verze manifestu se ukl\u00e1d\u00e1 v anotaci samotn\u00e9ho objektu, <\/li>\n<li> c\u00edlov\u00e1 \u2014 se bere z ur\u010den\u00e9ho souboru YAML,<\/li>\n<li> aktu\u00e1ln\u00ed \u2014 z b\u011b\u017e\u00edc\u00edho clusteru.<\/li>\n<\/ul>\n<p>\nNyn\u00ed, kdy\u017e jsme si vysv\u011btlili teorii, je \u010das \u0159\u00edci, co jsme ud\u011blali v werf.<\/p>\n<h2>Aplikace zm\u011bn v werf<\/h2>\n<p>\nD\u0159\u00edve werf, stejn\u011b jako Helm 2, pou\u017eil patche typu 2-way-merge.<\/p>\n<h3>Repair patch<\/h3>\n<p>\nAbychom p\u0159e\u0161li na nov\u00fd typ patch\u016f \u2014 3-way-merge, prvn\u00edm krokem jsme zavedli takzvan\u00e9 <b>repair-patche<\/b>.<\/p>\n<p>P\u0159i nasazen\u00ed se pou\u017e\u00edv\u00e1 standardn\u00ed patch typu 2-way-merge, ale werf nav\u00edc generuje takov\u00fd patch, kter\u00fd by synchronizoval aktu\u00e1ln\u00ed stav zdroje s t\u00edm, co je naps\u00e1no v Git (takov\u00fd patch se vytv\u00e1\u0159\u00ed podle stejn\u00fdch pravidel synchronizovan\u00e9ho zdroje, jak bylo pops\u00e1no v\u00fd\u0161e).<\/p>\n<p>V p\u0159\u00edpad\u011b, \u017ee dojde k desynchronizaci, na konci nasazen\u00ed u\u017eivatel obdr\u017e\u00ed WARNING s odpov\u00eddaj\u00edc\u00ed zpr\u00e1vou a patchem, kter\u00fd je t\u0159eba aplikovat, aby se zdroj dostal do synchronizovan\u00e9ho stavu. Tento patch se tak\u00e9 zapisuje do speci\u00e1ln\u00ed anotace <code>werf.io\/repair-patch<\/code>. P\u0159edpokl\u00e1d\u00e1 se, \u017ee u\u017eivatel ru\u010dn\u011b <b>s\u00e1m<\/b> aplikuje tento patch: werf jej principi\u00e1ln\u011b aplikovat nebude.<\/p>\n<p>Generov\u00e1n\u00ed repair-patch\u016f je do\u010dasn\u00e9 opat\u0159en\u00ed, kter\u00e9 umo\u017e\u0148uje v praxi vyzkou\u0161et vytv\u00e1\u0159en\u00ed patch\u016f podle principu 3-way-merge, ale automaticky tyto patche neuplat\u0148ovat. V sou\u010dasn\u00e9 dob\u011b je tento pracovn\u00ed re\u017eim ve v\u00fdchoz\u00edm nastaven\u00ed zapnut.<\/p>\n<h3>3-way-merge patch pouze pro nov\u00e9 release<\/h3>\n<p>\nOd 1. prosince 2019 beta- a alpha-verze werf za\u010d\u00ednaj\u00ed <b>ve v\u00fdchoz\u00edm nastaven\u00ed<\/b> pou\u017e\u00edvat plnohodnotn\u00e9 3-way-merge-patche pro aplikaci zm\u011bn pouze pro nov\u00e9 releasy Helm, kter\u00e9 jsou nasazov\u00e1ny prost\u0159ednictv\u00edm werf. Ji\u017e existuj\u00edc\u00ed releasy budou pokra\u010dovat v pou\u017e\u00edv\u00e1n\u00ed p\u0159\u00edstupu s 2-way-merge + repair-patchy.<\/p>\n<p>Tento pracovn\u00ed re\u017eim lze v\u00fdslovn\u011b aktivovat nastaven\u00edm <code>WERF_THREE_WAY_MERGE_MODE=onlyNewReleases<\/code> u\u017e nyn\u00ed.<\/p>\n<p><i><b>Pozn\u00e1mka<\/b>: funkce se objevovala v werf b\u011bhem n\u011bkolika releas\u016f: v alpha kan\u00e1lu byla p\u0159ipravena od verze <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/werf\/releases\/tag\/v1.0.5-alpha.19\">v1.0.5-alpha.19<\/a><\/noindex>, a v beta kan\u00e1lu \u2014 od <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>3-way-merge patch pro v\u0161echny releasy<\/h3>\n<p>\nOd 15. prosince 2019 beta a alpha verze werf za\u010dnou pou\u017e\u00edvat plnohodnotn\u00e9 3-way-merge patche pro aplikaci zm\u011bn pro v\u0161echny verze.<\/p>\n<p>Tento pracovn\u00ed re\u017eim lze v\u00fdslovn\u011b aktivovat nastaven\u00edm <code>WERF_THREE_WAY_MERGE_MODE=enabled<\/code> u\u017e nyn\u00ed.<\/p>\n<h3>Jak to bude s autom\u011b\u0159en\u00edm zdroj\u016f?<\/h3>\n<p>\nV Kubernetes existuj\u00ed 2 typy autom\u011b\u0159en\u00ed: HPA (horizont\u00e1ln\u00ed) a VPA (vertik\u00e1ln\u00ed).<\/p>\n<p>Horizont\u00e1ln\u00ed automaticky vyb\u00edr\u00e1 po\u010det replik, vertik\u00e1ln\u00ed \u2014 mno\u017estv\u00ed zdroj\u016f. Jak po\u010det replik, tak po\u017eadavky na zdroje jsou uvedeny v manifestu zdroje (viz <code>spec.replicas<\/code> nebo <code>spec.containers[].resources.limits.cpu<\/code>, <code>spec.containers[].resources.limits.memory<\/code> a <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/manage-compute-resources-container\/#resource-requests-and-limits-of-pod-and-container\">dal\u0161\u00ed<\/a><\/noindex>).<\/p>\n<p>Probl\u00e9m: pokud si u\u017eivatel nakonfiguruje zdroj v chartu tak, \u017ee v n\u011bm budou uvedeny konkr\u00e9tn\u00ed hodnoty pro zdroje nebo repliky, a pro tento zdroj budou povoleni autoscale\u0159i, pak p\u0159i ka\u017ed\u00e9m nasazen\u00ed werf resetuje tyto hodnoty na to, co je zaps\u00e1no v manifestu chartu.<\/p>\n<p>Existuj\u00ed dv\u011b \u0159e\u0161en\u00ed pro tento probl\u00e9m. Nejprve je nejlep\u0161\u00ed se z\u0159eknout jasn\u00e9ho uveden\u00ed automatizovan\u011b m\u011b\u0159iteln\u00fdch hodnot v manifestu chartu. Pokud tento variant z jak\u00fdchkoli d\u016fvod\u016f nen\u00ed vhodn\u00fd (nap\u0159\u00edklad proto\u017ee je v chartu pohodln\u00e9 nastavit po\u010d\u00e1te\u010dn\u00ed limity zdroj\u016f a po\u010det replik), werf nab\u00edz\u00ed n\u00e1sleduj\u00edc\u00ed anotace:<\/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>\nPokud je takov\u00e1 anotace p\u0159\u00edtomna, werf nebude resetovat odpov\u00eddaj\u00edc\u00ed hodnoty p\u0159i ka\u017ed\u00e9m nasazen\u00ed, ale pouze je nastav\u00ed p\u0159i prvotn\u00edm vytvo\u0159en\u00ed zdroje.<\/p>\n<p>V\u00edce informac\u00ed \u2014 viz dokumentace projektu k <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/resources_update_methods_and_adoption.html#deal-with-hpa\">HPA<\/a><\/noindex> a <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>Zak\u00e1zat pou\u017e\u00edv\u00e1n\u00ed 3-way-merge patch<\/h3>\n<p>\nU\u017eivatel m\u016f\u017ee prozat\u00edm zak\u00e1zat pou\u017e\u00edv\u00e1n\u00ed nov\u00fdch patch\u016f v werf pomoc\u00ed prom\u011bnn\u00e9 prost\u0159ed\u00ed <code>WERF_THREE_WAY_MERGE_MODE=disabled<\/code>. Nicm\u00e9n\u011b od <b>1. b\u0159ezna 2020 tento z\u00e1kaz p\u0159estane platit<\/b> a bude mo\u017en\u00e9 pou\u017e\u00edvat pouze 3-way-merge patche.<\/p>\n<h2>Adopce zdroj\u016f v werf<\/h2>\n<p>\nOsvojen\u00ed metody aplikace zm\u011bn 3-way-merge patche n\u00e1m umo\u017enilo okam\u017eit\u011b implementovat funkci adopce existuj\u00edc\u00edch zdroj\u016f v clusterech do Helm release.<\/p>\n<p>Helm 2 m\u00e1 probl\u00e9m: nelze p\u0159idat do manifest\u016f chartu zdroj, kter\u00fd ji\u017e existuje v clusteru, bez jeho kompletn\u00edho znovu vytvo\u0159en\u00ed (viz <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>). Nau\u010dili jsme werf p\u0159ij\u00edmat existuj\u00edc\u00ed zdroje do release. K tomu je pot\u0159eba nastavit na aktu\u00e1ln\u00ed verzi zdroje z b\u011b\u017e\u00edc\u00edho clustera anotaci (nap\u0159\u00edklad pomoc\u00ed <code>kubectl edit<\/code>):<\/p>\n<pre><code class=\"plaintext\">\"werf.io\/allow-adoption-by-release\": RELEASE_NAME<\/code><\/pre>\n<p>\nNyn\u00ed je t\u0159eba popsat zdroj v chart\u011b a p\u0159i p\u0159\u00ed\u0161t\u00edm nasazen\u00ed s werf releasem s odpov\u00eddaj\u00edc\u00edm n\u00e1zvem bude existuj\u00edc\u00ed zdroj p\u0159ijat do tohoto releasu a z\u016fstane pod jeho spr\u00e1vou. Nav\u00edc, b\u011bhem procesu p\u0159ijet\u00ed zdroje do releasu werf p\u0159ivede aktu\u00e1ln\u00ed stav zdroje z funk\u010dn\u00edho clusteru do stavu, popsan\u00e9ho v chart\u011b, pomoc\u00ed stejn\u00fdch patch\u016f 3-way-merge a pravidel synchronizovan\u00e9ho zdroje.<\/p>\n<p><i><b>Pozn\u00e1mka<\/b>: nastaven\u00ed <code>WERF_THREE_WAY_MERGE_MODE<\/code> nem\u00e1 vliv na adopci zdroj\u016f \u2014 v p\u0159\u00edpad\u011b adopce se v\u017edy pou\u017e\u00edv\u00e1 patch 3-way-merge.<\/i><\/p>\n<p>Podrobnosti \u2014 v <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/resources_update_methods_and_adoption.html#resources-adoption\">dokumentaci<\/a><\/noindex>.<\/p>\n<h2>Z\u00e1v\u011bry a dal\u0161\u00ed pl\u00e1ny<\/h2>\n<p>\nDouf\u00e1m, \u017ee po tomto \u010dl\u00e1nku je jasn\u011bj\u0161\u00ed, co jsou 3-way-merge patche a pro\u010d k nim do\u0161lo. Z praktick\u00e9ho hlediska v\u00fdvoje projektu werf se jejich implementace stala dal\u0161\u00edm krokem sm\u011brem k vylep\u0161en\u00ed nasazen\u00ed podobn\u00e9ho Helm. Nyn\u00ed lze zapomenout na probl\u00e9my se synchronizac\u00ed konfigurace, kter\u00e9 \u010dasto nast\u00e1valy p\u0159i pou\u017e\u00edv\u00e1n\u00ed Helm 2. Sou\u010dasn\u011b byla p\u0159id\u00e1na nov\u00e1 u\u017eite\u010dn\u00e1 funkce adopce ji\u017e sta\u017een\u00fdch Kubernetes zdroj\u016f do Helm releasu.<\/p>\n<p>V nasazen\u00ed podobn\u00e9m Helmu st\u00e1le z\u016fst\u00e1vaj\u00ed n\u011bkter\u00e9 probl\u00e9my a pot\u00ed\u017ee, jako je pou\u017e\u00edv\u00e1n\u00ed Go \u0161ablon, a budeme je i nad\u00e1le \u0159e\u0161it.<\/p>\n<p>Informace o metod\u00e1ch aktualizace zdroj\u016f a adopci lze tak\u00e9 nal\u00e9zt na <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/resources_update_methods_and_adoption.html\">t\u00e9to str\u00e1nce dokumentace<\/a><\/noindex>.<\/p>\n<h3>Helm 3<\/h3>\n<p>\nSamostatn\u00e9 zm\u00ednky si zaslou\u017e\u00ed <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/news\/t\/475722\/\">nov\u011b vydan\u00e1<\/a><\/noindex> doslova p\u0159ed n\u011bkolika dny nov\u00e1 major verze Helmu \u2014 v3, \u2014 kter\u00e1 tak\u00e9 pou\u017e\u00edv\u00e1 3-way-merge patche a zbavuje se Tillera. Nov\u00e1 verze Helmu vy\u017eaduje <noindex><a rel=\"nofollow\" href=\"https:\/\/helm.sh\/docs\/topics\/v2_v3_migration\/\">migraci<\/a><\/noindex> ji\u017e existuj\u00edc\u00ed instalace, kter\u00e9 je t\u0159eba p\u0159ev\u00e9st do nov\u00e9ho form\u00e1tu ulo\u017een\u00ed releas\u016f.<\/p>\n<p>Werf se z jeho strany prozat\u00edm ji\u017e zbavil pou\u017e\u00edv\u00e1n\u00ed Tillera, p\u0159e\u0161el na 3-way-merge a p\u0159idal <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/differences_with_helm.html\">mnoho dal\u0161\u00edch<\/a><\/noindex>, p\u0159i\u010dem\u017e z\u016fstal kompatibiln\u00ed s ji\u017e existuj\u00edc\u00edmi instalacemi na Helmu 2 (nen\u00ed t\u0159eba vykon\u00e1vat \u017e\u00e1dn\u00e9 migra\u010dn\u00ed skripty). Tak\u017ee, dokud werf nep\u0159ejde na Helm 3, u\u017eivatel\u00e9 werf neztr\u00e1cej\u00ed hlavn\u00ed v\u00fdhody Helmu 3 ve srovn\u00e1n\u00ed s Helm 2 (ty jsou tak\u00e9 p\u0159\u00edtomny ve werfu).<\/p>\n<p>Nicm\u00e9n\u011b, p\u0159echod werfu na k\u00f3dovou z\u00e1kladnu Helmu 3 je nevyhnuteln\u00fd a uskute\u010dn\u00ed se v bl\u00edzk\u00e9 budoucnosti. P\u0159edpokl\u00e1d\u00e1 se, \u017ee bude werf 1.1 nebo werf 1.2 (v sou\u010dasnosti je hlavn\u00ed verz\u00ed werfu \u2014 1.0; podrobnosti o verzi werfu viz <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/werf#backward-compatibility-promise\">zde<\/a><\/noindex>). B\u011bhem t\u00e9to doby stihne Helm 3 stabilizovat.<\/p>\n<h2>P.S.<\/h2>\n<p>\nP\u0159e\u010dt\u011bte si tak\u00e9 n\u00e1\u0161 blog:<\/p>\n<ul>\n<li> Cyklus pozn\u00e1mek o nov\u00fdch funkc\u00edch ve werf:\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/468049\/\">Pou\u017eit\u00ed werf pro nasazen\u00ed komplexn\u00edch Helm chart\u016f<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/465131\/\">Podpora monorepo a multirepo v werf a jak to souvis\u00ed s Docker Registry<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/463613\/\">Sestavovat Docker obrazy v werf nyn\u00ed lze i podle b\u011b\u017en\u00e9ho Dockerfile<\/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 \u2014 n\u00e1\u0161 n\u00e1stroj pro CI\/CD v Kubernetes (p\u0159ehled a video p\u0159edn\u00e1\u0161ky)<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/469541\/\">Sestaven\u00ed a nasazen\u00ed typick\u00fdch mikroslu\u017eeb s werf a GitLab CI<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/453734\/\">Sezn\u00e1men\u00ed s Helm 3.<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>Zdroj: <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.3 - 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\/cs\/blog\/administrirovanie\/3-way-merge-v-werf-deploj-v-kubernetes-s-helm-na-steroidah\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"cs_CZ\" \/>\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\/cs\/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\udd47T\u0159\u00edcestn\u00e9 slou\u010den\u00ed v werf: nasazen\u00ed do Kubernetes s Helm \"na steroidech\" | ProHoster","description":"Stalo se to, na co jsme (a nejen my) dlouho \u010dekali: werf, na\u0161e Open Source utilita pro sestavov\u00e1n\u00ed aplikac\u00ed a jejich dod\u00e1v\u00e1n\u00ed do Kubernetes, nyn\u00ed podporuje.","canonical_url":"https:\/\/prohoster.info\/cs\/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":"cs_CZ","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\/cs\/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\/cs\/wp-json\/wp\/v2\/posts\/53120","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/comments?post=53120"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/53120\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media\/53121"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media?parent=53120"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/categories?post=53120"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/tags?post=53120"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}