Bashkimi me tre drejtime në werf: vendosja në Kubernetes me Helm "në steroid"

Ajo që ne (dhe jo vetëm ne) prisnim prej kohësh ndodhi: werf, mjeti ynë me burim të hapur për ndërtimin e aplikacioneve dhe dorëzimin e tyre në Kubernetes, tani mbështet aplikimin e ndryshimeve duke përdorur arnimet e bashkimit me 3 drejtime! Përveç kësaj, është e mundur të adoptohen burimet ekzistuese të K8s në lëshimet e Helm pa rindërtuar këto burime.

Bashkimi me tre drejtime në werf: vendosja në Kubernetes me Helm "në steroid"

Nëse është shumë e shkurtër, atëherë vendosim WERF_THREE_WAY_MERGE=enabled — marrim vendosjen “si në kubectl apply", i pajtueshëm me instalimet ekzistuese të Helm 2 dhe madje pak më shumë.

Por le të fillojmë me teorinë: çfarë saktësisht janë arnimet e bashkimit me 3 drejtime, si dolën njerëzit me qasjen për t'i gjeneruar ato dhe pse janë të rëndësishme në proceset CI/CD me infrastrukturën e bazuar në Kubernetes? Dhe pas kësaj, le të shohim se çfarë është bashkimi me 3 drejtime në werf, cilat mënyra përdoren si parazgjedhje dhe si ta menaxhojmë atë.

Çfarë është një patch me 3 drejtime?

Pra, le të fillojmë me detyrën e nxjerrjes së burimeve të përshkruara në manifestet YAML në Kubernetes.

Për të punuar me burimet, API Kubernetes ofron operacionet e mëposhtme bazë: krijoni, korrigjoni, zëvendësoni dhe fshini. Supozohet se me ndihmën e tyre është e nevojshme të ndërtohet një përhapje e përshtatshme e vazhdueshme e burimeve në grup. Si?

komandat imperative kubectl

Qasja e parë për menaxhimin e objekteve në Kubernetes është përdorimi i komandave imperative kubectl për të krijuar, modifikuar dhe fshirë ato objekte. E thënë thjesht:

  • ekipi kubectl run ju mund të ekzekutoni Deployment ose Job:
    kubectl run --generator=deployment/apps.v1 DEPLOYMENT_NAME --image=IMAGE
  • ekipi kubectl scale — ndryshoni numrin e kopjeve:
    kubectl scale --replicas=3 deployment/mysql
  • etj

Kjo qasje mund të duket e përshtatshme në shikim të parë. Megjithatë ka probleme:

  1. Është e vështirë automatizoj.
  2. Si pasqyrojnë konfigurimin në Git? Si të rishikoni ndryshimet që ndodhin në grup?
  3. Si të sigurohet riprodhueshmëria konfigurimet në rinisje?
  4. ...

Është e qartë se kjo qasje nuk përshtatet mirë me ruajtjen e aplikacionit dhe infrastrukturës si kod (IaC; ose madje GitOps si një opsion më modern, duke fituar popullaritet në ekosistemin Kubernetes). Prandaj, këto komanda nuk morën zhvillim të mëtejshëm në kubectl.

Krijoni, merrni, zëvendësoni dhe fshini operacionet

Me fillore krijim është e thjeshtë: dërgoni manifestin në operacion create kube api dhe burimi është krijuar. Përfaqësimi YAML i manifestit mund të ruhet në Git dhe të krijohet duke përdorur komandën kubectl create -f manifest.yaml.

С heqjen gjithashtu e thjeshtë: zëvendëso të njëjtën manifest.yaml nga Git te ekipi kubectl delete -f manifest.yaml.

Operacion replace ju lejon të zëvendësoni plotësisht konfigurimin e burimit me një të ri, pa rikrijuar burimin. Kjo do të thotë që përpara se të bëni një ndryshim në një burim, është logjike të kërkoni versionin aktual me operacionin get, ndryshojeni dhe përditësoni atë me operacionin replace. Apiserver kube është i integruar mbyllje optimiste dhe nëse pas operacionit get objekti ka ndryshuar, pastaj operacioni replace nuk do të funksionojë.

