{"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\/hr\/blog\/administrirovanie\/3-way-merge-v-werf-deploj-v-kubernetes-s-helm-na-steroidah","title":{"rendered":"3-way merge u werf: implementacija u Kubernetesu s Helmom \"na steroidima\"","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Dogodilo se ono \u0161to smo (i ne samo mi) dugo \u010dekali: <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/\">werf<\/a><\/noindex>, na\u0161 Open Source alat za izgradnju aplikacija i njihovu isporuku u Kubernetes, sada podr\u017eava primjenu promjena kori\u0161tenjem 3-way-merge patch-eva! Osim toga, uvedena je mogu\u0107nost usvajanja postoje\u0107ih K8s resursa u Helm relize bez ponovnog stvaranja tih resursa.<\/p>\n<p><img decoding=\"async\" alt=\"3-way merge u werf: implementacija u Kubernetesu s Helmom &quot;na steroidima&quot;\" src=\"\/wp-content\/uploads\/2019\/11\/e5be3544c201f7b2c97fba216a49506d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUkratko, postavljamo <code>WERF_THREE_WAY_MERGE=enabled<\/code> \u2014 dobivamo isporuku \u201ekao u <code>kubectl apply<\/code>\u201c, kompatibilnu s postoje\u0107im instalacijama na Helm 2, pa \u010dak i malo vi\u0161e.<\/p>\n<p>Ali hajde da po\u010dnemo s teorijom: \u0161to su zapravo 3-way-merge patch-evi, kako su ljudi do\u0161li do pristupa njihovoj generaciji i za\u0161to su va\u017eni u CI\/CD procesima s infrastrukturom temeljenom na Kubernetesu? A nakon toga \u2014 pogledat \u0107emo \u0161to zapravo predstavlja 3-way-merge u werfu, koji se na\u010dini koriste prema zadanim postavkama i kako tim upravljati.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>\u0160to je 3-way-merge patch?<\/h2>\n<p>\nDakle, zapo\u010dnimo s problematikom isporuke resursa opisanih u YAML manifestima, u Kubernetes.<\/p>\n<p>Za rad s resursima Kubernetes API nudi sljede\u0107e osnovne operacije: create, patch, replace i delete. Pretpostavlja se da je njihova svrha olak\u0161ati kontinuiranu isporuku resursa u klaster. Kako?<\/p>\n<h3>Imperativne komande kubectl<\/h3>\n<p>\nPrvi pristup upravljanju objektima u Kubernetesu \u2014 kori\u0161tenje imperativnih komandi kubectl za kreiranje, promjenu i brisanje tih objekata. Drugim rije\u010dima:<\/p>\n<ul>\n<li> komandom <code>kubectl run<\/code> mo\u017ee pokrenuti Deployment ili Job:\n<pre><code class=\"bash\">kubectl run --generator=deployment\/apps.v1 IME_DEPLOYMENT-a --image=IMAGE<\/code><\/pre>\n<\/li>\n<li> komandom <code>kubectl scale<\/code> \u2014 promijeniti broj replik:\n<pre><code class=\"bash\">kubectl scale --replicas=3 deployment\/mysql<\/code><\/pre>\n<\/li>\n<li>itd.<\/li>\n<\/ul>\n<p>\nOvaj pristup mo\u017ee se u\u010diniti jednostavnim na prvi pogled. Me\u0111utim, postoje problemi: <\/p>\n<ol>\n<li> Te\u0161ko je <b>automatizirati<\/b>.<\/li>\n<li> Kako <b>odraziti konfiguraciju<\/b> u Git? Kako napraviti pregled promjena, koje se doga\u0111aju s klasterom?<\/li>\n<li> Kako osigurati <b>reproducibilnost<\/b> konfiguracije prilikom ponovnog pokretanja?<\/li>\n<li>\u2026<\/li>\n<\/ol>\n<p>\nJasno je da se takav pristup lo\u0161e uskla\u0111uje s pohranjivanjem zajedno s kodom aplikacije i infrastrukturom kao kodom (IaC; ili \u010dak <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/458878\/\">GitOps<\/a><\/noindex> kao modernija opcija, koja postaje sve popularnija u Kubernetes ekosustavu). Stoga daljnji razvoj ovih komandi u kubectl nije se dogodio.<\/p>\n<h3>Operacije create, get, replace i delete<\/h3>\n<p>\nS osnovnim <b>kreiranjem<\/b> sve je jednostavno: \u0161aljemo manifest u operaciju <code>create<\/code> kube API-ju i resurs je kreiran. YAML prikaz manifesta mo\u017ee se pohraniti u Git, a za kreiranje \u2014 koristiti komandu <code>kubectl create -f manifest.yaml<\/code>.<\/p>\n<p>S <b>brisanje<\/b> tako\u0111er je jednostavno: umetnemo isti <code>manifest.yaml<\/code> iz Gita u komandu <code>kubectl delete -f manifest.yaml<\/code>.<\/p>\n<p>Operacija <b><code>replace<\/code><\/b> omogu\u0107uje potpuno zamjenu konfiguracije resursa s novom, bez ponovnog stvaranja resursa. To zna\u010di da je prije nego \u0161to se izvr\u0161i promjena resursa logi\u010dno zatra\u017eiti trenutnu verziju operacijom <code>preuzmi<\/code>, izmijeniti je i a\u017eurirati operacijom <code>replace<\/code>. U kube apiserveru ugra\u0111en je <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Optimistic_concurrency_control\">optimisti\u010dki zaklju\u010davanje<\/a><\/noindex> i, ako se nakon operacije <code>preuzmi<\/code> objekt promijenio, tada operacija <code>replace<\/code> ne\u0107e pro\u0107i.<\/p>\n<p>Kako bismo pohranili konfiguraciju u Git i a\u017eurirali je pomo\u0107u replace, potrebno je izvr\u0161iti operaciju <code>preuzmi<\/code>, spojiti konfiguraciju iz Gita s onim \u0161to smo dobili, i izvr\u0161iti <code>replace<\/code>. Standardno, kubectl omogu\u0107uje samo kori\u0161tenje naredbe <code>kubectl replace -f manifest.yaml<\/code>, gdje <code>manifest.yaml<\/code> \u2014 ve\u0107 potpuno pripremljen (u na\u0161em slu\u010daju \u2014 spojeni) manifest koji treba instalirati. Dakle, korisniku je potrebno implementirati spajanje manifestacija, a to nije trivijalno\u2026<\/p>\n<p>Tako\u0111er valja napomenuti da, iako <code>manifest.yaml<\/code> se pohranjuje u Git, ne mo\u017eemo unaprijed znati je li potrebno stvoriti objekt ili ga a\u017eurirati \u2014 to bi trebao u\u010diniti korisni\u010dki softver.<\/p>\n<p>Ukratko: <b>mo\u017eemo li izgraditi kontinuirani isporu\u010divanje<\/b> samo pomo\u0107u create, replace i delete, osiguravaju\u0107i pohranu konfiguracije infrastrukture u Gitu zajedno s kodom i prikladnim CI\/CD-om?<\/p>\n<p>U na\u010delu, mo\u017eemo\u2026 Za to <b>bit \u0107e potrebno implementirati operaciju spajanja<\/b> manifestacija i neku vrstu omota\u010da koji:<\/p>\n<ul>\n<li> provjerava postojanje objekta u klasteru,<\/li>\n<li> izvodi inicijalno stvaranje resursa,<\/li>\n<li> a\u017eurira ili bri\u0161e ga.<\/li>\n<\/ul>\n<p>\nPrilikom a\u017euriranja treba uzeti u obzir da <i>resurs je mogao promijeniti<\/i> od posljednjeg <code>preuzmi<\/code> i automatski obraditi slu\u010daj optimisti\u010dkog zaklju\u010davanja \u2014 izvr\u0161avati ponovne poku\u0161aje a\u017euriranja.<\/p>\n<p>Me\u0111utim, za\u0161to izmi\u0161ljati kota\u010d kada kube-apiserver nudi drugi na\u010din a\u017euriranja resursa: operaciju <code>patch<\/code>, koja preuzima dio opisanih problema od korisnika?<\/p>\n<h3>Patch<\/h3>\n<p>\nEvo nas do zakrpa.<\/p>\n<p>Zakrpe su glavni na\u010din primjene promjena postoje\u0107im objektima u Kubernetesu. Operacija <code>patch<\/code> funkcionira tako da:<\/p>\n<ul>\n<li> korisniku kube-apiservera treba poslati zakrpu u JSON formatu i navesti objekt,<\/li>\n<li> a apiserver \u0107e sam razumjeti trenutno stanje objekta i dovesti ga u \u017eeljeni oblik.<\/li>\n<\/ul>\n<p>\nOptimisti\u010dko zaklju\u010davanje u ovom slu\u010daju nije potrebno. Ova operacija je deklarativnija u usporedbi s replace, iako se isprva mo\u017ee \u010diniti obrnuto.<\/p>\n<p>Dakle:<\/p>\n<ul>\n<li> uz pomo\u0107 operacije <code>create<\/code> stvaramo objekt prema manifestu iz Gita,<\/li>\n<li> pomo\u0107u <code>izbri\u0161i<\/code> \u2014 bri\u0161emo ga ako objekt vi\u0161e nije potreban,<\/li>\n<li> pomo\u0107u <code>patch<\/code> \u2014 mijenjamo objekt, dovode\u0107i ga u oblik opisano u Gitu.<\/li>\n<\/ul>\n<p>\nMe\u0111utim, da biste to u\u010dinili, potrebno je stvoriti <i>ispravan patch<\/i>!<\/p>\n<h3>Kako rade patch-evi u Helm 2: 2-way-merge<\/h3>\n<p>\nPri prvoj instalaciji Helm izdanja vr\u0161i se operacija <code>create<\/code> za resurse charta.<\/p>\n<p>Pri a\u017euriranju izdanja Helm za svaki resurs:<\/p>\n<ul>\n<li> uzima patch izme\u0111u verzije resursa iz prethodnog charta i trenutne verzije charta,<\/li>\n<li> primjenjuje taj patch.<\/li>\n<\/ul>\n<p>\nTakav patch \u0107emo zvati <b>2-way-merge patch<\/b>, jer se u njegovom stvaranju sudjeluje 2 manifesta:<\/p>\n<ul>\n<li> manifest resursa iz prethodnog izdanja,<\/li>\n<li> manifest resursa iz trenutnog resursa.<\/li>\n<\/ul>\n<p>\nPri brisanju operacija <code>izbri\u0161i<\/code> u kube apiserveru se poziva za resurse koji su bili deklarirani u prethodnom izdanju, ali nisu deklarirani u trenutnom.<\/p>\n<p>Pristup s 2-way merge patch ima problem: dovodi do <b>nesinkronizacije stvarnog stanja resursa u klasteru i manifesta u Gitu<\/b>.<\/p>\n<h3>Ilustracija problema na primjeru<\/h3>\n<p><\/p>\n<ul>\n<li> U Gitu, u chartu se \u010duva manifest, u kojem polje <code>image<\/code> za Deployment ima vrijednost <code>ubuntu:18.04<\/code>.<\/li>\n<li> Korisnik je preko <code>kubectl edit<\/code> promijenio vrijednost tog polja na <code>ubuntu:19.04<\/code>.<\/li>\n<li> Pri ponovnoj depoymentu charta Helma <i>ne generira patch<\/i>, jer su polja <code>image<\/code> u prethodnoj verziji izdanja i trenutnom chartu ista.<\/li>\n<li> Nakon ponovnog deploya <code>image<\/code> ostaje <code>ubuntu:19.04<\/code>, iako u chartu pi\u0161e <code>ubuntu:18.04<\/code>.<\/li>\n<\/ul>\n<p>\nDobili smo nesinkronizaciju i izgubili deklarativnost.<\/p>\n<h3>\u0160to je to sinkronizirani resurs?<\/h3>\n<p>\nOp\u0107enito, <i>potpuno<\/i> uskla\u0111enost manifesta resursa u aktivnom klasteru i manifesta iz Gita nije mogu\u0107e posti\u0107i. Jer u stvarnom manifestu mogu biti sistemske anotacije\/oznake, dodatni kontejneri i drugi podaci koji se dinami\u010dki dodaju i uklanjaju iz resursa od strane kontrolera. Te podatke ne mo\u017eemo i ne \u017eelimo dr\u017eati u Gitu. Me\u0111utim, \u017eelimo da prilikom implementacije ta polja koja smo jasno naveli u Gitu imaju odgovaraju\u0107e vrijednosti.<\/p>\n<p>Ispada da je to op\u0107e <b>pravilo sinkroniziranog resursa<\/b>: prilikom implementacije resursa mogu se mijenjati ili brisati samo ona polja koja su jasno navedena u manifestu iz Gita (ili su bila navedena u prethodnoj verziji, a sada su uklonjena).<\/p>\n<h3>3-way-merge patch<\/h3>\n<p>\nOsnovna ideja <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Merge_(version_control)#Three-way_merge\">3-way-merge patch<\/a><\/noindex>: generira patch izme\u0111u posljednje primijenjene verzije manifesta iz Gita i ciljne verzije manifesta iz Gita uzimaju\u0107i u obzir trenutnu verziju manifesta iz aktivnog klastera. Kona\u010dni patch mora odgovarati pravilu sinkroniziranog resursa:<\/p>\n<ul>\n<li> nova polja, dodana u ciljnu verziju, dodaju se pomo\u0107u patch-a;<\/li>\n<li> polja koja su postojala u posljednjoj primijenjenoj verziji i ne postoje u ciljnome - poni\u0161tavaju se pomo\u0107u zakrpe;<\/li>\n<li> polja u trenutnoj verziji objekta koja se razlikuju od ciljne verzije manifesta - a\u017euriraju se pomo\u0107u zakrpe.<\/li>\n<\/ul>\n<p>\nNa upravo takvom principu generiraju se zakrpe <code>kubectl apply<\/code>:<\/p>\n<ul>\n<li> posljednja primijenjena verzija manifesta \u010duva se u anotaciji samog objekta, <\/li>\n<li> ciljna - preuzima se iz navedene YAML datoteke,<\/li>\n<li> trenutna - iz radnog klastera.<\/li>\n<\/ul>\n<p>\nSada kada smo se pozabavili teorijom, vrijeme je da ka\u017eemo \u0161to smo napravili u werf.<\/p>\n<h2>Primjena promjena u werf<\/h2>\n<p>\nRanije je werf, kao i Helm 2, koristio 2-way-merge zakrpe.<\/p>\n<h3>Repair zakrpa<\/h3>\n<p>\nKako bismo pre\u0161li na novi tip zakrpa - 3-way-merge, prvi korak koji smo poduzeli bio je uvo\u0111enje takozvanih <b>repair zakrpa<\/b>.<\/p>\n<p>Prilikom implementacije koristi se standardna 2-way-merge zakrpa, no werf dodatno generira takvu zakrpu koja bi sinkronizirala stvarno stanje resursa s onim \u0161to je napisano u Gitu (stvara se ta zakrpa koriste\u0107i isto pravilo sinkroniziranog resursa opisano iznad).<\/p>\n<p>U slu\u010daju nesinkronizacije, na kraju implementacije korisnik dobiva WARNING s odgovaraju\u0107om porukom i zakrpom koju treba primijeniti kako bi se resurs doveo u sinkronizirani polo\u017eaj. Tako\u0111er, ova zakrpa se zapisuje u posebnu anotaciju <code>werf.io\/repair-patch<\/code>. Predvi\u0111a se da korisnik ru\u010dno <b>samo<\/b> primijeni tu zakrpu: werf je ne\u0107e primijeniti principijelno.<\/p>\n<p>Generiranje repair zakrpa je privremena mjera koja omogu\u0107ava isprobavanje stvaranja zakrpa prema principu 3-way-merge, ali automatski te zakrpe ne primjenjuju. U ovom trenutku ovaj na\u010din rada je uklju\u010d\u0435\u043d prema zadanim postavkama.<\/p>\n<h3>3-way-merge zakrpa samo za nove izdanja<\/h3>\n<p>\nPo\u010dev\u0161i od 1. prosinca 2019. beta i alpha verzije werf po\u010dinju <b>po defaultu<\/b> koristiti potpune 3-way-merge zakrpe za primjenu promjena samo za nove Helm izdanja koja se implementiraju putem werf. Ve\u0107 postoje\u0107a izdanja nastavit \u0107e koristiti pristup s 2-way-merge + repair zakrpama.<\/p>\n<p>Ovaj na\u010din rada mo\u017ee se uklju\u010diti izrijekom postavkom <code>WERF_THREE_WAY_MERGE_MODE=onlyNewReleases<\/code> ve\u0107 sada.<\/p>\n<p><i><b>Napomena<\/b>: funkcija se pojavila u werf-u tijekom nekoliko izdanja: u alpha kanalu postala je gotova s verzijom <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 u beta kanalu - 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 zakrpa za sve verzije<\/h3>\n<p>\nOd 15. prosinca 2019. beta i alpha verzije werf po defaultu koriste potpune 3-way-merge patch-eve za primjenu promjena na svim izdanjima.<\/p>\n<p>Ovaj na\u010din rada mo\u017ee se uklju\u010diti izrijekom postavkom <code>WERF_THREE_WAY_MERGE_MODE=enabled<\/code> ve\u0107 sada.<\/p>\n<h3>Kako se nositi s automatskim skaliranjem resursa?<\/h3>\n<p>\nU Kubernetesu postoje 2 tipa automatskog skaliranja: HPA (horizontalno) i VPA (vertikalno).<\/p>\n<p>Horizontalno automatski odre\u0111uje broj replika, dok vertikalno odre\u0111uje koli\u010dinu resursa. I broj replika i zahtjevi za resursima su navedeni u manifestu resursa (vidi. <code>spec.replicas<\/code> ili <code>spec.containers[].resources.limits.cpu<\/code>, <code>spec.containers[].resources.limits.memory<\/code> i <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/manage-compute-resources-container\/#resource-requests-and-limits-of-pod-and-container\">druge<\/a><\/noindex>).<\/p>\n<p>Problem: ako korisnik konfiguri\u0161e resurs u chartu tako da ima odre\u0111ene vrijednosti za resurse ili replike i za taj resurs su uklju\u010deni automatski skaleri, tada \u0107e werf pri svakoj implementaciji resetirati ove vrijednosti na ono \u0161to je zapisano u manifestu charta.<\/p>\n<p>Postoje dva rje\u0161enja za problem. Prvo, najbolje je odustati od eksplicitnog navo\u0111enja automatski skaliranih vrijednosti u manifestu charta. Ako ova opcija iz nekog razloga nije pogodna (na primjer, jer je zgodno postaviti po\u010detna ograni\u010denja resursa i broj replika unutar charta), werf nudi sljede\u0107e anotacije:<\/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>\nU prisustvu takve anotacije, werf ne\u0107e resetirati odgovaraju\u0107e vrijednosti pri svakoj implementaciji, ve\u0107 \u0107e ih postaviti samo prilikom prvog kreiranja resursa.<\/p>\n<p>Vi\u0161e informacija \u2014 vidi u dokumentaciji projekta o <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/resources_update_methods_and_adoption.html#deal-with-hpa\">HPA<\/a><\/noindex> i <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>Zabraniti kori\u0161tenje 3-way-merge patch-a<\/h3>\n<p>\nKorisnik mo\u017ee trenutno zabraniti kori\u0161tenje novih patch-eva u werf pomo\u0107u varijable okru\u017eenja <code>WERF_THREE_WAY_MERGE_MODE=disabled<\/code>. Me\u0111utim, od <b>1. o\u017eujka 2020. ovo pravilo prestaje vrijediti<\/b> i bit \u0107e mogu\u0107e samo kori\u0161tenje 3-way-merge patch-eva.<\/p>\n<h2>Usvajanje resursa u werf<\/h2>\n<p>\nUvo\u0111enje metode primjene promjena 3-way-merge patch-evima omogu\u0107ilo nam je odmah implementirati funkciju poput usvajanja postoje\u0107ih resursa u klasteru u Helm izdanju.<\/p>\n<p>Helm 2 ima problem: nije mogu\u0107e dodati resurs koji ve\u0107 postoji u klasteru u manifeste charta bez ponovnog stvaranja tog resursa (vidi. <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 smo werf da prihvati postoje\u0107e resurse u izdanju. Za to je potrebno na trenutnu verziju resursa iz aktivnog klastera postaviti anotaciju (na primjer, pomo\u0107u <code>kubectl edit<\/code>):<\/p>\n<pre><code class=\"plaintext\">\"werf.io\/allow-adoption-by-release\": RELEASE_NAME<\/code><\/pre>\n<p>\nSada resurs treba opisati u chartu, a prilikom sljede\u0107e implementacije werf-a s odgovaraju\u0107im imenom, postoje\u0107i resurs \u0107e biti prihva\u0107en u tu verziju i ostat \u0107e pod njegovim upravljanjem. \u0160tovi\u0161e, tijekom prihva\u0107anja resursa u verziju, werf \u0107e dovesti trenutno stanje resursa iz radnog klastera u stanje opisano u chartu, koriste\u0107i iste 3-way-merge zakrpe i pravilo sinkroniziranog resursa.<\/p>\n<p><i><b>Napomena<\/b>: konfiguracija <code>WERF_THREE_WAY_MERGE_MODE<\/code> ne utje\u010de na usvajanje resursa \u2014 u slu\u010daju usvajanja uvijek se koristi 3-way-merge zakrpa.<\/i><\/p>\n<p>Detalji \u2014 u <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/resources_update_methods_and_adoption.html#resources-adoption\">dokumentaciju<\/a><\/noindex>.<\/p>\n<h2>Zaklju\u010dci i daljnji planovi<\/h2>\n<p>\nNadam se da je nakon ovog \u010dlanka jasnije \u0161to su 3-way-merge zakrpe i za\u0161to su uvedene. Iz prakti\u010dne perspektive razvoja projekta werf, njihova implementacija bila je jo\u0161 jedan korak ka pobolj\u0161anju Helm-sli\u010dne implementacije. Sada mo\u017eemo zaboraviti na probleme sa sinkronizacijom konfiguracija koji su se \u010desto javljali pri kori\u0161tenju Helm 2. Tako\u0111er, dodana je nova korisna zna\u010dajka usvajanja ve\u0107 preuzetih Kubernetes resursa u Helm verziju.<\/p>\n<p>U Helm-sli\u010dnim implementacijama i dalje ostaju neki problemi i pote\u0161ko\u0107e, poput kori\u0161tenja Go predlo\u017eaka, a nastavit \u0107emo ih rje\u0161avati.<\/p>\n<p>Informacije o metodama a\u017euriranja resursa i usvajanju tako\u0111er se mogu prona\u0107i na <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/resources_update_methods_and_adoption.html\">ovoj stranici dokumentacije<\/a><\/noindex>.<\/p>\n<h3>Helm 3<\/h3>\n<p>\nPosebnu pa\u017enju zaslu\u017euje <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/news\/t\/475722\/\">nedavno objavljena<\/a><\/noindex> nova glavna verzija Helma \u2014 v3, \u2014 koja tako\u0111er koristi 3-way-merge zakrpe i uklanja Tiller. Nova verzija Helma zahtijeva <noindex><a rel=\"nofollow\" href=\"https:\/\/helm.sh\/docs\/topics\/v2_v3_migration\/\">migraciju<\/a><\/noindex> ve\u0107 postoje\u0107ih instalacija kako bi ih konvertirala u novi format pohrane verzija.<\/p>\n<p>Werf je sa svoje strane ve\u0107 uklonio kori\u0161tenje Tillera, pre\u0161ao na 3-way-merge i dodao <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/documentation\/reference\/deploy_process\/differences_with_helm.html\">mnoge druge stvari<\/a><\/noindex>, pri \u010demu je ostao kompatibilan s ve\u0107 postoje\u0107im instalacijama na Helmu 2 (nema potrebe za izvo\u0111enjem skripti za migraciju). Stoga, dok werf ne pre\u0111e na Helm 3, korisnici werfa ne gube osnovne prednosti Helma 3 u odnosu na Helm 2 (one su tako\u0111er prisutne u werfu).<\/p>\n<p>Ipak, prebacivanje werfa na kodnu bazu Helma 3 neizbje\u017eno je i dogodit \u0107e se u bliskoj budu\u0107nosti. Pretpostavlja se da \u0107e to biti werf 1.1 ili werf 1.2 (trenutno je glavna verzija werfa \u2014 1.0; vi\u0161e o strukturi verzioniranja werfa pogledajte <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/werf#backward-compatibility-promise\">ovdje<\/a><\/noindex>). U to vrijeme Helm 3 \u0107e se uspjeti stabilizirati.<\/p>\n<h2>P.S.<\/h2>\n<p>\nPro\u010ditajte i na na\u0161em blogu:<\/p>\n<ul>\n<li> Ciklus bilje\u0161ki o novinama u werf:\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/468049\/\">Kori\u0161tenje werfa za implementaciju slo\u017eenih Helm-chartova<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/465131\/\">Podr\u0161ka za monorepo i multirepo u werfu i kakve veze to ima s Docker Registry-jem<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/463613\/\">Sada je mogu\u0107e sastavljati Docker slike u werf i prema obi\u010dnom Dockerfile-u<\/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 na\u0161 alat za CI\/CD u Kubernetesu (pregled i video prezentacija)<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/469541\/\">Gradnja i deploy istovrsnih mikroservisa s werf i GitLab CI<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/453734\/\">Uvod u Helm 3<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>Izvor: <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.4 - 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\/hr\/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.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"hr_HR\" \/>\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\/hr\/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\udd473-smjerno spajanje u werfu: implementacija u Kubernetes s Helm \u201ena steroidima\u201d | ProHoster","description":"Desilo se ono \u0161to smo (ne samo mi) dugo \u010dekali: werf, na\u0161 Open Source alat za izgradnju aplikacija i njihovo dostavljanje u Kubernetes, sada podr\u017eava.","canonical_url":"https:\/\/prohoster.info\/hr\/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":"hr_HR","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\/hr\/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\/hr\/wp-json\/wp\/v2\/posts\/53120","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/comments?post=53120"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/53120\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media\/53121"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media?parent=53120"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/categories?post=53120"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/tags?post=53120"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}