
Hapi i parë i vendosjes në Kubernetes është vendosja e aplikacionit tuaj në një kontejner. Në këtë seri, do të shqyrtojmë se si mund të krijoni një imazh të një kontejneri të vogël dhe të sigurt.
Falë Docker-it, krijimi i imazheve të kontejnerëve nuk ka qenë kurrë kaq i lehtë. Specifikoni imazhin bazë, shtoni ndryshimet tuaja dhe krijoni kontejnerin.

Megjithëse ky qasje është shumë e përshtatshme për të filluar, përdorimi i imazheve bazë të paracaktuar mund të çojë në funksionim të pasigurt me imazhe të mëdha, plot me vulnerabilitete.
Për më shumë, shumica e imazheve në Docker përdorin Debian ose Ubuntu si imazhin bazë dhe, ndonëse kjo siguron një përputhshmëri të shkëlqyer dhe një adaptim të lehtë (skedari Docker zë vetëm dy rreshta kod), imazhet bazë mund të shtojnë qindra megabajt ngarkesë shtesë në kontejnerin tuaj. Për shembull, një skedar i thjeshtë node.js i aplikacionit Go "hello-world" zë rreth 700 megabajt, meqë madhësia e vetë aplikacionit tuaj është vetëm disa megabajt.

Prandaj, e gjithë kjo ngarkesë shtesë është një shpenzim i panevojshëm i hapësirës digjitale dhe një vend i shkëlqyer për vulnerabilitete dhe gabime në sistemin e sigurisë. Prandaj, le të shqyrtojmë dy mënyra për të reduktuar madhësinë e imazhit të kontejnerit.
E para është përdorimi i imazheve bazë me madhësi të vogël, e dyta është përdorimi i modelit të dizajnit Builder Pattern. Përdorimi i imazheve bazë më të vogla është ndoshta mënyra më e thjeshtë për të reduktuar madhësinë e kontejnerit tuaj. Me siguri, gjuha ose steka që po përdorni siguron një imazh të aplikacionit origjinal shumë më të vogël se imazhi i paracaktuar. Le të shohim kontejnerin tonë node.js.

Me zakon, madhësia e imazhit bazë node:8 në Docker është 670 MB, ndërsa madhësia e node:8-alpine është vetëm 65 MB, domethënë 10 herë më e vogël. Duke përdorur një imazh më të vogël bazë Alpine, do të reduktoni në mënyrë të ndjeshme madhësinë e kontejnerit tuaj. Alpine është një shpërndarje e vogël dhe e lehtë e Linux-it që është shumë e njohur midis përdoruesve të Docker-it, sepse është e përputhshme me shumë aplikacione, duke ruajtur gjithashtu madhësinë e vogël të kontejnerëve. Ndryshe nga imazhi standard Docker 'node', 'node:alpine' fshin shumë skedarë dhe programe ndihmëse, duke lënë vetëm ata që janë të nevojshëm për të ekzekutuar aplikacionin tuaj.
Për të kaluar në një imazh bazë më të vogël, thjesht azhurnoni skedarin Docker për të filluar përdorimin e imazhit të ri bazë:

Tani, ndryshe nga imazhi i vjetër onbuild, duhet të kopjoni kodin tuaj në kontejner dhe të instaloni çdo varësi. Në skedarin e ri Docker, kontejneri fillon me imazhin node:alpine, pastaj krijon një katalog për kodin, instalon varësitë me menaxherin e paketave NPM dhe, përfundimisht, fillon server.js.

Me këtë përditësim, rezulton një kontejner që është 10 herë më i vogël. Nëse gjuha juaj e programimit ose steka nuk ka një funksion për të zvogëluar imazhin bazë, përdorni Alpine Linux. Ai gjithashtu do të ofrojë mundësinë për të menaxhuar plotësisht përmbajtjen e kontejnerit. Përdorimi i imazheve bazë me madhësi të vogël është një mënyrë e shkëlqyer për të ndërtuar shpejt kontejnerë të vegjël. Por mund të arrihet edhe më shumë zvogëlim duke përdorur Builder Pattern.

