Kolmesuunaline ühendamine werfiga: juurutamine Kubernetesesse koos Helmiga "steroididel"

Juhtus see, mida oleme (ja mitte ainult meie) kaua oodanud: werf, meie avatud lähtekoodiga utiliit rakenduste loomiseks ja nende Kubernetesesse tarnimiseks, toetab nüüd muudatuste rakendamist kolmesuunaliste liitmispaikade abil! Lisaks on võimalik olemasolevaid K3-i ressursse Helmi väljalasetesse kasutusele võtta ilma neid ressursse ümber ehitamata.

Kolmesuunaline ühendamine werfiga: juurutamine Kubernetesesse koos Helmiga "steroididel"

Kui see on väga lühike, siis paneme WERF_THREE_WAY_MERGE=enabled — saame kasutuselevõtu „nagu kubectl apply", mis ühildub olemasolevate Helm 2 installidega ja isegi veidi enamaga.

Kuid alustame teooriaga: mis on 3-suunalised liitmispaigad, kuidas inimesed nende genereerimise lähenemisviisi leidsid ja miks on need olulised Kubernetese-põhise infrastruktuuriga CI/CD protsessides? Ja pärast seda vaatame, mis on werfis 3-way-merge, milliseid režiime vaikimisi kasutatakse ja kuidas seda hallata.

Mis on 3-suunaline liitmisplaaster?

Niisiis, alustame YAML-i manifestides kirjeldatud ressursside Kubernetesesse juurutamise ülesandega.

Ressurssidega töötamiseks pakub Kubernetes API järgmisi põhitoiminguid: loomine, paikamine, asendamine ja kustutamine. Eeldatakse, et nende abiga on vaja konstrueerida klastrisse mugav pidev ressursside levitamine. Kuidas?

Imperatiivsed kubectli käsud

Esimene lähenemine objektide haldamisele Kubernetesis on kasutada nende objektide loomiseks, muutmiseks ja kustutamiseks kubectli imperatiivseid käske. Lihtsamalt öeldes:

  • meeskond kubectl run saate käivitada juurutamise või töö:
    kubectl run --generator=deployment/apps.v1 DEPLOYMENT_NAME --image=IMAGE
  • meeskond kubectl scale — muutke koopiate arvu:
    kubectl scale --replicas=3 deployment/mysql
  • jne

See lähenemisviis võib esmapilgul tunduda mugav. Siiski on probleeme:

  1. See on raske automatiseerida.
  2. Kui peegeldavad konfiguratsiooni Gitis? Kuidas klastris toimuvaid muudatusi üle vaadata?
  3. Kuidas pakkuda reprodutseeritavus konfiguratsioonid taaskäivitamisel?
  4. ...

On selge, et see lähenemine ei sobi hästi rakenduse ja infrastruktuuri koodina salvestamisega (IaC; või isegi GitOps moodsama võimalusena, kogudes populaarsust Kubernetese ökosüsteemis). Seetõttu ei saanud neid käske kubectlis edasi arendada.

Looge, hankige, asendage ja kustutage toiminguid

Esmasega looming see on lihtne: saatke manifest operatsioonile create kube api ja ressurss on loodud. Manifesti YAML-i esituse saab salvestada Giti ja luua käsuga kubectl create -f manifest.yaml.

С eemaldamine ka lihtne: asenda sama manifest.yaml Gitist meeskonda kubectl delete -f manifest.yaml.

Operatsioon replace võimaldab teil täielikult asendada ressursi konfiguratsiooni uuega, ilma ressurssi uuesti loomata. See tähendab, et enne ressursis muudatuse tegemist on loogiline teha toiminguga päring praeguse versiooni kohta get, muutke seda ja värskendage seda toiminguga replace. kube apiserver on sisse ehitatud optimistlik lukustus ja kui pärast operatsiooni get objekt on muutunud, siis toiming replace see ei tööta.

Konfiguratsiooni salvestamiseks Giti ja värskendamiseks asendamise abil peate tegema toimingu get, ühendage Giti konfiguratsioon saadud andmetega ja käivitage replace. Vaikimisi lubab kubectl kasutada ainult käsku kubectl replace -f manifest.yamlKus manifest.yaml — juba täielikult ettevalmistatud (meie puhul liidetud) manifest, mis tuleb installida. Selgub, et kasutaja peab rakendama ühendamismanifestid ja see pole tühine asi...

Märkimist väärib ka see, et kuigi manifest.yaml ja on salvestatud Gitis, ei saa me ette teada, kas on vaja mingi objekt luua või seda uuendada – seda peab tegema kasutajatarkvara.

