Kontejnerji niso modna muha, temveč pomembno orodje sedanjosti in prihodnosti!

10.05.2021

Članek

 

Avtor članka: Tomaž Borštnar

 

Virtualizacija

Virtulizacija je že zelo zrela tehnologija, katere korenine segajo v 60. leta prejšnjeg stoletja, ko je bila to pomembna prednost velikih (mainframe) sistemov. S pomočjo virtualizacije so bolj učinkovito uporabili (drage) kapacitete, ki so bile na razpolago. Virtualizacija je postala zelo razširjena tudi v širšem okolju proti koncu prejšnjega stoletja npr. podjetje VMWare je bilo ustanovljeno leta 1998. Že leto kasneje so izdali VMWare Workstation in v 2001 tudi strežniški inačici GSX Server in ESX Server. S tem je postala ta tehnologija široko dostopna vsem vrstam uporabnikom.

Virtualizacija nam v večini primerov ni prihranila kaj dosti ali nič pri stroških nakupa/licenciranja programske opreme, prav tako ni kaj dosti pomagala pri zmanjševanju nekaterih operativnih stroškov npr. shranjevanja podatkov. Prihranila nam je prostor v strežniških sobah ter strošek elektrike in delno strošek upravljanja. Zakaj samo delno strošek upravljanja? Pred virtualizacijo smo imeli manjše število namestitev operacijskih sistemov, a so hkrati imeli tudi veliko različnih aplikacij nameščenih. administratorji s(m)o se bali sprememb, saj je lahko vsaka sprememba na operacijskem sistemu ter nameščenih knjižnicah bistveno vplivala na delovanje APLIKACIJ.

V resnici je virtualizacija olajšala samo upravljanje operacijskih sistemov – navideznih računalnikov, bore malo je pripomogla k upravljanju aplikacij, ki so v resnici »KRUH« vsake resne organizacije. Na produkcijskih sistemih je bila tipično naloga administratorjev, da so skrbeli za operacijski sistem in aplikacije, zato je bila cenjena stabilnost – pred novostmi in prepogosto tudi pred VARNOSTNIMI POPRAVKI. Ker je bila stabilnost tako cenjena, je bil administrator v tem smislu ves čas med kladivom in nakovalom, saj so razvijalci želeli okolje, ki se hitro prilagaja, vodstvo jim je pogosto pritrjevalo, a je hkrati spet pričakovalo praktično 100% razpoložljivost APLIKACIJ. Polna razpoložljivost virtualizacije je relativno enostavna, saj vsi resni sistemi omogočajo prenos živega navideznega računalnika med fizičnimi strežniki. A vse to ne pomeni kaj dosti, ko je treba npr. POSODOBITI operacijski sistem ali aplikacijo.
Sedaj je verjetno večini že jasno, da virtualizacija sama po sebi ne rešuje 100% razpoložljivosti, niti upravljanja aplikacij. Za kaj takega potrebujemo drugačna orodja...

Kontejnerji

Ena od alternativ virtualizaciji so kontejnerji. Za razliko od navideznih računalnikov, ki potrebujejo strojno opremo, kjer teče hipervizor, ki omogoča delovanje navideznih računalnikov, je tu navidezno slabša izolacija, saj je kontejner dejansko skupina enega ali več procesov, ki si delijo jedro (kernel) operacijskega sistema. Skupno jedro pomeni, da kontejner ne rabi svojega navideznega računalnika, zato se lahko zelo hitro zažene in porabi precej manj strojnih kapacitet. Tak kontejner je lahko sistemski kontejner, ki ima v sebi običajne servise operacijskega sistema npr. oddaljeno prijavo, logiranje in podobno; ali pa je aplikacijski kontejner, ki vsebuje samo komponente, ki so nujne za delovanje ene aplikacije.

Zgodovina kontejnerjev

Začetnik kontejnerjev je bil Unix V7, kjer so leta 1979 uvedli možnost omejitve procesa na posamezni imenik – chroot funkcionalnost. Leta 2000 je bilo to bistveno izboljšano v FreeBSD jails mehanizmu, ki je postavil temelje sistemskim in aplikacijskim kontejnerjem. Linux je kmalu (2001) sledil s pomočjo VServer tehnologije ter kasneje tudi Solaris Zones (2004). Te tehnologije so se aktivno razvijale npr. Linux LXC ter končno v 2013, ko smo dobili Docker kontejnerje kot evolucijo vsega tega omenjenega razvoja.