Në gjuhët interpretuese, kodi burimor fillimisht kalon nëpër interpretor dhe pastaj ekzekutohet direkt. Në gjuhët e kompiluara, kodi burimor fillimisht kthehet në kod të kompiluara. Gjatë kësaj kohe, kompilimi shpesh përdor mjete që në të vërtetë nuk janë të nevojshme për të ekzekutuar kodin. Kjo do të thotë që mund të hiqni plotësisht këto mjete nga kontejneri përfundimtar. Për këtë, mund të përdorni Builder Pattern.

Kodi krijohet në kontejnerin e parë dhe kompilohet. Pastaj kodi i kompiluara paketizohet në kontejnerin përfundimtar pa kompilatorët dhe mjetet e nevojshme për të kompaktuar këtë kod. Le të kalojmë përmes këtij procesi me aplikacionin Go. Së pari, do të kalojmë nga imazhi onbuild në Alpine Linux.

Në skedarin e ri Docker, kontejneri fillon me imazhin golang:alpine. Më pas krijon një katalog për kodin, ekopjon atë në kodin burimor, e ndërtson këtë kod burimor dhe ekzekuton aplikacionin. Ky kontejner është shumë më i vogël se kontejneri onbuild, por ende përmban kompilatorin dhe mjetet e tjera Go, të cilat në të vërtetë nuk na nevojiten. Prandaj, le të nxjerrim thjesht programin e kompiluar dhe ta vendosim atë në kontejnerin tonë.

Mund të vini re diçka të çuditshme në këtë skedar Docker: ai përmban dy rreshta FROM. Seksioni i parë prej 4 rreshtash duket saktësisht si skedari i mëparshëm Docker, përveç faktit që përdor fjalën çelës AS për t'i dhënë emër këtij faze. Në seksionin pasues ka një rresht të ri FROM, duke filluar një imazh të ri, duke përdorur Raw alpine si imazhin bazë në vend të golang:alpine.
Raw Alpine Linux nuk ka asnjë certifikatë SSL të instaluar, që do të çojë në dështimin e shumicës së thirrjeve të API përmes protokollit HTTPS, prandaj le të instalojmë disa certifikata të korit CA.
E tani vjen pjesa më interesante: për të kopjuar kodin e kompiluar nga kontejneri i parë në të dytin, thjesht mund të përdorim komandën COPY, e cila gjendet në rreshtin e 5-të të seksionit të dytë. Ajo do të kopjojë vetëm një skedar aplikacioni dhe nuk do të prekë mjetet ndihmëse Go. Skedari i ri Docker me shumë hapa do të përmbajë imazhin e kontejnerit me vetëm 12 megabajt, ndërsa imazhi burimor ishte 700 megabajt, që është një diferencë e madhe!
Pra, përdorimi i imazheve të vogla bazë dhe Modeli i Ndërtuesit janë mënyra të shkëlqyera për të krijuar kontejnerë shumë më të vegjël pa shumë punë.
Mund tĂ« jetĂ« qĂ«, nĂ« varĂ«si tĂ« stack-ut tĂ« aplikacionit, ka edhe mĂ«nyra tĂ« tjera pĂ«r tĂ« zvogĂ«luar madhĂ«sinĂ« e imazhit dhe kontejnerit, por a ka vĂ«rtet pĂ«rfitime tĂ« dukshme kontejnerĂ«ve tĂ« vegjĂ«l? Le tĂ« shqyrtojmĂ« dy aspekte ku kontejnerĂ«t e vegjĂ«l janĂ« jashtĂ«zakonisht efikas â Ă«shtĂ« performanca dhe siguria.
Për të vlerësuar rritjen e performancës, le të shqyrtojmë kohën e procesit të krijimit të një kontejneri, futjes së tij në regjistrin (push) dhe të nxjerrjes së tij nga atje (pull). Mund ta shihni se një kontejner me përmasë më të vogël ka një avantazh të jashtëzakonshëm në krahasim me një kontejner më të madh.

