3-smerno spajanje z werf: uvedba v Kubernetes s Helmom "na steroidih"

Zgodilo se je tisto, kar smo (pa ne samo mi) dolgo čakali: werf, naš odprtokodni pripomoček za gradnjo aplikacij in njihovo dostavo v Kubernetes, zdaj podpira uveljavljanje sprememb z uporabo trosmernih popravkov spajanja! Poleg tega je možno sprejeti obstoječe vire K3s v izdaje Helm brez ponovne gradnje teh virov.

3-smerno spajanje z werf: uvedba v Kubernetes s Helmom "na steroidih"

Če je zelo kratek, potem postavimo WERF_THREE_WAY_MERGE=enabled — dobimo razporeditev »kot v kubectl apply", združljiv z obstoječimi namestitvami Helm 2 in še malo več.

Toda začnimo s teorijo: kaj točno so popravki 3-way-merge, kako so ljudje prišli do pristopa k njihovemu ustvarjanju in zakaj so pomembni v procesih CI/CD z infrastrukturo, ki temelji na Kubernetesu? In po tem si poglejmo, kaj je 3-way-merge v werf, kateri načini so privzeto uporabljeni in kako jih upravljati.

Kaj je popravek 3-smernega spajanja?

Torej, začnimo z nalogo uvajanja virov, opisanih v manifestih YAML, v Kubernetes.

Za delo z viri Kubernetes API ponuja naslednje osnovne operacije: ustvarjanje, popravljanje, zamenjava in brisanje. Predpostavlja se, da je z njihovo pomočjo potrebno zgraditi priročno neprekinjeno uvajanje virov v gručo. kako

kubectl imperativni ukazi

Prvi pristop k upravljanju objektov v Kubernetesu je uporaba obveznih ukazov kubectl za ustvarjanje, spreminjanje in brisanje teh objektov. Enostavno povedano:

  • ekipa kubectl run lahko zaženete Deployment ali Job:
    kubectl run --generator=deployment/apps.v1 DEPLOYMENT_NAME --image=IMAGE
  • ekipa kubectl scale — spremenite število replik:
    kubectl scale --replicas=3 deployment/mysql
  • itd

Ta pristop se lahko na prvi pogled zdi udoben. Vendar obstajajo težave:

  1. Težko je avtomatizirati.
  2. Kot odraža konfiguracijo v Gitu? Kako pregledati spremembe, ki se dogajajo v gruči?
  3. Kako zagotoviti ponovljivost konfiguracije ob ponovnem zagonu?
  4. ...

Jasno je, da se ta pristop ne ujema dobro s shranjevanjem aplikacije in infrastrukture kot kode (IaC; ali celo GitOps kot sodobnejša možnost, ki postaja vse bolj priljubljena v ekosistemu Kubernetes). Zato ti ukazi niso prejeli nadaljnjega razvoja v kubectl.

Operacije ustvarjanja, pridobivanja, zamenjave in brisanja

S primarno ustvarjanje preprosto je: pošljite manifest operaciji create kube api in vir je ustvarjen. YAML predstavitev manifesta je mogoče shraniti v Git in ustvariti z ukazom kubectl create -f manifest.yaml.

С odstranitev tudi preprosto: zamenjajte enako manifest.yaml od Gita do ekipe kubectl delete -f manifest.yaml.

Operacija replace vam omogoča, da popolnoma zamenjate konfiguracijo vira z novo, ne da bi znova ustvarili vir. To pomeni, da je pred spremembo vira logično, da z operacijo poizvedete trenutno različico get, ga spremenite in posodobite z operacijo replace. kube apiserver je vgrajen optimistično zaklepanje in če po operaciji get objekt se je spremenil, nato operacija replace ne bo delovalo.

Če želite shraniti konfiguracijo v Git in jo posodobiti z zamenjavo, morate izvesti operacijo get, združite konfiguracijo iz Gita s tem, kar smo prejeli, in izvedite replace. Privzeto kubectl dovoljuje samo uporabo ukaza kubectl replace -f manifest.yamlČe manifest.yaml — že v celoti pripravljen (v našem primeru združen) manifest, ki ga je treba namestiti. Izkazalo se je, da mora uporabnik implementirati manifeste spajanja in to ni nepomembna zadeva ...

