Tridirekta kunfandiĝo al werf: deplojo al Kubernetes kun Helm "sur steroidoj"

Tio, kion ni (kaj ne nur ni) atendis delonge, okazis: werf, nia Malfermfonta ilo por konstrui aplikaĵojn kaj liveri ilin al Kubernetes, nun subtenas apliki ŝanĝojn uzante tridirektajn kunfandajn flikaĵojn! Aldone al ĉi tio, eblas adopti ekzistantajn K3s-resursojn en Helm-eldonojn sen rekonstrui ĉi tiujn rimedojn.

Tridirekta kunfandiĝo al werf: deplojo al Kubernetes kun Helm "sur steroidoj"

Se ĝi estas tre mallonga, tiam ni metas WERF_THREE_WAY_MERGE=enabled — ni ricevas deplojon “kiel en kubectl apply", kongrua kun ekzistantaj instalaĵoj de Helm 2 kaj eĉ iom pli.

Sed ni komencu per la teorio: kio precize estas 3-vojaj kunfanditaj flikaĵoj, kiel homoj elpensis la aliron por generi ilin, kaj kial ili estas gravaj en CI/KD-procezoj kun Kubernetes-bazita infrastrukturo? Kaj post tio, ni vidu, kio 3-voja-kundigo estas en werf, kiaj reĝimoj estas uzataj defaŭlte kaj kiel administri ĝin.

Kio estas 3-direkta kunfanda flikaĵo?

Do, ni komencu kun la tasko elvolvi la rimedojn priskribitajn en YAML-manifestoj en Kubernetes.

Por labori kun rimedoj, la Kubernetes API ofertas la jenajn bazajn operaciojn: krei, fliki, anstataŭigi kaj forigi. Oni supozas, ke kun ilia helpo necesas konstrui oportunan kontinuan lanĉon de rimedoj al la areto. Kiel?

kubectl imperativaj komandoj

La unua aliro al administrado de objektoj en Kubernetes estas uzi kubectl imperativajn komandojn por krei, modifi kaj forigi tiujn objektojn. Simple dirite:

  • teamo kubectl run vi povas ruli Deployment aŭ Job:
    kubectl run --generator=deployment/apps.v1 DEPLOYMENT_NAME --image=IMAGE
  • teamo kubectl scale — ŝanĝi la nombron da kopioj:
    kubectl scale --replicas=3 deployment/mysql
  • kaj tiel plu.

Ĉi tiu aliro povas ŝajni oportuna unuavide. Tamen estas problemoj:

  1. Estas malfacile aŭtomatigi.
  2. Kiel reflekti agordon en Git? Kiel revizii ŝanĝojn okazantajn al la areto?
  3. Kiel provizi reproduktebleco agordoj ĉe rekomenco?
  4. ...

Estas klare, ke ĉi tiu aliro ne bone kongruas kun stokado de aplikaĵo kaj infrastrukturo kiel kodo (IaC; aŭ eĉ GitOps kiel pli moderna opcio, akirante popularecon en la ekosistemo Kubernetes). Tial ĉi tiuj komandoj ne ricevis plian disvolviĝon en kubectl.

Krei, akiri, anstataŭigi kaj forigi operaciojn

Kun primara kreado ĝi estas simpla: sendu la manifeston al la operacio create kube api kaj la rimedo estas kreita. La YAML-reprezento de la manifesto povas esti stokita en Git kaj kreita per la komando kubectl create -f manifest.yaml.

С forigante ankaŭ simpla: anstataŭigu la samon manifest.yaml de Git al teamo kubectl delete -f manifest.yaml.

Funkciado replace ebligas vin tute anstataŭigi la rimedan agordon per nova, sen rekrei la rimedon. Ĉi tio signifas, ke antaŭ ol fari ŝanĝon al rimedo, estas logike pridemandi la nunan version kun la operacio get, ŝanĝu ĝin kaj ĝisdatigu ĝin kun la operacio replace. kube apiserver estas enkonstruita optimisma ŝlosado kaj, se post kirurgio get la objekto ŝanĝiĝis, tiam la operacio replace ĝi ne funkcios.

