Aplikacionet "cloud-native" ose thjesht "në re" krijohen specifikisht për t'u funksionuar në infrastrukturat e re. Zakonisht, ato nisin si një grup mikroshërbimesh të lidhura dobët, të paketuar në kontejnerë, të cilët, nga ana tjetër, menaxhohen nga një platformë cloud. Këto aplikacione janë parazgjedhur për t'u rikuperuar nga dështimet, që do të thotë se funksionojnë dhe shkallëzohen me besueshmëri, madje edhe në rastet e dështimeve serioze në nivelin e infrastrukturës. Anë tjetër e medaljes është grumbulli i kufizimeve (kontraktet) që platformat cloud vendosin mbi aplikacionet container, për t'u mundësuar menaxhimin e tyre në mënyrë automatike.

Duke e kuptuar plotësisht nevojën dhe rëndësinë e kalimit në aplikacione në re, shumë organizata ende nuk dinë nga të fillojnë. Në këtë postim, ne do të shqyrtojmë një sërë parimesh, respektimi i të cilave gjatë zhvillimit të aplikacioneve me kontejnerë do të lejojë realizimin e potencialit të platformave cloud dhe arritjen e funksionimit dhe shkallëzimit të besueshëm të aplikacioneve, madje edhe në rastet e dështimeve të rënda në nivelin e infrastrukturës IT. Qëllimi kryesor i parimeve të paraqitura këtu është të mësojmë si të krijojmë aplikacione që mund të menaxhohen automatikisht nga platforma cloud, siç është Kubernetes.
Parimet e projektimit të softuerit
Në botën e programimit, parimet kuptohen si rregulla mjaft të përgjithshme që duhet të respektohen gjatë zhvillimit të softuerit. Ato mund të aplikohen gjatë punës me çdo gjuhë programimi. Çdo parim ka qëllimet e veta, për të cilat zakonisht shërbejnë modelet dhe praktikat. Po ashtu, ekzistojnë një sërë parimesh themelore për krijimin e softuerit cilësor, nga të cilat burojnë të gjitha të tjerat. Le të japim disa shembuj të parimeve themelore:
- (Keep it simple, stupid) – mos e kompliko;
- (Don’t repeat yourself) – mos u përsërit;
- (You aren’t gonna need it) – mos krijo atë që nuk e ke nevojë menjëherë;
- (Separation of concerns) – ndaje përgjegjësitë.
Siç mund të shihet, këto parime nuk caktoshin rregulla të caktuara, por i përkasin kategorisë së konsideratave të shëndosha të bazuara në përvojën praktike, të cilat shumë zhvillues i ndajnë dhe në të cilat ata referohen rregullisht.
Për më tepër, ekziston – një grup nga pesë parimet e para të programimit dhe projektimit të orientuar nga objektet, të formuluara nga Robert Martin. SOLID përfshin parime të përgjithshme dhe të hapura për interpretim, të cilat – nëse aplikohen së bashku – ndihmojnë në krijimin e sistemeve të softuerit më cilësore dhe mbështetje më të mirë për to në perspektivën afatgjatë.
Parimet SOLID i përkasin fushës së OOP dhe formulohen në gjuhën e koncepteve dhe nocioneve si klasat, ndërfaqet dhe trashëgimia. Në të njëjtën mënyrë, për aplikacionet në re gjithashtu mund të formulohen parimet e zhvillimit, vetëm se elementi bazë këtu do të jetë një kontejner dhe jo një klasë. Duke ndjekur këto parime, mund të krijohen aplikacione kontejneri që përgjigjen më mirë qëllimeve dhe detyrave të platformave cloud si Kubernetes.
Konteinerët e orientuar nga re: qasja Red Hat
Sot, është relativisht e lehtë të paketoni pothuajse çdo aplikacion në konteinerë. Por për të që aplikacionet të automatizohen dhe orkestrohen efektivisht në kuadër të një platforme cloud si Kubernetes, kërkohet përpjekje të mëtejshme.
Baza për idetë e paraqitura më poshtë ishte metodologjia dhe shumë punë të tjera mbi aspekte të ndryshme të krijimit të aplikacioneve web, nga menaxhimi i kodit burimor deri te modelet e shkallëzimit. Parimet e përshkruara i përkasin vetëm zhvillimit të aplikacioneve kontejneri, të cilat janë ndërtuar mbi bazën e mikrosërbimeve dhe janë të destinuara për platforma cloud si Kubernetes. Elementi bazë në shqyrtimet tona është imazhi i kontejnerit, dhe për ambiencën e caktuar të ekzekutimit të kontejnerëve kuptohet platforma e orkestrimit të kontejnerëve. Qëllimi i parimeve të propozuara është të krijojmë konteinerë, për të cilët në shumicën e platformave të orkestrimit mund të automatizohen detyrat e planifikimit, shkallëzimit dhe monitorimit. Parimet paraqiten në rend të rastësishëm.
Parimi i shqetësimit të vetëm (Single Concern Principle, SCP)
Ky princip është shumë i ngjashëm me parimin e përgjegjësisë së vetme (Single Responsibility Principle, ), i cili është pjesë e grupit SOLID dhe thotë se çdo objekt duhet të ketë një detyrë dhe kjo detyrë duhet të jetë plotësisht e inkapsuluar në klasë. Kuptimi i SRP është që çdo detyrë është një arsye për ndryshim, dhe klasa duhet të ketë një dhe vetëm një arsye për ndryshim.
Në SCP, në vend të fjalës "përgjegjësi" (responsibility), ne përdorim fjalën "detyrë" (concern), për të treguar një nivel më të lartë abstraksioni dhe një funksion më të gjerë të enëve krahasuar me klasën OOP. Dhe nëse qëllimi i SRP është të ketë vetëm një arsye për ndryshime, SCP ka për qëllim të zgjasë mundësitë për ripërdorim dhe zëvendësim të enëve. Duke ndjekur SRP dhe duke krijuar një enë që zgjidh një detyrë të vetme dhe e bën këtë në një mënyrë funksionale të plotë, ju rrisni shanset për ripërdorimin e këtij imazhi të enës në kontekste të ndryshme aplikacionesh.
Parimi SCP thotë se çdo enë duhet të zgjidhë një detyrë të vetme dhe ta bëjë atë mirë. Po ashtu, SCP në botën e enëve arrihet më lehtë sesa SRP në botën e OOP, pasi enët zakonisht kryejnë një proces të vetëm, dhe shumicën e kohës ky proces zgjidh një detyrë të vetme.
Nëse ndonjë mikrosistem enë duhet të zgjidhë disa detyra, atëherë mund të ndahet në enë me një detyrë dhe t'i bashkohen në një pod (njësi implementimi të platformës së enëve) nëpërmjet shablloneve sidecar dhe init-container. Për më tepër, SCP e lehtëson zëvendësimin e enës së vjetër (p.sh., serverit të uebit apo brokerit të mesazheve) me një të re, e cila zgjidh të njëjtën detyrë, por ka funksionalitete të zgjeruara ose është më mirë e shkallëzueshme.