Docker do të ruajë nivelet, kështu që ndërtimet e mëpasshme do të realizohen shumë shpejt. Megjithatë, në shumë sisteme CI, të cilat përdoren për të ndërtuar dhe testuar kontejnerët, nivelet nuk ruhen, kështu që këtu ka një kursim të konsiderueshëm të kohës. Siç duket, koha e ndërtimit të kontejnerit të madh, varësisht nga fuqia e makinës tuaj, është nga 34 në 54 sekonda, ndërsa për të përdorur një kontejner të zvogëluar me anë të Pattern Builder, është nga 23 në 28 sekonda. Për operacione të tilla, rritja e performancës arrin 40-50%. Pra, thjesht mendoni sa herë e krijoni dhe testoni kodin tuaj.
Pasi të jetë ndërtuar kontejneri, ju nevojitet të futni imazhin e tij (push container image) në regjistrin e kontejnerëve, për ta përdorur më vonë në klasterin tuaj Kubernetes. Unë rekomandoj të përdorni regjistrin e kontejnerëve të Google.

Duke përdorur Google Container Registry (GCR), ju paguani vetëm për ruajtjen dhe rrjetin "bllok" dhe nuk ka pagesa shtesë për menaxhimin e kontejnerëve. Kjo është e besueshme, e sigurt dhe shumë e shpejtë. GCR përdor shumë truke për të përshpejtuar operacionin pull. Siç e shihni, futja e imazhit të kontejnerit Docker Container Image me përdorimin e go:onbuild varësisht nga performanca e kompjuterit do të zgjasë nga 15 në 48 sekonda, ndërsa e njëjta operacion me një kontejner më të vogël nga 14 në 16 sekonda, ku për makinën me performancë më të ulët, përparësia në shpejtësinë e operacionit rritet deri në 3 herë. Për makinat e mëdha, koha është afërsisht e njëjtë, pasi GCR përdor një cache global për bazën e përbashkët të imazheve, që do të thotë se nuk keni nevojë t'i ngarkoni fare. Në kompjuterët me performancë të ulët, CPU është pika e ngushtë, prandaj përparësia e përdorimit të kontejnerëve të vegjël këtu është shumë më e dukshme.
Nëse po përdorni GCR, unë theksoj qëju të përdorni Google Container Builder (GCB) si pjesë të sistemit tuaj të ndërtimit.

Si e shihni, pĂ«rdorimi i saj lejon arritjen e rezultateve shumĂ« mĂ« tĂ« mira nĂ« reduktimin e kohĂ«s sĂ« operacionit Build+Push, madje edhe mĂ« shumĂ« se njĂ« makinĂ« me performancĂ« tĂ« lartĂ« â nĂ« kĂ«tĂ« rast, procesi i ndĂ«rtimit dhe dĂ«rgimit tĂ« kontejnerĂ«ve nĂ« host shpejtohet gati dyfish. PĂ«r mĂ« tepĂ«r, çdo ditĂ« ju merrni 120 minuta ndĂ«rtimi falas, qĂ« nĂ« shumicĂ«n e rasteve plotĂ«son nevojat pĂ«r krijimin e kontejnerĂ«ve.
MĂ« pas vjen metrika mĂ« e rĂ«ndĂ«sishme e performancĂ«s â shpejtĂ«sia e tĂ«rheqjes, ose shkarkimit tĂ« kontejnerĂ«ve Pull. Dhe nĂ«se nuk ju intereson shumĂ« kohĂ«zgjatja e operacionit push, koha e procesit pull ndikon seriozisht nĂ« performancĂ«n e pĂ«rgjithshme tĂ« sistemit. Supozoni se keni njĂ« klaster prej tre nyjash dhe njĂ«ra prej tyre dĂ«shton. NĂ«se pĂ«rdorni njĂ« sistem menaxhimi, si Google Kubernetes Engine, ai automatikisht do tĂ« zĂ«vendĂ«sojĂ« nyjen qĂ« nuk punon me njĂ« tĂ« re. MegjithatĂ«, kjo nyje e re do tĂ« jetĂ« krejtĂ«sisht e zbrazĂ«t, dhe ju do tĂ« duhet ta tĂ«rheqni tĂ« gjitha kontejnerĂ«t tuaj nĂ« tĂ« pĂ«r t'u aktivizuar. NĂ«se operacioni pull zgjat shumĂ«, atĂ«herĂ« gjithĂ« atĂ« kohĂ« klasteri juaj do tĂ« punojĂ« me njĂ« performancĂ« mĂ« tĂ« ulĂ«t.
EkzistojnĂ« shumĂ« raste kur mund tĂ« ndodhĂ« kjo: shtimi i njĂ« nyje tĂ« re nĂ« klaster, pĂ«rditĂ«simi i nyjave ose madje kalimi nĂ« njĂ« kontejner tĂ« ri pĂ«r deploy. KĂ«shtu, minimizimi i kohĂ«s sĂ« tĂ«rheqjes pull bĂ«het njĂ« faktor kyç. ĂshtĂ« e pamohueshme se njĂ« kontejner i vogĂ«l shkarkohet shumĂ« mĂ« shpejt se njĂ« i madh. NĂ«se pĂ«rdorni disa kontejnerĂ« nĂ« klasterin Kubernetes, kursimi i kohĂ«s mund tĂ« jetĂ« shumĂ« i rĂ«ndĂ«sishĂ«m.