Për të ruajtur konfigurimin në Git dhe për ta përditësuar atë duke përdorur zëvendësimin, duhet të kryeni operacionin get, bashkoni konfigurimin nga Git me atë që morëm dhe ekzekutoni replace. Si parazgjedhje, kubectl ju lejon vetëm të përdorni komandën kubectl replace -f manifest.yamlKu manifest.yaml — një manifest tashmë i përgatitur plotësisht (në rastin tonë, i bashkuar) që duhet të instalohet. Rezulton se përdoruesi duhet të zbatojë manifestet e bashkimit, dhe kjo nuk është një çështje e parëndësishme...

Vlen gjithashtu të theksohet se edhe pse manifest.yaml dhe ruhet në Git, ne nuk mund ta dimë paraprakisht nëse është e nevojshme të krijohet një objekt ose të përditësohet - kjo duhet të bëhet nga softueri i përdoruesit.

Total: a mund të ndërtojmë një paraqitje të vazhdueshme vetëm duke përdorur krijimin, zëvendësimin dhe fshirjen, duke siguruar që konfigurimi i infrastrukturës të ruhet në Git së bashku me kodin dhe CI/CD të përshtatshme?

Në parim mundemi... Për këtë do t'ju duhet të zbatoni operacionin e bashkimit manifeste dhe një lloj lidhjeje që:

  • kontrollon praninë e një objekti në grup,
  • kryen krijimin e burimeve fillestare,
  • e përditëson ose e fshin atë.

Kur përditësoni, ju lutemi vini re këtë burimi mund të ketë ndryshuar që nga e fundit get dhe trajtoni automatikisht rastin e mbylljes optimiste - bëni përpjekje të përsëritura për të përditësuar.

Megjithatë, pse të rishpikni rrotën kur kube-apiserver ofron një mënyrë tjetër për të përditësuar burimet: operacionin patch, e cila e lehtëson përdoruesin nga disa nga problemet e përshkruara?

copë toke

Tani arrijmë te arna.

Arnimet janë mënyra kryesore për të aplikuar ndryshime në objektet ekzistuese në Kubernetes. Operacioni patch funksionon si kjo:

  • përdoruesi i kube-apiserver duhet të dërgojë një patch në formën JSON dhe të specifikojë objektin,
  • dhe vetë apiserver do të merret me gjendjen aktuale të objektit dhe do ta sjellë atë në formën e kërkuar.

Bllokimi optimist nuk kërkohet në këtë rast. Ky operacion është më shumë deklarativ sesa zëvendësimi, megjithëse në fillim mund të duket e kundërta.

Në këtë mënyrë:

  • duke përdorur një operacion create ne krijojmë një objekt sipas manifestit nga Git,
  • me ndihmën e delete - fshini nëse objekti nuk është më i nevojshëm,
  • me ndihmën e patch — e ndryshojmë objektin, duke e sjellë në formën e përshkruar në Git.

Megjithatë, për ta bërë këtë, ju duhet të krijoni arnimi i duhur!

Si funksionojnë arnimet në Helm 2: Bashkim 2-kahësh

Kur instaloni për herë të parë një lëshim, Helm kryen operacionin create për burimet e grafikut.

Kur përditësoni një version të Helm për çdo burim:

  • merr parasysh copëzimin midis versionit të burimit nga grafiku i mëparshëm dhe versionit aktual të grafikut,
  • aplikon këtë patch.

Ne do ta quajmë këtë patch Arnimi i bashkimit me 2 drejtime, sepse 2 manifeste janë të përfshira në krijimin e tij:

  • manifest burimi nga publikimi i mëparshëm,
  • manifestimi i burimit nga burimi aktual.

Gjatë heqjes së operacionit delete në kube apiserver thirret për burime që janë deklaruar në versionin e mëparshëm, por nuk janë deklaruar në atë aktual.