Parimi i lehtësisë së monitorimit (High Observability Principle, HOP)
Kur përdoren kontejnerët si një mënyrë e standardizuar për paketimin dhe ekzekutimin e aplikacioneve, vetë aplikacionet shikohen si "kutia e zezë". Megjithatë, nëse këta janë kontejnerë në re, ata duhet të sigurojnë mjedisit të ekzekutimit API të veçanta për të monitoruar shëndetin e kontejnerëve dhe për të marrë masat përkatëse nëse është e nevojshme. Pa këtë, nuk mund të standardizohet automatizimi i përditësimit të kontejnerëve dhe menaxhimit të ciklit të jetës së tyre, gjë që, për pasojë, do të përkeqësojë qëndrueshmërinë dhe lehtësinë e përdorimit të sistemit software.
Në praktikë, aplikacioni i kontejnerit duhet, së paku, të ketë një API për lloje të ndryshme kontrollesh shëndeti: teste të aktiviteteve (liveness) dhe teste të gatishmërisë (readiness). Nëse aplikacioni pretendohet të ofrojë më shumë, ai duhet të sigurojë edhe mjete të tjera për kontrollin e gjendjes së tij. Për shembull, regjistrimin e ngjarjeve të rëndësishme nëpërmjet STDERR dhe STDOUT për agregimin e regjistrave përmes Fluentd, Logstash dhe mjeteve të ngjashme. Gjithashtu, integrimin me biblioteka për gjurmimin dhe mbledhjen e metrikeve, si OpenTracing, Prometheus etj.
Në përgjithësi, aplikacioni mund të konsiderohet ende si "kutia e zezë", por ai duhet të jetë i pajisur me të gjitha API-të e nevojshme për platformën që të monitorojë dhe menaxhojë atë në mënyrën më të mirë.
Principi i përshtatjes ndaj ciklit të jetës (Life-cycle Conformance Principle, LCP)
LCP – është një antitezë ndaj HOP. Nëse HOP thotë që kontejneri duhet të ofrojë API për lexim në platformë, LCP kërkon nga aplikacioni aftësinë për të pranuar informacion nga platforma. Për më tepër, kontejneri duhet të mos vetëm të marrë ngjarje, por të përshtatet, dmth, të reagojë ndaj tyre. Kështu, për këtë arsye, ky princip mund të shikohet si një kërkesë për t'i ofruar platformës API për shkrim.

