Më 27 maj në sallën kryesore të konferencës DevOpsConf 2019, që po zhvillohet në kuadër të festivalit , në kuadër të sesionit "Shpërndarja e vazhdueshme", u mbajt një kumtesë "werf - mjeti ynë për CI/CD në Kubernetes". Ajo flet për ato problemet dhe sfidat me të cilat përballet çdo njeri gjatë deploimit në Kubernetes, si dhe për nuancat që mund të mos duken menjëherë. Duke analizuar posibilitetet e zgjidhjeve, ne tregojmë se si është realizuar në mjetin Open Source .
QĂ« nga paraqitja, utilita jonĂ« (e njohur mĂ« parĂ« si dapp) ka kaluar njĂ« pikĂ« historike nĂ« 1000 yje nĂ« GitHub â shpresojmĂ« se komuniteti nĂ« rritje i pĂ«rdoruesve tĂ« saj do tĂ« lehtĂ«sojĂ« jetĂ«n e shumĂ« inxhinierĂ«ve DevOps.

Prandaj, paraqesim (~47 minuta, shumë informative më shumë se artikulli) dhe një përmbledhje themelore të saj në formë tekstuale. Le të fillojmë!
Dërgimi i kodit në Kubernetes
Kumtesa do tĂ« flasĂ« mĂ« shumĂ« jo pĂ«r werf, por pĂ«r CI/CD nĂ« Kubernetes, duke nĂ«nkuptuar se softi ynĂ« Ă«shtĂ« paketuar nĂ« konteinerĂ« Docker (kĂ«tĂ« e kam folur nĂ« ), dhe K8s do tĂ« pĂ«rdoret pĂ«r ta nisur atĂ« nĂ« prodhim (pĂ«r kĂ«tĂ« â nĂ« ).
Si duket dërgimi në Kubernetes?
- Ka një repozitor Git me kodin dhe udhëzimet për ndërtimin e tij. Aplikacioni ndërtohet në një imazh Docker dhe publikohet në Docker Registry.
- Në të njëjtin repozitor ka edhe udhëzime për mënyrën e deploimit dhe nisjes së aplikacionit. Në fazën e deploimit, këto udhëzime dërgohen në Kubernetes, i cili merr imazhin e nevojshëm nga registry dhe e nis atë.
- Për më tepër, zakonisht ka teste. Disa prej tyre mund të kryhen gjatë publikimit të imazhit. Gjithashtu mund të (sipër udhëzimeve të njëjta) rrisni një kopje të aplikacionit (në një hapësirë emri të veçantë K8s ose në një klaster të veçantë) dhe të kryeni testet aty.
- Në fund, nevojitet një sistem CI që merr ngjarje nga Git (ose klikime butonash) dhe thërret të gjitha fazat e caktuara: ndërtim, publikim, deploim, testim.