Por konservi la agordon en Git kaj ĝisdatigi ĝin per anstataŭigo, vi devas fari la operacion get, kunfandi la agordon de Git kun tio, kion ni ricevis, kaj ekzekutu replace. Defaŭlte, kubectl nur permesas al vi uzi la komandon kubectl replace -f manifest.yamlkie manifest.yaml — jam plene preta (en nia kazo, kunfandita) manifesto, kiu devas esti instalita. Rezultas, ke la uzanto devas efektivigi kunfandi manifestojn, kaj ĉi tio ne estas bagatela afero...

Indas ankaŭ rimarki, ke kvankam manifest.yaml kaj estas konservita en Git, ni ne povas anticipe scii ĉu necesas krei objekton aŭ ĝisdatigi ĝin - tio devas esti farita per uzantprogramaro.

Sumo: ĉu ni povas konstrui daŭran lanĉon nur uzante krei, anstataŭigi kaj forigi, certigante, ke la infrastruktura agordo estas konservita en Git kune kun la kodo kaj oportuna CI/KD?

Principe ni povas... Por tio vi devos efektivigi la kunfandan operacion manifestoj kaj ia ligado kiu:

  • kontrolas la ĉeeston de objekto en la areto,
  • faras komencan kreadon de rimedoj,
  • ĝisdatigas aŭ forigas ĝin.

Dum ĝisdatigo, bonvolu noti tion rimedo eble ŝanĝiĝis ekde lasta get kaj aŭtomate trakti la kazon de optimisma ŝlosado - faru ripetajn ĝisdatigajn provojn.

Tamen, kial reinventi la radon kiam kube-apiserver proponas alian manieron ĝisdatigi rimedojn: la operacio patch, kiu malpezigas la uzanton de kelkaj el la priskribitaj problemoj?

Patch

Nun ni venas al la diakiloj.

Flikiloj estas la ĉefa maniero apliki ŝanĝojn al ekzistantaj objektoj en Kubernetes. Operacio patch ĝi funkcias tiel:

  • la kube-apiserver-uzanto devas sendi diakilon en JSON-formo kaj specifi la objekton,
  • kaj apiserver mem traktos la nunan staton de la objekto kaj alportos ĝin al la bezonata formo.

Optimisma ŝlosado ne estas postulata en ĉi tiu kazo. Ĉi tiu operacio estas pli deklara ol anstataŭigi, kvankam komence ĝi povas ŝajni inverse.

Tiel:

  • uzante operacion create ni kreas objekton laŭ la manifesto de Git,
  • kun helpo de delete — forigu se la objekto ne plu bezonas,
  • kun helpo de patch — ni ŝanĝas la objekton, alportante ĝin al la formo priskribita en Git.

Tamen, por fari tion, vi devas krei ĝusta flikaĵo!

Kiel funkcias flikiloj en Helm 2: dudirekta kunfandiĝo

Kiam vi unue instalas eldonon, Helm faras la operacion create por diagramaj rimedoj.

Kiam vi ĝisdatigas Helm-eldonon por ĉiu rimedo:

  • konsideras la diakilon inter la rimedversio de la antaŭa diagramo kaj la nuna diagramversio,
  • aplikas ĉi tiun flikilon.

Ni nomos ĉi tiun diakilon Dudirekta kunfanda flikaĵo, ĉar 2 manifestoj estas implikitaj en ĝia kreado:

  • rimeda manifesto de la antaŭa eldono,
  • rimedo manifest de la nuna rimedo.

Kiam oni forigas operacion delete en kube apiserver estas vokita por rimedoj kiuj estis deklaritaj en la antaŭa eldono, sed ne deklaritaj en la nuna.