Platformat kanë lloje të ndryshme ngjarjesh që ndihmojnë në menaxhimin e ciklit të jetës së kontejnerit. Por vendimi se cilat ngjarje të pranojnë dhe si të reagojnë, duhet të jetë nga vetë aplikacioni.
E qartë se disa ngjarje janë më të rëndësishme se të tjerat. Për shembull, nëse një aplikacion nuk e përballon mirë përfundimin e papritur, ai duhet të pranojë mesazhet signal: terminate (SIGTERM) dhe sa më shpejt që të jetë e mundur të fillojë procedurën e tij të mbylljes, për të arritur para se të ndodhë sinjali signal: kill (SIGKILL), i cili vjen pas SIGTERM.
Për më tepër, ngjarje si PostStart dhe PreStop mund të jenë të rëndësishme për ciklin e jetës së aplikacionit. Për shembull, pas fillimit, aplikacioni mund të kërkojë një kohë të caktuar për "ngrohje" para se të mund të përgjigjet ndaj kërkesave. Ose aplikacioni duhet të lirojë burimet në një mënyrë të veçantë kur mbyllet.
Parimi i pandryshueshmërisë së imazhit të kontejnerit (Image Immutability Principle, IIP)
Konsiderohet se aplikacionet konteiner duhet të mbeten të pandryshuara pas ndërtimit, edhe nëse ekzekutohet në vende të ndryshme. Këtu del nevoja për të eksternalizuar ruajtjen e të dhënave në fazën e ekzekutimit (dmth, për ta bërë këtë duke përdorur mjete të jashtme), si dhe për të mbështetur konfigurime të jashtme, të përshtatura për ambientin e veprimit, në vend se të modifikosh ose të krijosh kontejnerë unik për çdo ambient. Pas çdo ndryshimi në aplikacion, imazhi i kontejnerit duhet të ndërtohet përsëri dhe të zbatohet në të gjitha ambientet ku përdoret. Me rastin e menaxhimit të sistemeve IT, përdoret një parim i ngjashëm, i njohur si parimi i pandryshueshmërisë së serverëve dhe infrastrukturës.
Qëllimi i IIP është të parandalojë krijimin e imazheve të ndryshme të kontejnerit për ambiente të ndryshme ekzekutimi dhe të përdorë të njëjtin imazh në të gjitha vendet me konfigurimin e duhur për ambientin specifik. Ndjekja e këtij parimi ndihmon në realizimin e praktikave të rëndësishme për automatizimin e sistemeve në cloud, si rikthimi (roll-back) dhe përparimi (roll-forward) i përditësimeve të aplikacioneve.

Parimi i disponueshmërisë së proceseve (Process Disposability Principle, PDP)
Një nga karakteristikat më të rëndësishme të një kontejneri është efemëria e tij: një instancë e kontejnerit krijohet lehtësisht dhe shkatërrohet lehtësisht, prandaj mund të zëvendësohet në çdo moment me një instancë tjetër. Shkaku i zëvendësimit mund të jetë shumë: dështimi në testin e përshtatshmërisë, shkallëzimi i aplikacionit, transferimi në një host tjetër, shterimi i burimeve të platformës ose situata të tjera.
Si si ndodh, aplikacionet me konteinerë duhet të ruajnë shtetin e tyre me ndihmën e ndonjë mjeti të jashtëm, ose të përdorin skema të brendshme të shpërndara me redundancë. Për më tepër, aplikacioni duhet të nisë shpejt dhe të mbyllet gjithashtu shpejt, si dhe të jetë i gatshëm për një dështim fatkeq të papritur të harduerit.
Një nga praktikat që ndihmon në realizimin e këtij parimi është krijimi i konteinerëve të vegjël. Mjediset cloud mund të zgjedhin automatikisht host-in për të nisur instancën e konteinerit, prandaj sa më e vogël të jetë madhësia e konteinerit, aq më shpejt do të nisë – thjesht do të kopjohet më shpejt në host-in e synuar përmes rrjetit.
Parimi i vetë-mjaftueshmërisë (Self-containment Principle, S-CP)
Sipas këtij parimi, në fazën e ndërtimit përfshihen të gjithë komponentët e nevojshëm në konteiner. Konteineri duhet të ndërtohet me supozimin se sistemi ka vetëm një kernel të pastër Linux, prandaj të gjitha bibliotekat e nevojshme duhet të vendosen brenda të njëjtit konteiner. Aty duhet të ndodhen edhe elemente të tilla si mjedisi i ekzekutimit për gjuhën përkatëse të programimit, platforma e aplikacioneve (nëse është e nevojshme) dhe varësitë e tjera që do të nevojiten gjatë funksionimit të aplikacionit me konteiner.