Qasja e patch-it të bashkimit me dy mënyra ka një problem: çon në jashtë sinkronizimit me gjendjen reale të burimit në grup dhe manifestit në Git.

Ilustrimi i problemit me një shembull

  • Në Git, një grafik ruan një manifest në të cilin fusha image Çështjet e vendosjes ubuntu:18.04.
  • Përdoruesi nëpërmjet kubectl edit ndryshoi vlerën e kësaj fushe në ubuntu:19.04.
  • Kur ri-vendosni tabelën Helm nuk gjeneron një patch, sepse fusha image në versionin e mëparshëm të lëshimit dhe në tabelën aktuale janë të njëjta.
  • Pas ri-vendosjes image eshtra ubuntu:19.04, edhe pse grafiku thotë ubuntu:18.04.

Morëm desinkronizim dhe humbëm deklarativitetin.

Çfarë është një burim i sinkronizuar?

Në përgjithësi i plotë Është e pamundur të arrihet një përputhje midis manifestit të burimeve në një grup të ekzekutimit dhe manifestit nga Git. Sepse në një manifest të vërtetë mund të ketë shënime/etiketa shërbimi, kontejnerë shtesë dhe të dhëna të tjera që shtohen dhe hiqen nga burimi në mënyrë dinamike nga disa kontrollues. Ne nuk mund dhe nuk duam t'i mbajmë këto të dhëna në Git. Sidoqoftë, ne duam që fushat që kemi specifikuar në mënyrë eksplicite në Git të marrin vlerat e duhura pas paraqitjes.

Rezulton kaq e përgjithshme rregulli i burimeve të sinkronizuara: kur shpërndani një burim, mund të ndryshoni ose fshini vetëm ato fusha që janë specifikuar në mënyrë eksplicite në manifest nga Git (ose janë specifikuar në versionin e mëparshëm dhe tani janë fshirë).

Arnimi i bashkimit me 3 drejtime

Ideja qendrore Arnimi i bashkimit me 3 drejtime: ne krijojmë një rregullim midis versionit të fundit të aplikuar të manifestit nga Git dhe versionit të synuar të manifestit nga Git, duke marrë parasysh versionin aktual të manifestit nga grupi i ekzekutimit. Patch-i që rezulton duhet të përputhet me rregullin e burimeve të sinkronizuara:

  • fushat e reja të shtuara në versionin e synuar shtohen duke përdorur një patch;
  • fushat ekzistuese më parë në versionin e fundit të aplikuar dhe që nuk ekzistojnë në versionin e synuar rivendosen duke përdorur një patch;
  • fushat në versionin aktual të objektit që ndryshojnë nga versioni i synuar i manifestit përditësohen duke përdorur patch-in.

Është mbi këtë parim që ai gjeneron arna kubectl apply:

  • versioni i fundit i aplikuar i manifestit ruhet në shënimin e vetë objektit,
  • objektiv - marrë nga skedari i specifikuar YAML,
  • ky aktual është nga një grup që funksionon.

Tani që kemi zgjidhur teorinë, është koha t'ju tregojmë se çfarë bëmë në werf.

Zbatimi i ndryshimeve në werf

Më parë, werf, si Helm 2, përdorte arna me dy drejtime.

Patch riparimi

Për të kaluar në një lloj të ri të arnimeve - 3-way-merge - hapi i parë që prezantuam është i ashtuquajturi arna riparimi.

Gjatë vendosjes, përdoret një rregullim standard i bashkimit me dy drejtime, por werf gjithashtu gjeneron një patch që do të sinkronizonte gjendjen reale të burimit me atë që është shkruar në Git (një rregullim i tillë krijohet duke përdorur të njëjtin rregull të sinkronizuar të burimit të përshkruar më sipër) .

Nëse ndodh një desinkronizim, në fund të vendosjes përdoruesi merr një PARALAJMËRIM me një mesazh përkatës dhe një patch që duhet të aplikohet për të sjellë burimin në një formë të sinkronizuar. Ky patch regjistrohet gjithashtu në një shënim të veçantë werf.io/repair-patch. Supozohet se duart e përdoruesit сам do të aplikojë këtë patch: werf nuk do ta zbatojë fare.