La 2-direkta kunfanda flikila aliro havas problemon: ĝi kondukas al malsinkronigita kun la reala stato de la rimedo en la areto kaj la manifesto en Git.

Ilustraĵo de la problemo kun ekzemplo

  • En Git, diagramo stokas manifeston en kiu la kampo image Deplojo gravas ubuntu:18.04.
  • Uzanto per kubectl edit ŝanĝis la valoron de ĉi tiu kampo al ubuntu:19.04.
  • Redeplojante la Helm-diagramon ne generas diakilon, ĉar la kampo image en la antaŭa versio de la eldono kaj en la nuna diagramo estas la samaj.
  • Post re-deplojo image restaĵoj ubuntu:19.04, kvankam la diagramo diras ubuntu:18.04.

Ni ricevis malsinkronigon kaj perdis deklaracion.

Kio estas sinkronigita rimedo?

Ĝenerale parolante, kompleta Estas neeble akiri kongruon inter la rimeda manifesto en kuranta aro kaj la manifesto de Git. Ĉar en reala manifesto povas esti servaj komentarioj/etikedoj, aldonaj ujoj kaj aliaj datumoj, kiuj estas dinamike aldonitaj kaj forigitaj de la rimedo de iuj regiloj. Ni ne povas kaj ne volas konservi ĉi tiujn datumojn en Git. Tamen ni volas, ke la kampoj, kiujn ni eksplicite specifis en Git, alprenu la taŭgajn valorojn post lanĉo.

Ĝi rezultas tiel ĝenerala sinkronigita rimeda regulo: dum elrulado de rimedo, vi povas ŝanĝi aŭ forigi nur tiujn kampojn kiuj estas eksplicite specifitaj en la manifesto de Git (aŭ estis specifitaj en antaŭa versio kaj nun estas forigitaj).

Dudirekta kunfanda flikaĵo

La ĉefa ideo Dudirekta kunfanda flikaĵo: ni generas diakilon inter la lasta aplikata versio de la manifesto de Git kaj la celversio de la manifesto de Git, konsiderante la aktualan version de la manifesto de la kuranta areto. La rezulta flikaĵo devas observi la sinkronigitan rimedregulon:

  • novaj kampoj aldonitaj al la celversio estas aldonitaj per flikaĵo;
  • antaŭe ekzistantaj kampoj en la lasta aplikata versio kaj ne ekzistantaj en la celversio estas rekomencigitaj per flikaĵo;
  • kampoj en la nuna versio de la objekto, kiuj diferencas de la celversio de la manifesto, estas ĝisdatigitaj per la flikaĵo.

Estas sur ĉi tiu principo ke ĝi generas diakilojn kubectl apply:

  • la lasta aplikata versio de la manifesto estas konservita en la komentario de la objekto mem,
  • celo - prenita de la specifita YAML-dosiero,
  • la nuna estas de kuranta areto.

Nun kiam ni ordigis la teorion, estas tempo diri al vi, kion ni faris en werf.

Aplikante ŝanĝojn al werf

Antaŭe, werf, kiel Helm 2, uzis dudirektajn kunfandajn flikaĵojn.

Ripara diakilo

Por ŝanĝi al nova speco de flikoj - 3-voja-kunfandiĝo - la unua paŝo ni enkondukis la t.n. riparaj diakiloj.

Dum deplojiĝo, norma 2-direkta kunfanda flikaĵo estas uzata, sed werf aldone generas peceton kiu sinkronigus la realan staton de la rimedo kun tio, kio estas skribita en Git (tia flikaĵo estas kreita uzante la saman sinkronigitan rimedregulon priskribitan supre) .

Se malsinkronigo okazas, ĉe la fino de la deplojo la uzanto ricevas AVERTON kun ekvivalenta mesaĝo kaj flikaĵo kiu devas esti aplikita por alporti la rimedon al sinkronigita formo. Ĉi tiu flikaĵo ankaŭ estas registrita en speciala komentario werf.io/repair-patch. Oni supozas, ke la manoj de la uzanto сам aplikos ĉi tiun flikilon: werf tute ne aplikos ĝin.