Omeniti velja tudi, da čeprav manifest.yaml in je shranjen v Gitu, ne moremo vnaprej vedeti, ali je treba ustvariti objekt ali ga posodobiti - to mora storiti uporabniška programska oprema.

Skupaj: ali lahko zgradimo neprekinjeno uvajanje samo z uporabo ustvarjanja, zamenjave in brisanja, s čimer zagotovite, da je konfiguracija infrastrukture shranjena v Git skupaj s kodo in priročnim CI/CD?

Načeloma lahko ... Za to boste morali izvesti operacijo spajanja manifeste in nekakšno zavezo, ki:

  • preveri prisotnost predmeta v gruči,
  • izvede začetno ustvarjanje virov,
  • posodobi ali izbriše.

Pri posodabljanju upoštevajte to vir se je morda spremenil od zadnjega get in samodejno obravnava primer optimističnega zaklepanja – večkrat poskusite posodobiti.

Vendar, zakaj bi znova izumljali kolesje, ko pa kube-apiserver ponuja še en način posodabljanja virov: operacijo patch, ki uporabnika razbremeni nekaterih opisanih težav?

Patch

Zdaj smo pri popravkih.

Popravki so primarni način za uporabo sprememb na obstoječih objektih v Kubernetesu. Delovanje patch deluje takole:

  • uporabnik kube-apiserverja mora poslati popravek v obliki JSON in določiti predmet,
  • in apiserver se bo sam ukvarjal s trenutnim stanjem objekta in ga pripeljal v zahtevano obliko.

Optimistično zaklepanje v tem primeru ni potrebno. Ta operacija je bolj deklarativna kot zamenjava, čeprav se na začetku morda zdi ravno obratno.

Na ta način:

  • z uporabo operacije create ustvarimo objekt v skladu z manifestom iz Gita,
  • s pomočjo delete — izbrisati, če predmet ni več potreben,
  • s pomočjo patch — predmet spremenimo in ga pripeljemo v obliko, opisano v Gitu.

Vendar pa morate za to ustvariti pravilen obliž!

Kako delujejo popravki v Helm 2: 2-way-merge

Ko prvič namestite izdajo, Helm izvede operacijo create za vire grafikonov.

Pri posodabljanju izdaje Helm za vsak vir:

  • upošteva popravek med različico vira iz prejšnjega grafikona in trenutno različico grafikona,
  • uporablja ta popravek.

Ta popravek bomo imenovali 2-smerni spojni popravek, ker sta pri njegovem ustvarjanju udeležena 2 manifesta:

  • manifest vira iz prejšnje izdaje,
  • manifest vira iz trenutnega vira.

Pri odstranitvi operacije delete v kube apiserver se kliče za vire, ki so bili deklarirani v prejšnji izdaji, vendar niso bili deklarirani v trenutni.

Pristop dvosmernega spajanja popravkov ima težavo: vodi do ni usklajen z dejanskim stanjem vira v gruči in manifestom v Gitu.

Ponazoritev problema s primerom

  • V Gitu grafikon shrani manifest, v katerem polje image Uvajanje je pomembno ubuntu:18.04.
  • Uporabnik prek kubectl edit spremenil vrednost tega polja v ubuntu:19.04.
  • Pri ponovni postavitvi karte Helm ne ustvari popravka, saj polje image v prejšnji različici izdaje in v trenutnem grafikonu sta enaka.
  • Po ponovni namestitvi image ostanki ubuntu:19.04, čeprav grafikon pravi ubuntu:18.04.

Dobili smo desinhronizacijo in izgubili deklarativnost.

Kaj je sinhronizirani vir?

Na splošno dokončana Nemogoče je pridobiti ujemanje med manifestom vira v delujoči gruči in manifestom iz Gita. Ker so v pravem manifestu lahko pripombe/oznake storitve, dodatni vsebniki in drugi podatki, ki jih nekateri krmilniki dinamično dodajajo in odstranjujejo iz vira. Teh podatkov ne moremo in ne želimo hraniti v Gitu. Vendar pa želimo, da polja, ki smo jih izrecno podali v Gitu, ob uvedbi prevzamejo ustrezne vrednosti.

Izkazalo se je tako splošno pravilo sinhroniziranega vira: ko uvajate vir, lahko spremenite ali izbrišete samo tista polja, ki so izrecno podana v manifestu iz Gita (ali so bila navedena v prejšnji različici in so zdaj izbrisana).