Këtu ka disa vërejtje të rëndësishme:
- Duke qenë se ne kemi një infrastrukturë të pandryshueshme (infrastructure e pandryshueshme), imazhi i aplikacionit, që përdoret në të gjitha fazat (staging, prodhim etj.), duhet të jetë një. Për më shumë informacion mbi këtë me shembuj kam folur .
- Duke qenë se ndiqnim qasjen infrastrukturë si kod (IaC), kodi i aplikacionit, udhëzimet për ndërtimin dhe nisjen e tij duhet të jenë pikërisht në një repozitor. Për më shumë mbi këtë - shih në .
- Faza e dorĂ«zimit (delivery) zakonisht e shohim kĂ«shtu: aplikacioni Ă«shtĂ« ndĂ«rtuar, testuar, lĂ«shuar (fazĂ« release) dhe gjithçka â dĂ«rgesa u realizua. Por nĂ« tĂ« vĂ«rtetĂ«, pĂ«rdoruesi merr atĂ« qĂ« ju publikoni, jo kur e çuat atĂ« nĂ« production, dhe kur ai ka mundĂ«sinĂ« tĂ« hyjĂ« aty dhe ky production funksionoi. Prandaj, mendoj se zinxhiri i dĂ«rgesĂ«s pĂ«rfundon vetĂ«m nĂ« fazĂ«n e operimit (run), dhe nĂ«se flasim mĂ« saktĂ«, madje nĂ« atĂ« moment, kur kodi u hoq nga production (duke e zĂ«vendĂ«suar atĂ« me njĂ« tĂ« ri).
Le të kthehemi te skema e dërgesës të përmendur më sipër në Kubernetes: ajo u shpik jo vetëm nga ne, por edhe nga praktisht çdo kush që është marrë me këtë problem. E vërteta është se tani ky model quhet GitOps (më shumë për termin dhe idetë që qëndrojnë pas tij mund të lexoni ). Le të shohim fazat e skemës.
Faza e ndërtimit (build)
Duket se çfarĂ« mund tĂ« tregosh nĂ« vitin 2019 pĂ«r ndĂ«rtimin e imazheve Docker, kur tĂ« gjithĂ« dinĂ« tĂ« shkruajnĂ« Dockerfile dhe tĂ« launch docker build?.. ĐĐŸŃ ĐœŃĐ°ĐœŃŃ, ĐœĐ° ĐșĐŸŃĐŸŃŃĐ” Ń
ĐŸŃĐ”Đ»ĐŸŃŃ Đ±Ń ĐŸĐ±ŃаŃĐžŃŃ ĐČĐœĐžĐŒĐ°ĐœĐžĐ”:
- Pesha e imazhit ka rëndësi, prandaj përdorni , për të lënë në imazh vetëm atë që është në të vërtetë e nevojshme për funksionimin e aplikacionit.
- Numri i shtresave duhet minimizuar, duke i kombinuar zinxhirët e
RUN-komandave sipas kuptimit. - Megjithatë, kjo shton probleme në debugging, sepse kur ndodhi një gabim në ndërtim, duhet të gjejmë atë komandë të nevojshme nga zinxhiri që shkaktoi problemin.
- Shpejtësia e ndërtimit është e rëndësishme, sepse duam të nxjerrim ndryshime shpejt dhe të shohim rezultatin. Për shembull, nuk është dëshirë të ripohojmë varësitë në bibliotekat e gjuhës në çdo ndërtim të aplikacionit.
- Shpesh nga një Git-repository kërkohen shumë imazhe, që mund të zgjidhet me një grup Dockerfile-ësh (ose faza të emërtuara në një skedë) dhe një skript Bash me ndërtimin e tyre në mënyrë sekondare.
Kjo ishte vetëm maja e ajsbergut me të cilin përballen të gjithë. Por ekzistojnë edhe probleme të tjera, në veçanti:
- Shpesh në fazën e ndërtimit na nevojitet të montojmë (për shembull, të keshojmë rezultatin e komandës së tipit apt në një direktor të jashtëm).
- Ne duam Ansible ndryshe nga shkruani në shell.
- Ne duam të ndërtojmë pa Docker (pse na nevojitet një makinë virtuale shtesë, në të cilën duhet të gjitha të konfigurohen për këtë, kur tashmë ekziston një klaster Kubernetes, në të cilin mund të nisim konteinerit?).
- Ndërtimi paralel, i cili mund të kuptohet në mënyra të ndryshme: komandat e ndryshme nga Dockerfile (nëse përdoret multi-stage), disa komite të një repository, disa Dockerfile.
- NdĂ«rtimi i shpĂ«rndarĂ«: ne duam tĂ« mbledhim diçka nĂ« podâash, tĂ« cilat janĂ« "efemerike", pasi ata humbasin cache, pra â duhet ta ruajmĂ« diku veçmas.
- Në fund, unë e quajta majën e dëshirave automagji: do të ishte përsosmërisht të hysh në depo, të shkruash ndonjë komandë dhe të marrësh një imazh të gatshëm, i ndërtuar me kuptimin se si dhe çfarë duhet bërë siç duhet. Megjithatë, personalisht nuk jam i sigurt se të gjitha nuancat mund të parashikohen kështu.
Dhe ja, ka projekte:
- â ndĂ«rtuesi nga kompania Docker Inc (tani i integruar nĂ« versionet aktuale tĂ« Docker), e cila pĂ«rpiqet tĂ« zgjidhĂ« tĂ« gjitha kĂ«to probleme;
- â ndĂ«rtuesi nga Google, qĂ« lejon ndĂ«rtimin pa Docker;
- â pĂ«rpjekja e CNCF pĂ«r tĂ« bĂ«rĂ« automagjinĂ« dhe, nĂ« veçanti, njĂ« zgjidhje interesante me rebase pĂ«r shtresa;
- dhe ende shumĂ« utilitete tĂ« tjerĂ«, tĂ« tillĂ« si , âŠ
⊠dhe shihni sa shumĂ« yje kanĂ« nĂ« GitHub. Pra, nga njĂ«ra anĂ«, docker build ka dhe mund tĂ« bĂ«jĂ« diçka, por nĂ« fakt çështja nuk Ă«shtĂ« e zgjidhur deri nĂ« fund â dĂ«shmi pĂ«r kĂ«tĂ« Ă«shtĂ« zhvillimi paralel i ndĂ«rtuesve alternativĂ«, çdo njĂ«ri prej tĂ« cilĂ«ve zgjidh njĂ« pjesĂ« tĂ« problemeve.
Ndërtimi në werf
KĂ«shtu arritĂ«m te (mĂ« parĂ« si dapp) â utiliteti Open Source i kompanisĂ« "Flant", qĂ« ne e zhvillojmĂ« tashmĂ« pĂ«r shumĂ« vite. E gjithĂ« kjo filloi rreth 5 vjet mĂ« parĂ« me skriptat Bash, qĂ« optimizonin ndĂ«rtimin e Dockerfile-ve, dhe dy vitet e fundit zhvillohet njĂ« projekt i plotĂ« me njĂ« depo tĂ« vet. (fillimisht nĂ« Ruby, dhe pastaj nĂ« Go, dhe njĂ«kohĂ«sisht u rinovua). ĂfarĂ« probleme tĂ« ndĂ«rtimit zgjidhen nĂ« werf?