Generado de riparaj flikaĵoj estas provizora rimedo, kiu ebligas al vi efektive testi la kreadon de flikaĵoj surbaze de la principo de 3-direkta kunfandado, sed ne aŭtomate aplikas ĉi tiujn flikaĵojn. Nuntempe, ĉi tiu operacia reĝimo estas ebligita defaŭlte.

3-direkta kunfanda flikaĵo nur por novaj eldonoj

Ekde la 1-a de decembro 2019, beta- kaj alfa-versioj de werf komenciĝas implicite uzu plenrajtajn 3-direktajn kunfandajn flikaĵojn por apliki ŝanĝojn nur al novaj Helm-eldonoj lanĉitaj per werf. Ekzistantaj eldonoj daŭre uzos la dudirektan kunfandiĝon + riparajn diakilojn.

Ĉi tiu operacia reĝimo povas esti ebligita eksplicite per agordo WERF_THREE_WAY_MERGE_MODE=onlyNewReleases nun.

Примечание: la funkcio aperis en werf dum pluraj eldonoj: en la alfa-kanalo ĝi fariĝis preta kun versio v1.0.5-alfa.19, kaj en la beta-kanalo - kun v1.0.4-beta.20.

3-direkta kunfanda flikaĵo por ĉiuj eldonoj

Ekde la 15-an de decembro 2019, beta- kaj alfa-versioj de werf komencas uzi plenajn tridirektajn kunfandaĵojn defaŭlte por apliki ŝanĝojn al ĉiuj eldonoj.

Ĉi tiu operacia reĝimo povas esti ebligita eksplicite per agordo WERF_THREE_WAY_MERGE_MODE=enabled nun.

Kion fari kun aŭtoskalo de rimedoj?

Estas 2 specoj de aŭtoskalo en Kubernetes: HPA (horizontala) kaj VPA (vertikala).

Horizontala aŭtomate elektas la nombron da kopioj, vertikala - la nombro da rimedoj. Kaj la nombro da kopioj kaj rimedpostuloj estas specifitaj en la rimeda manifesto (vidu Rimeda Manifesto). spec.replicasspec.containers[].resources.limits.cpu, spec.containers[].resources.limits.memory и aliaj).

Problemo: se uzanto agordas rimedon en diagramo tiel ke ĝi specifu certajn valorojn por rimedoj aŭ kopioj kaj aŭtoskaliloj estas ebligitaj por ĉi tiu rimedo, tiam kun ĉiu deplojo werf restarigos ĉi tiujn valorojn al tio, kio estas skribita en la grafika manifesto. .

Estas du solvoj al la problemo. Komence, estas plej bone eviti eksplicite specifi aŭtoskalaj valoroj en la diagramo manifesto. Se ĉi tiu opcio ial ne taŭgas (ekzemple ĉar estas oportune agordi komencajn rimedlimojn kaj la nombron da kopioj en la diagramo), tiam werf ofertas la jenajn komentadojn:

  • werf.io/set-replicas-only-on-creation=true
  • werf.io/set-resources-only-on-creation=true

Se tia komentario ĉeestas, werf ne restarigos la respondajn valorojn sur ĉiu deplojo, sed nur starigos ilin kiam la rimedo estas komence kreita.

Por pliaj detaloj, vidu la projektdokumentaron por HPA и VPA.

Malpermesu la uzon de 3-direkta kunfanda flikaĵo

La uzanto povas nuntempe malpermesi la uzon de novaj pecetoj en werf uzante mediovariablon WERF_THREE_WAY_MERGE_MODE=disabled. Tamen, komencante Ekde la 1-a de marto 2020, ĉi tiu malpermeso ne plu aplikiĝos. kaj nur eblos uzi tridirektajn kunfandajn flikaĵojn.