3-smerni spojni popravek

osrednja ideja 3-smerni spojni popravek: ustvarimo popravek med zadnjo uporabljeno različico manifesta iz Gita in ciljno različico manifesta iz Gita, pri čemer upoštevamo trenutno različico manifesta iz delujoče gruče. Nastali popravek mora biti skladen s pravilom sinhroniziranega vira:

  • nova polja, dodana ciljni različici, so dodana s popravkom;
  • prej obstoječa polja v zadnji uporabljeni različici in neobstoječa polja v ciljni različici se ponastavijo s popravkom;
  • polja v trenutni različici predmeta, ki se razlikujejo od ciljne različice manifesta, se posodobijo s popravkom.

Po tem principu generira popravke kubectl apply:

  • zadnja uporabljena različica manifesta je shranjena v opombi samega predmeta,
  • cilj - vzeto iz navedene datoteke YAML,
  • trenutni je iz delujoče gruče.

Zdaj, ko smo uredili teorijo, je čas, da vam povemo, kaj smo počeli v werfu.

Uveljavljanje sprememb v werf

Prej je werf, tako kot Helm 2, uporabljal popravke dvosmernega spajanja.

Popravite obliž

Da bi prešli na novo vrsto popravkov - 3-way-merge - smo prvi korak uvedli t.i. popravki popravkov.

Pri uvajanju se uporablja standardni 2-way-merge patch, vendar werf dodatno ustvari popravek, ki bi sinhroniziral dejansko stanje vira s tistim, kar je zapisano v Gitu (tak popravek je ustvarjen z istim pravilom sinhroniziranega vira, ki je opisano zgoraj) .

Če pride do desinhronizacije, na koncu uvedbe uporabnik prejme OPOZORILO z ustreznim sporočilom in popravkom, ki ga je treba uporabiti, da se vir prenese v sinhronizirano obliko. Ta popravek je tudi zabeležen v posebni opombi werf.io/repair-patch. Predpostavlja se, da roke uporabnika sam bo uporabil ta popravek: werf ga sploh ne bo uporabil.

Ustvarjanje popravljalnih popravkov je začasen ukrep, ki vam omogoča, da dejansko preizkusite ustvarjanje popravkov na podlagi načela 3-smernega združevanja, vendar teh popravkov ne uporabite samodejno. Ta način delovanja je trenutno privzeto omogočen.

3-smerni popravek združevanja samo za nove izdaje

S 1. decembrom 2019 se začnejo različice beta in alfa werf privzeto uporabite polnopravne popravke 3-smernega združevanja, da uporabite spremembe samo za nove izdaje Helma, uvedene prek werf. Obstoječe izdaje bodo še naprej uporabljale pristop dvosmernega spajanja + popravkov popravkov.

Ta način delovanja lahko izrecno omogočite z nastavitvijo WERF_THREE_WAY_MERGE_MODE=onlyNewReleases zdaj.

Obvestilo: funkcija se je pojavila v werf v več izdajah: v kanalu alfa je postala pripravljena z različico v1.0.5-alpha.19, in v beta kanalu - z v1.0.4-beta.20.

3-smerni spojni popravek za vse izdaje

Od 15. decembra 2019 začnejo različice beta in alfa werf privzeto uporabljati popolne popravke za 3-smerno spajanje, da se spremembe uporabijo za vse izdaje.

Ta način delovanja lahko izrecno omogočite z nastavitvijo WERF_THREE_WAY_MERGE_MODE=enabled zdaj.

Kaj storiti s samodejnim skaliranjem virov?

V Kubernetesu obstajata dve vrsti samodejnega skaliranja: HPA (vodoravno) in VPA (navpično).

Vodoravno samodejno izbere število replik, navpično - število virov. Število replik in zahteve glede virov so podane v manifestu virov (glejte Manifest virov). spec.replicas ali spec.containers[].resources.limits.cpu, spec.containers[].resources.limits.memory и drugi).

Težava: če uporabnik konfigurira vir v grafikonu tako, da poda določene vrednosti za vire ali so za ta vir omogočeni replike in samodejni skalirniki, bo werf z vsako uvedbo ponastavil te vrednosti na tisto, kar je zapisano v manifestu grafikona .