Shikoni krahasimin e dhënë: operacioni pull kur punoni me kontejnerë të vegjël zë një kohë 4-9 herë më të vogël varësisht nga fuqi e makinës se sa një operacion i tillë duke përdorur go:onbuild. Përdorimi i imazheve baze të përbashkëta të kontejnerëve të vogla nxjerr shumë përpara kohën dhe shpejtësinë, me të cilat nyjat e reja Kubernetes mund të aktivizohen dhe të dalin në internet.
Le të shqyrtojmë çështjen e sigurisë. Konstruktet më të vogla konsiderohen shumë më të sigurta se ato më të mëdhatë, sepse kanë një sipërfaqe sulmi më të vogël. A është kjo e vërtetë në të vërtetë? Një nga funksionet më të dobishme të Google Container Registry është mundësia për të skanuar automatikisht konstruktet tuaja për të gjetur dobësi. disa muaj më parë krijova si onbuild ashtu edhe konstrukte të shumëfishta, prandaj le të shohim nëse ka ndonjë dobësi atje.

Rezultati Ă«shtĂ« mahnitĂ«s: nĂ« njĂ« konteiner tĂ« vogĂ«l u gjetĂ«n vetĂ«m 3 dobĂ«si tĂ« mesme, ndĂ«rsa nĂ« njĂ« tĂ« madh â 16 kritike dhe 376 dobĂ«si tĂ« tjera. Duke shqyrtuar pĂ«rmbajtjen e konteinerit tĂ« madh, duket se shumica e problemeve tĂ« sigurisĂ« nuk kanĂ« asnjĂ« lidhje me aplikacionin tonĂ«, por janĂ« tĂ« lidhura me programe qĂ« ne madje nuk i pĂ«rdorim. Prandaj, kur njerĂ«zit flasin pĂ«r njĂ« sipĂ«rfaqe tĂ« madhe pĂ«r sulme, ata kanĂ« pikĂ«risht kĂ«tĂ« parasysh.

Përfundimi është i qartë: krijoni konteinerë të vegjël, sepse ata ofrojnë përfitime reale në performancën dhe sigurinë e sistemit tuaj.

Pak reklamĂ« đ
Faleminderit që po qëndroni me ne. Ju pëlqen artikujt tanë? Doni të shihni më shumë materiale interesante? Na mbështesni duke bërë një porosi ose duke rekomanduar tek miqtë tuaj, , një analog unik i serverëve entry-level që e kemi shpikur për Ju: (opcionet me RAID1 dhe RAID10, deri në 24 bërthama dhe deri në 40GB DDR4 janë të disponueshme).
Dell R730xd dyfish mĂ« i lirĂ« nĂ« qendĂ«r tĂ« tĂ« dhĂ«nave Equinix Tier IV nĂ« Amsterdam? VetĂ«m te ne nĂ« HolandĂ«! Dell R420 â 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB â nga $99! Lexoni rreth
Burimi: habr.com