Adopto de rimedoj en werf

Majstrado de la metodo apliki ŝanĝojn kun 3-direktaj kunfandaj flikoj permesis al ni tuj efektivigi tian funkcion kiel adopti rimedojn ekzistantajn en la areto en la Helm-eldonon.

Helm 2 havas problemon: vi ne povas aldoni rimedon al grafikaj manifestoj kiuj jam ekzistas en la areto sen rekrei ĉi tiun rimedon de nulo (vidu. #6031, #3275). Ni instruis al werf akcepti ekzistantajn rimedojn por liberigo. Por fari tion, vi devas instali komentarion sur la nuna versio de la rimedo de la kuranta grapolo (ekzemple, uzante kubectl edit):

"werf.io/allow-adoption-by-release": RELEASE_NAME

Nun la rimedo devas esti priskribita en la diagramo kaj la venontan fojon kiam werf deplojos eldonon kun la taŭga nomo, la ekzistanta rimedo estos akceptita en ĉi tiu eldono kaj restos sub ĝia kontrolo. Plie, en la procezo de akceptado de rimedo por liberigo, werf alportos la nunan staton de la rimedo de la kuranta areto al la stato priskribita en la diagramo, uzante la samajn 3-manierajn kunfandaĵojn kaj la sinkronigitan rimedan regulon.

Примечание: agordo WERF_THREE_WAY_MERGE_MODE ne influas la adopton de resursoj - en la kazo de adopto, 3-direkta kunfanda flikaĵo ĉiam estas uzata.

Detaloj - en dokumentado.

Konkludoj kaj estontaj planoj

Mi esperas, ke post ĉi tiu artikolo fariĝis pli klare, kio estas 3-direktaj kunfandaĵoj kaj kial ili venis al ili. De praktika perspektivo de la evoluo de la werf-projekto, ilia efektivigo estis alia paŝo al plibonigado de la Helm-simila deplojo. Nun vi povas forgesi pri la problemoj kun agorda sinkronigo, kiuj ofte aperis kiam vi uzas Helm 2. Samtempe, nova utila trajto adopti jam elŝutitajn rimedojn de Kubernetes estis aldonita al la Helm-eldono.

Ankoraŭ ekzistas kelkaj problemoj kaj defioj kun Helm-similaj deplojoj, kiel ekzemple la uzo de Go-ŝablonoj, kiujn ni daŭre traktos.

Informoj pri metodoj de ĝisdatigo de rimedoj kaj adopto ankaŭ troveblas ĉe ĉi tiu dokumenta paĝo.

Helmo 3

Inda de speciala noto liberigita ĝuste la alian tagon nova grava versio de Helm - v3 - kiu ankaŭ uzas 3-direktajn kunfanditajn pecetojn kaj forigas Tiller. La nova versio de Helm postulas migrado ekzistantaj instalaĵoj por konverti ilin en la novan eldonan stokadformaton.

Werf, siaflanke, nuntempe forigis uzadon de Tiller, ŝanĝis al tridirekta kunfandiĝo kaj aldonis multe pli, dum ĝi restas kongrua kun ekzistantaj instalaĵoj de Helm 2 (neniuj migraj skriptoj devas esti efektivigitaj). Tial, ĝis werf ŝanĝas al Helm 3, werf-uzantoj ne perdas la ĉefajn avantaĝojn de Helm 3 super Helm 2 (ŭerf ankaŭ havas ilin).

Tamen, la ŝanĝo de werf al la kodbazo Helm 3 estas neevitebla kaj okazos en proksima estonteco. Supozeble ĉi tio estos werf 1.1 aŭ werf 1.2 (nuntempe, la ĉefa versio de werf estas 1.0; por pliaj informoj pri la werf-versiiga aparato, vidu tie). Dum ĉi tiu tempo, Helm 3 havos tempon por stabiligi.

PS

Legu ankaŭ en nia blogo:

fonto: www.habr.com

Aldoni komenton