Osebno sem dolga leta pridno uporabljal FreeBSD jails kot zelo dobro metodo ločevanja aplikacij, saj je imel vsak tak kontejner (jail) svoje uporabnike, svoje procese in podatke, ki so si delili isto strojno opremo ter isto jedro (kernel) operacijskega sistema. Za razliko od virtualizacije je bilo tu zelo malo izgube hitrosti aplikacij – od 0 do 2%! Tak sistem se je zelo hitro zagnal in je omogočal, da so bile na sistemu aplikacije, ki se med seboj niso videle in niti motile in so zelo hitro delovale. Edina slabost v primerjavi z virtualizacijo je bila nezmožnost poganjanja drugih operacijskih sistemov na isti strojni opremi, a tudi to je kasneje FreeBSD dodal s funkcionalnostjo Bhyve.

Že omenjeni Docker je leta 2013 izdal svoj sistem za kontejnerizacijo z istim imenom. Osebno nikoli nisem bil veliki ljubitelj njihove programske opreme, saj so me razvadili drugi ponudniki (predvsem FreeBSD in Solaris), a jim je potrebno priznati, da so opravili FANTASTIČNO promocijsko delo, ker so izobrazili ogromno razvijalcev, da je to dober in uporaben način za pakiranje in distribucijo programske opreme! Do tedaj so razvijalci običajno uporabljali aplikacijske pakete (packages) ali celo kar cele imenike shranjene v eni datoteki – običajno ZIP ali TAR. Prednost paketa je bila, da je bilo tako enostavno dodati ali odstraniti aplikacijo, a je bilo vezano na konkretno distribucijo operacijskega sistema in ni bilo enotnosti. Pri imenikih je bila stvar navidezno bolj prenosljiva, a manj praktična.

Zasnova kontejnerskih sistemov

Arhitektura tehnologije je bila enostavna – v osnovi je bil to sistem odjemalec-strežnik, kjer je bil odjemalec enostavna aplikacija, ki je komunicirala s strežnikom - lokalno ali na daljavo. Strežnik je bil velik proces, ki je potreboval veliko pravic na sistemu za delovanja. Strežnik je potreboval kontejnersko sliko (container image), kjer so bile notri vse potrebne datoteke za zagon. To sliko smo lahko dobili preko posebnih distribucijskih kanalov – registrov za kontejnerske slike – container image registry. Seveda so poskrbeli, da je bilo kmalu na voljo ogromno teh slik za uporabnike, da so lahko začeli delati s to tehnologijo.

V praksi je pomenilo, da je lahko kdorkoli začel uporabljati to tehnologijo s pomočjo nekaj ukazov za namestitev Dockerja in zagon  kontejnerja neposredno iz Interneta. Ni več bilo potrebno gledati, če imamo pravo distribucijo sistema, prave aplikacije in podobno. V primeru zahtevnejših aplikacij je to BISTVENO poenostavilo in olajšalo uporabo aplikacij, saj je glavna prednost kontejnerske slike ravno to, da je notri VSE POTREBNO za zagon in uporabo. In kako HITER je ta zagon! Če je notri samo aplikacija, ko jo potrebujemo, se lahko kontejner zažene v SEKUNDAH in ne v minutah kot je bolj tipično za virtualke.

Dodatne prednosti kontejnerjev

S čim še je Docker prepričal uporabnike v svojo vizijo? S poenostavljenim upravljanjem omrežnih nastavitev, saj je lahko uporabnik v večini primerov preprosto zagnal kontejner in je aplikacija že bila na voljo znotraj istega sistema. V primeru, da je bilo potrebno kaj več, je v večini primerov zadoščalo odprtje enih TCP/UDP vrat in že je bila aplikacija na voljo tudi drugim uporabnikom na omrežju! Prav tako je bilo enostavno narediti svoja zasebna omrežja za posamezne aplikacije in podobno.

Prav tako je bilo enostavno pripraviti svoje kontejnerske slike – s pomočjo zagona druge slike in shranjenimi spremembami ter preko uporabe že obstoječih slik (base image), ki so bile samo še dopolnjenes pomočjo mehanizma Dockerfile. Dockerfile je ime datoteke, kjer s pomočjo precej enostavnih ukazov pripravimo svojo kontejnersko sliko – iz nič ali s pomočjo obstoječe slike, ki jo dopolnimo s svojimi spremembami.

Dobre prakse