Përjashtime bëhen vetëm për konfigurimet që ndryshojnë nga mjedisi në mjedis dhe duhet të ofrohen në fazën e ekzekutimit, për shembull, përmes Kubernetes ConfigMap.
Aplikacioni mund të përfshijë disa komponentë të kontejnerizuar, për shembull, një konteiner të veçantë DBMS si pjesë e një aplikacioni web me konteiner. Sipas parimit S-CP, këta konteinerë nuk duhet të bashkohen në një, por duhet të sigurohet që konteineri DBMS të përmbajë gjithçka të nevojshme për funksionimin e bazës së të dhënave, ndërsa konteineri i aplikacionit web të ketë gjithçka të nevojshme për funksionimin e aplikacionit web, po ashtu si edhe serveri web. Si rezultat, gjatë ekzekutimit, konteineri i aplikacionit web do të varet nga konteineri DBMS dhe do të lidhet me të kur të ketë nevojë.
Parimi i kufizimit në fazën e ekzekutimit (Runtime Confinement Principle, RCP)
Principi S-CP përcakton se si duhet të ndërtohet një kontejner dhe çfarë duhet të përmbajë skedari binar i imazhit. Por kontejneri nuk është thjesht një "kutinë e zezë", e cila ka vetëm një veçori - madhësinë e skedarit. Gjatë ekzekutimit, kontejneri merr dimensione të tjera: sasia e memories së përdorur, koha e procesorit dhe burime të tjera sistemike.

Dhe këtu vjen në ndihmë principi RCP, sipas të cilit kontejneri duhet të dekapsullojë kërkesat e tij për burime sistemike dhe t'i transmetojë ato platformës. Duke pasur profilet e burimeve për secilin kontejner (sa burime CPU, memorie, rrjeti dhe sistemi i diskut i nevojiten), platforma mund të realizojë menaxhimin optimal dhe automatik të burimeve, të menaxhojë kapacitetet IT dhe të mbështesë nivelet e SLA për kontejnerët.
Përveç plotësimit të kërkesave për burimet e kontejnerit, është gjithashtu e rëndësishme që aplikacioni të mos kalojë kufijtë e vendosur nga vetë ai. Në rastin e mungesës së burimeve, platforma ka më shumë gjasa të përfshijë atë në listën e aplikacioneve që duhet të ndërpriten ose të migrohen.
Duke folur për orientimin në cloud, ne fillimisht mendojmë për mënyrën e funksionimit.
Më sipër, ne formuluam një sërë prinsipesh të përgjithshme që vendosin themelin metodologjik për ndërtimin e aplikacioneve të cilësisë së lartë të kontejnerëve për mjediset cloud.
Vlen të theksohet se përveç këtyre prinsipesh të përgjithshme, ju gjithashtu do të keni nevojë për metoda dhe teknika të avancuara për punën me kontejnerët. Për më tepër, kemi disa rekomandime të shkurtra që kanë një karakter më të veçantë dhe duhet të aplikohen (ose jo) në varësi të situatës:
- Përpiquni të zvogëloni madhësinë e imazheve: fshini skedarët e përkohshëm dhe mos instaloni paketa të panevojshme - sa më e vogël të jetë madhësia e kontejnerit, aq më shpejt ai ndërtohet dhe kopjohet në host-in e synuar përmes rrjetit.
- Orientohuni në User-ID të rastësishëm: mos përdorni komandën sudo ose ndonjë userid të veçantë për të kryer kontejnerët tuaj.
- Shenoni portet e rëndësishme: numrat e porteve mund të caktohen edhe gjatë ekzekutimit, por është më mirë t'i specifikoni ato me komandën EXPOSE - kështu do të jetë më e lehtë për njerëzit dhe programet të përdorin imazhet tuaja.
- Ruani të dhënat e përhershme në volume: të dhënat që duhet të qëndrojnë pas zhdukjes së kontejnerit duhet të ruhen në volume.
- Shkruani metadata mbi imazhin: etiketat, shenjat dhe annotimet e lehtësojnë përdorimin e imazheve – zhvillues të tjerë do t'ju jenë mirënjohës.
- Sinkronizoni hostin dhe imazhet: për disa aplikacione kontejneri nevojitet që kontejneri të sinkronizohet me hostin sipas disa atributeve, si koha ose identifikatori i makinës.
- Në përfundim, ndajmë shabllone dhe praktikat më të mira që do t'ju ndihmojnë të zbatojë më efektivisht parimet e përmendura më sipër:
11 qershor në 11.00
Çfarë do të mësoni:
- Immutable Red Hat Enterprise Linux CoreOS
- OpenShift service mesh
- Operator framework
- Knative framework
Burimi: habr.com