Kokku: kas saame luua pideva levitamise kasutades ainult loomist, asendamist ja kustutamist, tagades, et infrastruktuuri konfiguratsioon salvestatakse Giti koos koodi ja mugava CI/CD-ga?

Põhimõtteliselt saame... Selleks peate ühendamise toimingu rakendama manifestid ja mingi sidumine, mis:

  • kontrollib objekti olemasolu klastris,
  • teostab esialgse ressursi loomise,
  • värskendab või kustutab selle.

Värskendamisel pidage meeles ressurss võib olla muutunud viimasest saadik get ja tegeleb automaatselt optimistliku lukustamise juhtumiga – tehke korduvaid värskendamiskatseid.

Miks aga ratast uuesti leiutada, kui kube-apiserver pakub ressursside värskendamiseks teist võimalust: operatsiooni patch, mis vabastab kasutaja mõnest kirjeldatud probleemist?

Plaaster

Nüüd jõuame plaastrite juurde.

Plaastrid on peamine viis Kubernetese olemasolevate objektide muudatuste rakendamiseks. Operatsioon patch see töötab nii:

  • kube-apiserveri kasutaja peab saatma JSON-vormingus paiga ja määrama objekti,
  • ja apiserver ise tegeleb objekti hetkeseisuga ja viib selle vajalikule kujule.

Optimistlik lukustamine pole sel juhul vajalik. See toiming on pigem deklaratiivne kui asendamine, kuigi alguses võib see tunduda vastupidine.

Seega:

  • operatsiooni kasutades create loome objekti Giti manifesti järgi,
  • abiga delete — kustutada, kui objekti pole enam vaja,
  • abiga patch — muudame objekti, viies selle Gitis kirjeldatud kujule.

Selleks tuleb aga luua õige plaaster!

Kuidas plaastrid Helm 2-s töötavad: 2-way-merge

Väljalase esmakordsel installimisel teostab Helm toimingu create diagrammiressursside jaoks.

Iga ressursi Helmi väljalase värskendamisel tehke järgmist.

  • võtab arvesse plaastrit eelmise diagrammi ressursiversiooni ja praeguse diagrammi versiooni vahel,
  • rakendab seda plaastrit.

Me nimetame seda plaastrit Kahesuunaline liitmisplaaster, sest selle loomisega on seotud 2 manifesti:

  • ressursi manifest eelmisest versioonist,
  • ressursi manifest praegusest ressursist.

Operatsiooni eemaldamisel delete in kube apiserver kutsutakse ressurssidele, mis olid deklareeritud eelmises versioonis, kuid mida ei deklareeritud praeguses.

Kahesuunalise ühendamise plaastri lähenemisel on probleem: see viib sünkroonist väljas ressursi tegeliku olekuga klastris ja manifestiga Gitis.

Probleemi illustreerimine näitega

  • Gitis salvestab diagramm manifesti, milles väli image Kasutuselevõtt on oluline ubuntu:18.04.
  • Kasutaja kaudu kubectl edit muutis selle välja väärtuseks ubuntu:19.04.
  • Helmi diagrammi uuesti juurutamisel ei genereeri plaastrit, sest põld image versiooni eelmises versioonis ja praeguses graafikus on samad.
  • Pärast ümberpaigutamist image jäänused ubuntu:19.04, kuigi diagramm ütleb ubuntu:18.04.

Saime desünkroniseerimise ja kaotasime deklaratiivsuse.

Mis on sünkroniseeritud ressurss?

Üldiselt täielik Töötavas klastris oleva ressursi manifesti ja Giti manifesti vahel on võimatu vastet leida. Kuna tõelises manifestis võivad olla teenuse annotatsioonid/sildid, täiendavad konteinerid ja muud andmed, mida mõned kontrollerid lisavad ja eemaldavad ressursist dünaamiliselt. Me ei saa ega taha neid andmeid Gitis hoida. Siiski tahame, et Gitis selgesõnaliselt määratud väljad võtaksid kasutuselevõtul sobivad väärtused.

See osutub nii üldiseks sünkroniseeritud ressursi reegel: ressursi väljastamisel saate muuta või kustutada ainult neid välju, mis on Giti manifestis selgesõnaliselt määratud (või olid määratud eelmises versioonis ja nüüd kustutatakse).

Kahesuunaline liitmisplaaster