Problemet e ngjyrosura me blu janë tashmë të realizuara, ndërtimi paralel është bërë brenda një hosti, dhe problemet e shënuara me të verdhë planifikojmë t'i përfundojmë deri në fund të verës.
Faza e publikimit në registry (publish)
MblodhĂ«m docker push⊠â çfarĂ« mund tĂ« jetĂ« e komplikuar pĂ«r tĂ« ngarkuar njĂ« imazh nĂ« registry? Dhe kĂ«tu lind pyetja: "Cila etiketĂ« t'i japim imazhit?" Ajo lind pĂ«r shkak se kemi Gitflow (ose njĂ« strategji tjetĂ«r tĂ« Git-it) dhe Kubernetes, dhe industria pĂ«rpiqet qĂ« ajo qĂ« ndodh nĂ« Kubernetes tĂ« pasojĂ« atĂ« qĂ« bĂ«het nĂ« Git. Sepse Git â Ă«shtĂ« burimi ynĂ« i vetĂ«m i tĂ« vĂ«rtetĂ«s.
ĂfarĂ« ka tĂ« vĂ«shtirĂ« nĂ« kĂ«tĂ«? TĂ« garantojmĂ« riprodhueshmĂ«rinĂ«: nga commiti nĂ« Git, i cili pĂ«r natyrĂ«n e tij Ă«shtĂ« i pandryshueshĂ«m (immutable), deri nĂ« imazhin Docker, i cili duhet tĂ« ruhet i tillĂ«.
Na është gjithashtu e rëndësishme të përcaktojmë origjinën, sepse dëshirojmë të kuptojmë nga cili commit është ndërtuar aplikacioni, i cili është e hapur në Kubernetes (ateherë mund të bëjmë diff dhe gjëra të ngjashme).
Strategjitë e etiketimit
E para është e thjeshtë git tag. Kemi një regjistrim me imazhin, i etiketuar si 1.0. Në Kubernetes ka një stage dhe prodhim, ku ky imazh është shkarkuar. Në Git ne bëjmë commit dhe në një moment vendosim një etiketë 2.0. E grumbullojmë atë sipas udhëzimeve nga repository dhe e vendosim në regjistrin me etiketën 2.0. E dërgojmë në stage dhe, nëse gjithçka shkon mirë, më pas në prodhim.