Na primer, če imamo aplikacijo, ki potrebuje točno določeno distribucijo Linuxa npr. Red Hat Enterprise Linux 7 ali Ubuntu 18 LTS, je dovolj, da poiščemo sliko, ki to že vsebuje in je po možnosti celo uradna slika distribucije (npr. Red Hat Universal Base Image – UBI), saj v tem primeru ni potrebno, da sami skrbimo za varnost te slike, ampak to počne skrbnik, ki to verjetno bolj obvlada kot mi. Naša naloga je samo, da ponovno zgeneriramo svojo sliko, ko vidimo, da je bila izvirna slika posodobljena zaradi varnostnih lukenj! Na ta način si lahko bistveno izboljšamo upravljanje in varnost aplikacij, ki so nam pomembne.

Naslednja pomembna stvar so stare aplikacije zaradi katerih smo bili do sedaj prisiljeni uporabljati navidezne računalnike, kjer je bil pogosto nameščen operacijski sistem, ki se ni posodabljal oz morda nima več podpore za posodobitve. V večini primerov je mnogo boljša opcija, da take aplikacije premaknemo v kontejnerske slike, ki se jih da enostavneje upravljati in zamenjati kot navidezne računalnike, a so hkrati notri SAMO tiste komponente, ki so potrebne za aplikacijo! S tem pomembno zmanjšamo potrebo po strojnih kapacitetah in hkrati bistveno izboljšamo varnost, saj imamo manj ranljivih točk kot pri navideznem računalniku. V takem primeru lahko izkoristimo tudi prednosti novejšega jedra operacijskega sistema – predvsem optimizacije delovanja in varnosti!

Do sedaj sem omenjal predvsem prednosti za razvijalce, zato je prav, da se omenijo tudi prednosti za druge skupine, ki so pomembne.

Katere so prednosti za administratorje in vodstvo?

Že prej sem omenil, da je namestitev zelo enostavna – za Linux kontejnerje potrebujemo Linux z jedrom, ki podpira kontejnerje ter sistem za upravljanje le teh npr. docker, podman, etc. Namestitev je v večini primerov samo en ukaz, zato je začetek res enostaven. Malce bolj zahtevno je, ko imamo zahtevnejšo aplikacijo pravilno segmentirano v več kontejnerjev, ko postane pomemben vrstni red zagona, pravilno omrežje in podobno. Za take primere se super obneseta docker-compose in podman-compose, ki sta namenjena ravno temu, da se pravilni vzpostavi in odstrani okolje za aplikacijo – pravo omrežje, s podporo za shranjevanje pomembnih podatkov izven kontejnerjev ter odprtje vrat za zunanji dostop. S pomočjo docker-compose in podman-compose je življenje zelo enostavno – za zagon uporabimo ukaz UP in za pravilno zaustavitev uporabimo ukaz DOWN. Obe aplikaciji poskrbita tudi za posodobitve slik, če so javno na voljo. Skratka, zelo enostavno in uporabno.

Varnost oz ko ni vse samo rožnato

Na začetku razcveta Docker kontejnerjev je bilo veliko govora o tem, da ta segmentacija ni ustrezno varnostno podprta, a se je sčasoma to precej spremenilo in danes je lahko tak sistem precej bolj varen od marsikaterega fizičnega ali navideznega strežnika, saj uporablja več nivojev zaščite, ki vsi skupaj poskrbijo za boljšo varnost glavnega sistema in samih kontejnerjev. Prva zaščita je že sama segmentacija, saj so aplikacije v kontejnerjih med seboj izolirane. Naslednji nivo je varnostni modul v samem Linux jedru – SELinux ali AppArmor, ki sta namenjena temu, da ujameta/preprečite poskuse pobega izven omejenega okolja, ki je na voljo kontejnerjem. Še vedno pa je možnost izrabe povezave med gostiteljem in kontejnerjem – preko sistemskih klicev (syscalls), ki so način kako lahko aplikacija komunicira z jedrom gostitelja. Naj povem, da je točno to tudi pogosto največji varnostni problem pri virtualizaciji, česar se večina ne zaveda.
Zelo pomemben modul je tudi cgroups oz  Control Groups, ki med drugim lahko zagotavlja tudi to, da aplikacije v kontejnerjih ne morejo uporabi več kapacitet kot smo jim jih dodelili! Na ta način lahko omejimo porabo procesorja, pomnilnika, dela z diskom in podobno. To je del Linux jedra že 14 let, a se še vedno premalo uporablja tudi brez kontejnerjev.

Pomembna lastnost uporabe kontejnerskih slik je, da so tipično precej manjše od virtualk, se hitro prenesejo in da zasedajo minimalno prostora, saj v primeru, da poganjamo več kontejnerjev iz istih slik, se ta slika shrani samo enkrat in se potem preslika tolikokrat kot je potrebno. Na ta način se da prihraniti ogromno prostora, saj za poganjanje 100 kontejnerjev iz iste slike, ne potrebujemo tolikokratno količino prostora. Hitri diskovni prostor je zelo drag in ga lahko na ta način ogromno prihranimo.