keskne idee Kahesuunaline liitmisplaaster: loome paiga Gitist pärit manifesti viimati rakendatud versiooni ja Giti manifesti sihtversiooni vahel, võttes arvesse käimasoleva klastri manifesti praegust versiooni. Saadud plaaster peab vastama sünkroonitud ressursi reeglile:

  • uued sihtversioonile lisatud väljad lisatakse paiga abil;
  • plaastri abil lähtestatakse viimati rakendatud versioonis varem olemas olnud väljad, mida sihtversioonis ei eksisteerinud;
  • paiga abil värskendatakse objekti praeguses versioonis olevaid välju, mis erinevad manifesti sihtversioonist.

Sellel põhimõttel genereerib see plaastreid kubectl apply:

  • manifesti viimati rakendatud versioon salvestatakse objekti enda annotatsioonis,
  • sihtmärk - võetud määratud YAML-failist,
  • praegune on töötavast klastrist.

Nüüd, kui oleme teooria välja selgitanud, on aeg teile rääkida, mida me werfis tegime.

Muudatuste rakendamine werfile

Varem kasutas werf, nagu Helm 2, kahesuunalisi liitmisplaastreid.

Parandage plaaster

Uut tüüpi plaastritele - 3-way-merge - üleminekuks võtsime esimese sammuna kasutusele nn. parandusplaastrid.

Juurutamisel kasutatakse standardset 2-way-merge plaastrit, kuid werf genereerib lisaks paiga, mis sünkroniseerib ressursi tegeliku oleku Gitis kirjutatuga (selline plaaster luuakse sama ülalkirjeldatud sünkroniseeritud ressursi reegli abil) .

Kui toimub desünkroniseerimine, saab kasutaja juurutamise lõpus HOIATUSE koos vastava teate ja paigaga, mis tuleb ressursi sünkroonitud vormile viimiseks rakendada. See plaaster on registreeritud ka spetsiaalses annotatsioonis werf.io/repair-patch. Eeldatakse, et kasutaja käed ise rakendab seda plaastrit: werf ei rakenda seda üldse.

Paranduspaikade genereerimine on ajutine meede, mis võimaldab testida kolmesuunalise liitmise põhimõttel põhinevate paikade loomist, kuid ei rakenda neid plaastreid automaatselt. Hetkel on see töörežiim vaikimisi lubatud.

Kolmesuunaline liitmisplaaster ainult uutele väljaannetele

Alates 1. detsembrist 2019 algavad werfi beeta- ja alfaversioonid vaikimisi kasutage täieõiguslikke 3-suunalisi liitmisplaastreid, et rakendada muudatusi ainult uutele Helmi väljalasetele, mis on välja antud werfi kaudu. Olemasolevates väljaannetes jätkatakse kahesuunalise ühendamise ja parandamise paikade lähenemisviisi kasutamist.

Seda töörežiimi saab selgesõnaliselt lubada seadistustega WERF_THREE_WAY_MERGE_MODE=onlyNewReleases nüüd.

Märkus: funktsioon ilmus werfis üle mitme väljalase: alfakanalis sai see valmis versiooniga v1.0.5-alpha.19, ja beetakanalis - koos v1.0.4-beeta.20.

Kolmesuunaline liitmisplaaster kõigi väljaannete jaoks

Alates 15. detsembrist 2019 hakkavad werfi beeta- ja alfaversioonid muudatuste rakendamiseks kõikidele versioonidele vaikimisi kasutama täielikke kolmesuunalisi liitmisplaastreid.

Seda töörežiimi saab selgesõnaliselt lubada seadistustega WERF_THREE_WAY_MERGE_MODE=enabled nüüd.

Mida teha ressursside automaatse skaleerimisega?

Kubernetesis on 2 tüüpi automaatset skaleerimist: HPA (horisontaalne) ja VPA (vertikaalne).

Horisontaalne valib automaatselt koopiate arvu, vertikaalne - ressursside arvu. Nii koopiate arv kui ka ressursinõuded on määratletud ressursi manifestis (vt Ressursi manifest). spec.replicas või spec.containers[].resources.limits.cpu, spec.containers[].resources.limits.memory и teised).

Probleem: kui kasutaja konfigureerib diagrammis ressursi nii, et see määrab ressurssidele või koopiatele teatud väärtused ja selle ressursi jaoks on lubatud automaatsed skaleerijad, lähtestab werf iga juurutusega need väärtused diagrammi manifestis kirjas olevatele väärtustele. .