Problemi me këtë qasje është se fillimisht vendosëm etiketën dhe vetëm pastaj e testuam dhe e dërguam. Pse? Së pari, është thjesht ilogjike: ne po lëshojmë një version të softuerit, të cilin nuk e kemi verifikuar ende (nuk mund ta bëjmë ndryshe, pasi për ta verifikuar, ne duhet të vendosim etiketën). Së dyti, një rrugë e tillë nuk përputhet me Gitflow.
Opcioni i dytĂ« Ă«shtĂ« git commit + tag. NĂ« degĂ«n master ka njĂ« etiketĂ« 1.0; pĂ«r tĂ«, nĂ« regjistrim â imazhi, i implementuar nĂ« prodhim. PĂ«r mĂ« tepĂ«r, nĂ« klasterin Kubernetes ka skema preview dhe staging. MĂ« pas ndjekim Gitflow: nĂ« degĂ«n kryesore pĂ«r zhvillim (develop) bĂ«jmĂ« karakteristika tĂ« reja, duke rezultuar nĂ« njĂ« commit me identifikuesin #c1. E grumbullojmĂ« dhe e publikojmĂ« nĂ« regjistrin, duke pĂ«rdorur kĂ«tĂ« identifikues (#c1). Me tĂ« njĂ«jtin identifikues e dĂ«rgojmĂ« nĂ« preview. Po ashtu, bĂ«jmĂ« me commitet #c2 dhe #c3.
Kur e kuptojmë se kemi mjaft karakteristika, fillojmë të stabilizojmë gjithçka. Në Git krijojmë një degë release_1.1 (bazuar në #c3 nga develop). Nuk do të nevojitet të grumbullojmë këtë lëshim, sepse është bërë në fazën e mëparshme. Prandaj mund ta dërgojmë thjesht në staging. Ndërsa korrigjojmë gabimet në #c4 dhe po ashtu e dërgojmë në staging. Paralelisht, në të njëjtën kohë zhvillohet puna në develop, ku ndryshimet e ndihen nganjëherë nga release_1.1. Në një moment e marrim commit-in e grumbulluar dhe të dërguar në staging, me të cilin jemi të kënaqur (#c25).
Atëherë bëjmë merge (me fast-forward) të degës së lëshimit (release_1.1) në master. Vendosim në këtë commit një etiketë me versionin e ri (1.1). Por ky imazh është tashmë ndërtuar në regjistër, prandaj, për të mos e ndërtuar përsëri, ne thjesht shtojmë një etiketë të dytë në imazhin ekzistues (tani ai në regjistër ka etiketat #c25 dhe 1.1). Pas kësaj, e dërgojmë në prodhim.
Ka njĂ« disavantazh, qĂ« nĂ« staging Ă«shtĂ« diskutuar njĂ« imazh (#c25), ndĂ«rsa nĂ« prodhim â siç duket - njĂ« tjetĂ«r (1.1), por ne e dimĂ« se 'fizikisht' Ă«shtĂ« e njĂ«jta imazh nga regjistri.

Megjithatë, disavantazhi i vërtetë është se nuk ka mbështetje për merge commit, duhet ta bëjmë fast-forward.
Mund të shkojmë më tej dhe të bëjmë një trik... Le të shqyrtojmë një shembull të një Dockerfile të thjeshtë:
FROM ruby:2.3 as assets
RUN mkdir -p /app
WORKDIR /app
COPY . ./
RUN gem install bundler && bundle install
RUN bundle exec rake assets:precompile
CMD bundle exec puma -C config/puma.rb
FROM nginx:alpine
COPY --from=assets /app/public /usr/share/nginx/www/publicDo ta ndërtojmë këtë skedar sipas kësaj parimi, që do të marrim:
- SHA256 nga identifikuesit e imazheve të përdorura (
ruby:2.3dhenginx:alpine), të cilat janë shumicat kontrolluese të përmbajtjes së tyre; - të gjitha komandat (
RUN,CMDetj.); - SHA256 nga skedarët që janë shtuar.
⊠dhe do të marrim shumicën kontrolluese (sërish SHA256) nga një skedar i tillë. Kjo nënshkrim e gjithçkaje që përcakton përmbajtjen e imazhit Docker.

Të kthehemi te skema dhe në vend të komiteteve do të përdorim një nënshkrim të tillë, dmth. të etiketojmë imazhet me nënshkrime.

Tani, kur të nevojitet, për shembull, të 'bashkohen' ndryshimet nga lëshimi në master, mund të kryejmë një komitet të vërtetë të bashkimit: do të ketë një identifikues tjetër, por të njëjtën nënshkrim. Me të njëjtin identifikues do ta lëshojmë imazhin edhe në production.
Mungesa Ă«shtĂ« se tani nuk do tĂ« jetĂ« e mundur tĂ« pĂ«rcaktojmĂ« se cili komitet Ă«shtĂ« çuar nĂ« production â shumicat kontrolluese punojnĂ« vetĂ«m nĂ« njĂ« drejtim. Kjo problem zgjidhet me njĂ« shtresĂ« shtesĂ« me metadata â do tĂ« flas mĂ« shumĂ« pĂ«r kĂ«tĂ« mĂ« vonĂ«.
Etiketimi në werf
NĂ« werf ne shkuam edhe mĂ« tej dhe po pĂ«rgatitemi tĂ« bĂ«jmĂ« njĂ« ndĂ«rtim tĂ« shpĂ«rndarĂ« me cache, i cili nuk ruhet nĂ« njĂ« makinĂ«... Pra, ne po ndĂ«rtuam imazhe Docker tĂ« dy llojeve, tĂ« cilat i quajmĂ« ) â njĂ« njĂ«si organizimi e pipeline-it, pĂ«rmban 1+ detyrĂ«, dhe image.
Në depozita Git werf ruhen udhëzime specifike për ndërtim, që përshkruajnë fazat e ndryshme të ndërtimit (beforeInstall, instalo, paraSetup, setup). Ne e ndërtuam imazhin e parë të fazës me nënshkrim, e cila është përcaktuar si shumicë kontrolluese e hapave të parë. Pastaj shtojmë kodin burimor, për imazhin e ri të fazës e llogarisim shumicën kontrolluese... Këto operacione përsëriten për të gjitha fazat, duke rezultuar në një grup imazhesh të fazave. Pastaj krijojmë imazhin përfundimtar, i cili përmban gjithashtu metadata mbi prejardhjen e tij. Dhe ky imazh ne e etiketojmë në mënyra të ndryshme (detaje më vonë).

Le tĂ« ndodhĂ« qĂ« njĂ« angazhim i ri tĂ« shfaqet, ku Ă«shtĂ« ndryshuar vetĂ«m kodi i aplikacionit. ĂfarĂ« do tĂ« ndodhĂ«? Do tĂ« krijohet njĂ« patch pĂ«r ndryshimet e kodit, njĂ« imazh i ri stage do tĂ« pĂ«rgatitet. NĂ«nshkrimi i tij do tĂ« pĂ«rcaktohet si njĂ« kontrolli i shumĂ«s sĂ« vjetĂ«r tĂ« imazhit tĂ« stage dhe patch-eve tĂ« reja. Nga ky imazh do tĂ« formohet dhe njĂ« imazh final i ri.
Prandaj, imazhet stage janë një kesh që mund të ruhet në mënyrë të shpërndarë, ndërsa imazhet që krijohen prej tij ngarkohen në Docker Registry.

Pastrimi i registry
Nuk do të flasim për fshirjen e shtresave që kanë mbetur të varura pas etiketave të fshira, kjo është një mundësi standarde e Docker Registry vetë. Bëhet fjalë për situatën kur akumulohet një numër i madh i etiketave Docker dhe ne e kuptojmë se një pjesë e tyre nuk na nevojitet më, por ata po zënë hapësirë (dhe/ose ne po paguajmë për të).
Cilat janë strategjitë e pastrimit?
- Mund të mos bësh asgjë në pastrim. Ndonjëherë është gjithashtu më e lehtë të paguash për hapësirën e tepërt se sa të zgjidhesh nga një klumb i madh i etiketave. Por kjo funksionon vetëm deri në një pikë të caktuar.
- Rimbus i plotĂ«. NĂ«se fshihen tĂ« gjitha imazhet dhe rikonstruktivohen vetĂ«m ato aktuese nĂ« sistemin CI, atĂ«herĂ« mund tĂ« ndodhĂ« njĂ« problem. NĂ«se kontejneri do tĂ« rinisĂ« nĂ« prodhim, pĂ«r tĂ« do tĂ« ngarkohet njĂ« imazh i ri â njĂ« qĂ« nuk Ă«shtĂ« testuar nga askush. Kjo shkatĂ«rron idenĂ« e infrastrukturĂ«s sĂ« pandryshueshme.
- Blu-jeshile. NjĂ« registry filloi tĂ« mbushet â ngarkohet imazhe nĂ« njĂ« tjetĂ«r. E njĂ«jta problematikĂ« si nĂ« mĂ«nyrĂ«n e mĂ«parshme: nĂ« cilĂ«n pikĂ« mund tĂ« pastroni atĂ« registry qĂ« filloi tĂ« mbushej?
- Sipas kohĂ«s. TĂ« fshihen tĂ« gjitha imazhet mĂ« tĂ« vjetra se 1 muaj? Por patjetĂ«r do tĂ« ketĂ« njĂ« shĂ«rbim qĂ« nuk Ă«shtĂ« pĂ«rditĂ«suar pĂ«r njĂ« muajâŠ
- Dore të përcaktojë se çfarë mund të fshihet tashmë.
Ka dy mundësi të vërteta jetësore: të mos pastroni ose një kombinim nga blu-jeshil + dorazi. Në këtë rast, bëhet fjalë për sa vijon: kur e kuptoni se është koha për të pastruar registry, krijoni një të ri dhe shtoni të gjitha imazhet e reja në të për një periudhë, për shembull, një muaj. Pas një muaji shikoni se cilat pod-i në Kubernetes akoma përdorin registry të vjetër, dhe i transferoni ato gjithashtu në registry të ri.
ĂfarĂ« kemi arritur nĂ« werf? ĐŃ ŃĐŸĐ±ĐžŃĐ°Đ”ĐŒ:
- Git head: tĂ« gjitha etiketat, tĂ« gjitha degĂ«t, â duke supozuar se gjithçka qĂ« Ă«shtĂ« etiketuar nĂ« Git, na nevojitet dhe nĂ« imazhe (dhe nĂ«se jo, atĂ«herĂ« duhet fshirĂ« nĂ« vetĂ« Git-in);
- tĂ« gjitha podâĂ«t qĂ« po shkarkohen tani nĂ« Kubernetes;
- ReplicaSetâĂ«t e vjetra (ato qĂ« ishin shkarkuar sĂ« fundmi), si dhe do tĂ« skanojmĂ« Helm-release dhe do tĂ« marrim imazhet mĂ« tĂ« fundit aty.
⊠dhe e bĂ«jmĂ« kĂ«tĂ« grup whitelist â lista e imazheve qĂ« nuk do t'i heqim. Ădo gjĂ« tjetĂ«r do ta pastronsim, pas sĂ« cilĂ«s do tĂ« gjejmĂ« imazhet stage jetimore dhe do t'i heqim ato gjithashtu.
Faza e deploy-it
Deklarativitet i besueshëm
Momenti i parë, për të cilin do të doja të tërhiqja vëmendjen në deploy, është lëshimi i konfiguracionit të rinovuar të burimeve, i shpallur në mënyrë deklarative. Dokumenti origjinal YAML me përshkrimin e burimeve të Kubernetes gjithmonë dallon shumë nga rezultati që funksionon realisht në klaster. Sepse Kubernetes shton në konfiguracion:
- identifikuesit;
- informacionin e shërbimeve;
- shumë vlera përkatëse;
- seksionin me statusin aktual;
- ndryshimet e bëra gjatë punës së admission webhook;
- rezultatin e punës së kontrolluesve të ndryshëm (dhe planifikuesit).
Pra, kur shfaqet një konfigurim i ri burimi (të reja), ne nuk mund ta marrim thjesht dhe ta shkruajmë atë mbi konfigurimin aktual, "live", (live). Për këtë, na duhen të krahasojmë të reja me konfigurimin e aplikuar më parë (last-applied) dhe të aplikojmë live patch-in e marrë.
Ky qasje quhet 2-way merge. Ai përdoret, për shembull, në Helm.
Ka edhe 3-way merge, i cili dallon nga fakti se:
- duke krahasuar last-applied dhe të reja, ne shohim çfarë është fshirë;
- duke krahasuar të reja dhe live, ne shohim çfarë është shtuar ose ndryshuar;
- patch-i i totalizuar vihet mbi live.
Ne e deploy-ojmë 1000+ aplikacione me Helm, kështu që në fakt jetojmë me 2-way merge. Megjithatë, ai ka një sërë probleme, që i kemi zgjidhur me patch-et tona, duke ndihmuar Helm-in të punojë normalisht.
Statusi real i lëshimit
Pas kĂ«saj, nga njĂ« ngjarje tĂ« radhĂ«s, sistemi ynĂ« CI gjeneron njĂ« konfigurim tĂ« ri pĂ«r Kubernetes, e dĂ«rgon pĂ«r t'u aplikuar (apply) nĂ« klaster â me ndihmĂ«n e Helm ose kubectl apply. NdĂ«rsa ndodh tashmĂ« N-way merge i pĂ«rshkruar, Kubernetes API pĂ«rgjigjet miratueshĂ«m sistemit CI, dhe ai â pĂ«rdoruesit tĂ« tij.

MegjithatĂ«, ka njĂ« problem tĂ« madh: sepse aplikaimi i suksesshĂ«m nuk do tĂ« thotĂ« lĂ«shim tĂ« suksesshĂ«m. NĂ«se Kubernetes kupton se cilat ndryshime duhet tĂ« aplikohet, e aplikon atĂ« â ne akoma nuk e dimĂ« se çfarĂ« do tĂ« marrĂ« si rezultat. PĂ«r shembull, pĂ«rditĂ«simi dhe rinisja e podâĂ«ve nĂ« frontend mund tĂ« kalojĂ« me sukses, ndĂ«rsa nĂ« backend jo, dhe do tĂ« marrim versione tĂ« ndryshme tĂ« imazheve tĂ« aplikacionit nĂ« funksion.
Për të bërë gjithçka siç duhet, ky skemë kërkon një element shtesë - një gjurmues të veçantë që do të marri informacione për statusin nga Kubernetes API dhe do t'i transmetojë ato për analizë të mëtejshme të situatës aktuale. Ne krijuam një bibliotekë Open Source në Go - (shih njoftimin e saj ), - e cila zgjidh këtë problem dhe është e integruar në werf.
Shtesat e këtij gjurmuesi për nivelin werf konfigurtohen me anë të annotimeve të vendosura në Deployments ose StatefulSets. Annotimi kryesor - fail-mode - kupton vlerat e mëposhtme:
-
IgnoreAndContinueDeployProcess- injorojmë problemet e shpërndarjes së këtij elementi dhe vazhdojmë me depon; -
FailWholeDeployProcessImmediately- një gabim në këtë element ndalon procesin e shpërndarjes; -
HopeUntilEndOfDeployProcess- shpresojmë se ky element do të funksionojë deri në fund të shpërndarjes.
Për shembull, një kombinim i tillë i burimeve dhe vlerave të annotimit fail-mode:

Kur e shpërndajmë për herë të parë, databaza (MongoDB) mund të mos jetë gati - Deployments do të bien. Por mund të presim momentin për ta nisur, dhe shpërndarja gjithsesi do të kalojnë.
Ekzistojnë gjithashtu dy annotime për kubedog në werf:
-
failures-allowed-per-replica- numri i dështimeve të lejuara për çdo replicë; -
show-logs-until- rregullon momentin deri në të cilin werf tregon (në stdout) log-et e të gjithë pod-eve që po shpërndahen. Si parazgjedhje ështëPodIsReady(për të injoruar mesazhet që ndoshta nuk na duhën, kur pod-i fillon të marrë trafikun), megjithatë, vlerat e lejuara janë gjithashtuControllerIsReadydheEndOfDeploy.
ĂfarĂ« tjetĂ«r duam nga shpĂ«rndarja?
Përveç dy pikave të përshkruara tashmë, ne dëshirojmë:
- të shohim log-et - për më tepër vetëm ato që na duhen, jo të gjitha pa ndonjë rend;
- të ndjekim progresin, sepse nëse një punë "nuk zëvendoset" për disa minuta, është e rëndësishme të kuptosh se çfarë po ndodh;
- të kemi rul muajor në rast se diçka shkoi keq (dhe për këtë është kritikisht e nevojshme të dinë statusin real të shpërndarjes). Shpërndarja duhet të jetë atomike: ose kalon deri në fund, ose gjithçka kthehet në gjendjen e mëparshme.
Përfundime
Ne si kompani për të realizuar të gjitha nuancat e përshkruara në faza të ndryshme të dorëzimit (ndërtimi, publikimi, shpërndarja) mjafton një sistem CI dhe një utilitar .
Përfundim:

Me ndihmën e werf, ne kemi avancuar mirë në zgjidhjen e një numri të madh problemesh për inxhinierët DevOps dhe do të ishim të lumtur nëse një komunitet më i gjerë do të provonte këtë utilitar në punë. Të arrijmë rezultate të mira bashkë do të jetë më e lehtë.
Videot dhe slidet
Video e prezantimit (~47 minuta):

Prezantimi i raportit:
P.S.
Raporte të tjera në lidhje me Kubernetes në blogun tonë:
- «» (Dmitri Stolyarov; 27 prill 2019 në «Stachka»);
- «» (Andrej Polovov; 8 prill 2019 në Saint HighLoad++);
- «» (Dmitri Stolyarov; 8 nëntor 2018 në HighLoad++);
- «» (Dmitry Stolyarov; 28 maj 2018 në RootConf);
- «» (Dmitry Stolyarov; 7 nëntor 2017 në HighLoad++);
- «» (Dmitry Stolyarov; 6 qershor 2017 në RootConf).
Burimi: habr.com