Krijimi i arnimeve të riparimit është një masë e përkohshme që ju lejon të testoni në fakt krijimin e arnimeve bazuar në parimin e bashkimit me 3 drejtime, por mos i aplikoni automatikisht këto arna. Për momentin, kjo mënyrë funksionimi është aktivizuar si parazgjedhje.

Patch 3-kahëshe vetëm për publikimet e reja

Duke filluar nga 1 dhjetori 2019, fillojnë versionet beta dhe alfa të werf nga parazgjedhja përdorni arna të plota me shkrirje me 3 drejtime për të aplikuar ndryshime vetëm në versionet e reja të Helm-it të shfaqura përmes werf-it. Publikimet ekzistuese do të vazhdojnë të përdorin qasjen e bashkimit me dy drejtime + arna të riparimit.

Kjo mënyrë funksionimi mund të aktivizohet në mënyrë eksplicite duke vendosur WERF_THREE_WAY_MERGE_MODE=onlyNewReleases tani.

Shënim: funksioni u shfaq në werf gjatë disa lëshimeve: në kanalin alfa u bë gati me versionin v1.0.5-alfa.19, dhe në kanalin beta - me v1.0.4-beta.20.

Arnim me 3 drejtime për të gjitha lëshimet

Duke filluar nga 15 dhjetori 2019, versionet beta dhe alfa të werf fillojnë të përdorin si parazgjedhje arnime të plota të bashkimit me 3 drejtime për të aplikuar ndryshime në të gjitha versionet.

Kjo mënyrë funksionimi mund të aktivizohet në mënyrë eksplicite duke vendosur WERF_THREE_WAY_MERGE_MODE=enabled tani.

Çfarë duhet të bëni me shkallëzimin automatik të burimeve?

Ekzistojnë 2 lloje të shkallëzimit automatik në Kubernetes: HPA (horizontale) dhe VPA (vertikale).

Horizontal zgjedh automatikisht numrin e kopjeve, vertikale - numrin e burimeve. Si numri i kopjeve ashtu edhe kërkesat për burime janë të specifikuara në manifestin e burimeve (shih Manifestin e Burimeve). spec.replicas ose spec.containers[].resources.limits.cpu, spec.containers[].resources.limits.memory и të tjerët).

Problemi: nëse një përdorues konfiguron një burim në një grafik në mënyrë që të specifikojë vlera të caktuara për burimet ose kopjet dhe shkallëzuesit automatikë janë aktivizuar për këtë burim, atëherë me çdo vendosje werf do t'i rivendosë këto vlera në atë që është shkruar në manifestin e grafikut. .

Ka dy zgjidhje për problemin. Për të filluar, është më mirë të shmangni specifikimin e qartë të vlerave të shkallëzuara automatike në manifestin e grafikut. Nëse ky opsion nuk është i përshtatshëm për ndonjë arsye (për shembull, sepse është i përshtatshëm për të vendosur kufijtë fillestarë të burimeve dhe numrin e kopjeve në grafik), atëherë werf ofron shënimet e mëposhtme:

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

Nëse një shënim i tillë është i pranishëm, werf nuk do të rivendosë vlerat përkatëse në çdo vendosje, por do t'i vendosë ato vetëm kur burimi të krijohet fillimisht.

Për më shumë detaje, shihni dokumentacionin e projektit për HPA и VPA.

Ndaloni përdorimin e patch-it me 3 drejtime

Përdoruesi aktualisht mund të ndalojë përdorimin e arnimeve të reja në werf duke përdorur një variabël mjedisi WERF_THREE_WAY_MERGE_MODE=disabled. Megjithatë, duke filluar Nga data 1 mars 2020, ky ndalim nuk do të zbatohet më. dhe do të jetë e mundur vetëm përdorimi i arnimeve me 3 drejtime.

Adoptimi i burimeve në werf