Probleemile on kaks lahendust. Alustuseks on kõige parem vältida automaatse skaleeritud väärtuste selgesõnalist määramist diagrammi manifestis. Kui see valik mingil põhjusel ei sobi (näiteks seetõttu, et diagrammis on mugav seada algsed ressursipiirangud ja koopiate arv), pakub werf järgmisi märkusi:

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

Kui selline märkus on olemas, ei lähtesta werf vastavaid väärtusi igal juurutamisel, vaid määrab need alles siis, kui ressurss on algselt loodud.

Lisateavet leiate projekti dokumentatsioonist HPA и VPA.

Keelake kolmesuunalise liitmise plaastri kasutamine

Kasutaja saab praegu keskkonnamuutujate abil keelata werf-is uute paikade kasutamise WERF_THREE_WAY_MERGE_MODE=disabled. Siiski alustades Alates 1. märtsist 2020 see keeld enam ei kehti. ja on võimalik kasutada ainult kolmesuunalisi liitmisplaastreid.

Ressursside kasutuselevõtt werfis

Kolmesuunaliste liitmispaikadega muudatuste rakendamise meetodi valdamine võimaldas meil kohe rakendada sellist funktsiooni nagu klastris olemasolevate ressursside kasutuselevõtt Helmi versioonis.

Helm 2-l on probleem: te ei saa lisada ressurssi diagrammi manifestidele, mis on klastris juba olemas, ilma seda ressurssi nullist uuesti loomata (vt. #6031, #3275). Õpetasime werfi olemasolevaid ressursse vabastamiseks vastu võtma. Selleks peate installima annotatsiooni ressursi praegusele versioonile töötavast klastrist (näiteks kasutades kubectl edit):

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

Nüüd tuleb ressurssi diagrammil kirjeldada ja järgmine kord, kui werf juurutab sobiva nimega väljalaske, võetakse olemasolev ressurss sellesse versiooni ja jääb selle kontrolli alla. Veelgi enam, werf viib ressursi vabastamiseks vastuvõtmise protsessis ressursi praeguse oleku töötavast klastrist diagrammil kirjeldatud olekusse, kasutades samu kolmesuunalise ühendamise plaastreid ja sünkroonitud ressursireeglit.

Märkus: seadistus WERF_THREE_WAY_MERGE_MODE ei mõjuta ressursside kasutuselevõttu - vastuvõtmise puhul kasutatakse alati 3-suunalist liitmist.

Üksikasjad - sisse dokumentatsioon.

Järeldused ja tulevikuplaanid

Loodan, et pärast seda artiklit on saanud selgemaks, mis on 3-way-merge plaastrid ja miks need nendeni jõudsid. Werfi projekti arendamise praktilisest seisukohast oli nende rakendamine järjekordne samm Helmi-laadse kasutuselevõtu parandamise suunas. Nüüd võid unustada probleemid konfiguratsiooni sünkroonimisega, mis Helm 2 kasutamisel sageli tekkisid. Samal ajal lisati Helmi väljalasele uus kasulik funktsioon juba allalaaditud Kubernetese ressursside kasutuselevõtuks.

Helmi-sarnaste juurutuste puhul on endiselt probleeme ja väljakutseid, näiteks Go-mallide kasutamine, millega jätkame tegelemist.

Teavet ressursside värskendamise meetodite ja kasutuselevõtu kohta leiate ka aadressilt sellel dokumentatsiooni lehel.

Rool 3

Erilist tähelepanu vääriv vabastatud just üleeile ilmus Helmi uus suurversioon – v3 –, mis samuti kasutab kolmesuunalisi liitmisplaastreid ja vabaneb Tillerist. Helmi uus versioon nõuab ränne olemasolevad installid, et teisendada need uue versiooni salvestusvormingusse.

Werf on omalt poolt praegu Tilleri kasutamisest lahti saanud, läinud üle 3-suunalisele ühendamisele ja lisanud palju rohkem, jäädes samal ajal ühilduvaks olemasolevate Helm 2 installidega (migreerimisskripte pole vaja käivitada). Seega, kuni werf lülitub Helm 3-le, ei kaota werfi kasutajad Helm 3 peamisi eeliseid Helm 2 ees (need on ka werfil).

Kuid werfi üleminek Helm 3 koodibaasi on vältimatu ja toimub lähitulevikus. Eeldatavasti on selleks werf 1.1 või werf 1.2 (hetkel on werfi põhiversioon 1.0; werf-i versioonimisseadme kohta lisateabe saamiseks vt siin). Selle aja jooksul on Helm 3-l aega stabiliseeruda.

PS

Loe ka meie blogist:

Allikas: www.habr.com

Lisa kommentaar