Obstajata dve rešitvi problema. Za začetek je najbolje, da se izognete eksplicitnemu podajanju samodejnih vrednosti v manifestu grafikona. Če ta možnost iz nekega razloga ni primerna (na primer, ker je priročno nastaviti začetne omejitve virov in število replik v grafikonu), potem werf ponuja naslednje opombe:

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

Če je taka opomba prisotna, werf ne bo ponastavil ustreznih vrednosti ob vsaki uvedbi, ampak jih bo nastavil šele, ko bo vir prvotno ustvarjen.

Za več podrobnosti si oglejte projektno dokumentacijo za HPA и VPA.

Prepovejte uporabo popravka 3-smernega spajanja

Uporabnik lahko trenutno prepove uporabo novih popravkov v werf z uporabo spremenljivke okolja WERF_THREE_WAY_MERGE_MODE=disabled. Vendar pa se začne Od 1. marca 2020 ta prepoved ne bo več veljala. in mogoče bo uporabljati le popravke s 3-smernim spajanjem.

Sprejetje virov v werf

Obvladovanje metode uveljavljanja sprememb s popravki 3-smernega spajanja nam je omogočilo takojšnjo implementacijo takšne funkcije, kot je sprejemanje virov, ki obstajajo v gruči, v izdajo Helm.

Helm 2 ima težavo: v manifeste grafikona ne morete dodati vira, ki že obstaja v gruči, ne da bi ta vir znova ustvarili iz nič (glejte. #6031, #3275). Werf smo naučili sprejeti obstoječe vire za izdajo. Če želite to narediti, morate namestiti opombo na trenutno različico vira iz delujoče gruče (na primer z uporabo kubectl edit):

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

Zdaj je treba vir opisati v grafikonu in ko bo werf naslednjič razmestil izdajo z ustreznim imenom, bo obstoječi vir sprejet v to izdajo in ostal pod njegovim nadzorom. Poleg tega bo werf v procesu sprejemanja vira za izdajo pripeljal trenutno stanje vira iz delujoče gruče v stanje, opisano v grafikonu, z uporabo istih popravkov 3-smernega združevanja in pravila sinhroniziranega vira.

Obvestilo: nastavitev WERF_THREE_WAY_MERGE_MODE ne vpliva na prevzem virov - v primeru prevzema se vedno uporablja 3-way-merge patch.

Podrobnosti - v dokumentacijo.

Zaključki in načrti za prihodnost

Upam, da je po tem članku postalo bolj jasno, kaj so popravki 3-way-merge in zakaj so prišli do njih. S praktičnega vidika razvoja projekta werf je bila njihova izvedba še en korak k izboljšanju uvajanja, podobnega Helmu. Zdaj lahko pozabite na težave s sinhronizacijo konfiguracije, ki so se pogosto pojavljale pri uporabi Helm 2. Hkrati je bila izdaji Helm dodana nova uporabna funkcija prevzemanja že prenesenih virov Kubernetes.

Še vedno obstajajo nekatere težave in izzivi z uvajanji, podobnimi Helmu, kot je uporaba predlog Go, ki jih bomo še naprej obravnavali.

Informacije o metodah posodabljanja virov in sprejetju najdete tudi na to stran z dokumentacijo.

Čelada 3

Vreden posebne pozornosti izpuščen Ravno pred dnevi nova večja različica Helma - v3 - ki prav tako uporablja popravke za 3-smerno spajanje in se znebi Tillerja. Nova različica Helma zahteva migracije obstoječe namestitve, da jih pretvorite v obliko shranjevanja nove izdaje.

Werf se je trenutno znebil uporabe Tillerja, preklopil na 3-way-merge in dodal veliko več, hkrati pa ostaja združljiv z obstoječimi namestitvami Helm 2 (izvajati ni treba nobenih migracijskih skriptov). Torej, dokler werf ne preklopi na Helm 3, uporabniki werfa ne izgubijo glavnih prednosti Helma 3 pred Helmom 2 (tudi werf jih ima).

Vendar pa je prehod werf na kodno osnovo Helm 3 neizogiben in se bo zgodil v bližnji prihodnosti. Predvidoma bo to werf 1.1 ali werf 1.2 (trenutno je glavna različica werf 1.0; za več informacij o napravi za ustvarjanje različic werf glejte tukaj). V tem času bo imel Helm 3 čas za stabilizacijo.

PS

Preberite tudi na našem blogu:

Vir: www.habr.com

Dodaj komentar