Prav tako je velikost teh slik zelo majhna – male slike imajo lahko tudi samo 5 MB! Da, pravilno ste prebrali – Alpine Linux slika ima samo 5 MB in vsebuje minimalni sistem, ki že zadošča ogromno aplikacijam! Običajne velikosti slik se gibljejo med 50 in 200MB. Le redko je potrebno več! Če to primerjamo s slikami za navidezne računalnike, kjer je večina teh slikah v GB ali celo desetinah GB in se tipično med seboj ne morejo deliti za večkratno uporabo! Kdor kopuje drage diskovne sisteme, si lahko hitro izračuna, da lahko samo na račun take optimizacije prihranimo  precej denarja.

Ves ta čas se nismo dotaknili težave, ko nam en strežnik ne zadošča več. Želimo uporabljati kontejnerje, a ne želimo tega delati ročno, potrebujemo avtomatizacijo, že omenjeno visoko razpoložljivost in še marsikaj drugega. Leta 2014 je Google najavil, da bo izdal odprtokodno verzijo  sistema za masovno uporabo kontejnerjev, ki bo baziral na njihovih desetletnih izkušnjah masovne uporabe kontejnerjev. Tako smo dobili Kubernetes (krajše k8s), ki je kmalu postal de facto standard za upravljanje aplikacij in je danes eno najboljših ogrodij za ta namen! Kot zanimivost naj povem, da so že v istem letu (2014) k projektu pristopili vsi veliki – Red Hat, IBM, Microsoft in drugi. V letu 2015 smo tako dobili Kubernetes 1.0, ki se od takrat še vedno razvija skoraj s svetlobno hitrostjo, saj vsake 3 mesece dobimo novo verzijo! Kubernetes je nekaj posebnega iz večih razlogov:

- je odprtokodni projekt z najširšo podporo 
- zasnovan je bil za največje sisteme – ena gruča ima lahko do 5000 strežnikov! A hkrati lahko dela tudi samo na enem!
- podpira mehanizme za preverjanje delovanja aplikacij
- omogoča avtomatsko reševanje težav gruče in aplikacij npr. v primeru izpada aplikacije ali strežnika se ta lahko ponovno zažene nekje druge. Brez ročnega posega!
- omogoča 100% razpoložljivost aplikacije, če je pravilno zasnovana in nastavljena!
- podpira enotne vmesnike za uporabo in upravljanje – API
- omogoča natančno razčlenitev pravic uporabnikom
- uporabniki so lahko ljudje in aplikacije
- odlično podpira DEVOPS/DEVSECOPS prakse npr. 12 Factor Apps
- zasnovan je bil kot splošni sistem za upravljanje aplikacij, zato podpira kontejnerje in tudi več vrst virtualizacije

Ravno to zadnje je tista pomembna lastnost, ki že sedaj bistveno vpliva na IT sektor, saj je čedalje manj potreb po hkratni uporabi večih tehnologij za namen poganja aplikacij. Kubernetes bo pomembno vplival na tržni delež nekaterih že uveljavljenih ponudnikov, če se ne bodo primerno prilagodili novimu izzivalcu.


Skratka, Kubernetes je fantastično okolje, ko prerastemo zmožnosti enega računalnika. Prav tako je pomemben del rešitev, ko moramo preiti na boljši način razvijanja, testiranja in uporabljanja aplikacij. Sem omenil, da je Kubernets prava »cloud native« rešitev? In da je pomemben razbijalec zaprtih sistemov?

A več o tem kdaj drugič...

 

O AVTORJU:

Tomaž Borštnar je strokovnjak z dolgoletnimi izkušnjami iz IT področja. Sodeloval je pri postavitvi največjih internetnih projektov v Sloveniji – SiOL, Arnes, Voljatel, etc. Bil je član začetnega uredniške odbora revije Monitor. Vodil je oddajo o računalništvu na Radiu Študent. Postavil in ustanovil je sistem Med.Over.Net, ki ga je dolga leta tudi vodil. V zadnjih letih izobražuje doma in v tujini ter dela na zanimivih projektih s sodobnimi tehnologijami. Je tudi uradni predavatelj za tečaje Red Hat, Suse, EnterpriseDB in Cisco ter nosilec številnih IT certifikatov.

Need assistance?
Need assistance?