Përvetësimi i metodës së aplikimit të ndryshimeve me arnimet e bashkimit me 3 drejtime na lejoi të zbatonim menjëherë një veçori të tillë si miratimi i burimeve ekzistuese në grup në lëshimin e Helm.

Helm 2 ka një problem: nuk mund të shtoni një burim në manifestimet e grafikut që tashmë ekziston në grup pa e rikrijuar këtë burim nga e para (shih. # 6031, # 3275). Ne i mësuam werf-it të pranonte burimet ekzistuese për lirim. Për ta bërë këtë, duhet të instaloni një shënim në versionin aktual të burimit nga grupi i ekzekutimit (për shembull, duke përdorur kubectl edit):

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

Tani burimi duhet të përshkruhet në tabelë dhe herën tjetër që werf vendos një version me emrin e duhur, burimi ekzistues do të pranohet në këtë version dhe do të mbetet nën kontrollin e tij. Për më tepër, në procesin e pranimit të një burimi për lëshim, werf do të sjellë gjendjen aktuale të burimit nga grupi i ekzekutimit në gjendjen e përshkruar në grafik, duke përdorur të njëjtat arna me 3 drejtime dhe rregullin e burimeve të sinkronizuara.

Shënim: vendosja WERF_THREE_WAY_MERGE_MODE nuk ndikon në adoptimin e burimeve - në rastin e adoptimit, përdoret gjithmonë një patch me bashkim 3-kahësh.

Detajet - në dokumentacionin.

Konkluzionet dhe planet e ardhshme

Shpresoj që pas këtij artikulli të jetë bërë më e qartë se çfarë janë arnimet e bashkimit me 3 drejtime dhe pse erdhën tek ato. Nga pikëpamja praktike e zhvillimit të projektit werf, zbatimi i tyre ishte një hap tjetër drejt përmirësimit të dislokimit të ngjashëm me Helm. Tani mund të harroni problemet me sinkronizimin e konfigurimit, të cilat shpesh lindnin kur përdorni Helm 2. Në të njëjtën kohë, një veçori e re e dobishme e adoptimit të burimeve tashmë të shkarkuara të Kubernetes u shtua në versionin e Helm.

Ka ende disa çështje dhe sfida me vendosjet e ngjashme me Helm, siç është përdorimi i shablloneve Go, të cilat ne do të vazhdojmë t'i trajtojmë.

Informacion rreth metodave të përditësimit të burimeve dhe miratimit mund të gjenden gjithashtu në këtë faqe dokumentacioni.

Helm 3

I denjë për shënim të veçantë liruar vetëm një ditë tjetër një version i ri kryesor i Helm - v3 - i cili gjithashtu përdor arna me bashkim me 3 drejtime dhe heq qafe Tiller. Versioni i ri i Helm kërkon migrimet instalimet ekzistuese për t'i kthyer ato në formatin e ri të ruajtjes së lëshimit.

Werf, nga ana e tij, aktualisht ka hequr qafe përdorimin e Tiller, ka kaluar në bashkimin me 3 drejtime dhe ka shtuar me shume, ndërkohë që mbetet i pajtueshëm me instalimet ekzistuese të Helm 2 (nuk ka nevojë të ekzekutohet skriptet e migrimit). Prandaj, derisa werf të kalojë në Helm 3, përdoruesit e werf nuk i humbasin avantazhet kryesore të Helm 3 ndaj Helm 2 (werf gjithashtu i ka ato).

Megjithatë, kalimi i werf në bazën e kodit Helm 3 është i pashmangshëm dhe do të ndodhë në të ardhmen e afërt. Me sa duket kjo do të jetë werf 1.1 ose werf 1.2 (për momentin, versioni kryesor i werf është 1.0; për më shumë informacion rreth pajisjes së versionit werf, shihni këtu). Gjatë kësaj kohe, Helm 3 do të ketë kohë të stabilizohet.

PS

Lexoni edhe në blogun tonë:

Burimi: www.habr.com

Shto një koment