FAKULTETA ZA INFORMACIJSKE ŠTUDIJE V NOVEM MESTU MAGISTRSKA NALOGA ŠTUDIJSKEGA PROGRAMA DRUGE STOPNJE ALEKSANDER MIHIČINAC Digitally signed by Aleksander Mihicinac DN: c=SI, o=ACNLB, o=NLB, ou=Fizicne osebe, serialNumber=7237325300, cn=Aleksander Mihicinac Date: 2014.12.11 17:39:04 +01'00' FAKULTETA ZA INFORMACIJSKE ŠTUDIJE V NOVEM MESTU MAGISTRSKA NALOGA LÁHKO IZVAJALNO OKOLJE V OBLIKI SAMOZADOSTNEGA LXC-VSEBNIKA Mentor: izr. prof. dr. Blaž Rodič Novo mesto, december 2014 ALEKSANDER MIHIČINAC IZJAVA O AVTORSTVU Podpisani Aleksander Mihičinac, študent FIŠ Novo mesto, izjavljam: ∙ da sem magistrsko nalogo pripravljal samostojno na podlagi virov, ki so navedeni v magistrski nalogi, ∙ da dovoljujem objavo magistrske naloge v polnem tekstu, v prostem dostopu, na spletni strani FIŠ oz. v digitalni knjižnici FIŠ, ∙ da je magistrska naloga, ki sem jo oddal v elektronski obliki, identična tiskani verziji, ∙ da je magistrska naloga lektorirana. V Novem mestu, dne Podpis avtorja KAZALO 1 UVOD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1 Namen, cilji in raziskovalna vprašanja . . . . . . . . . . . . . . . . . . . . . 3 1.2 Metode dela in struktura naloge . . . . . . . . . . . . . . . . . . . . . . . . 4 1.3 Predpostavke in omejitve . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2 METODE VIRTUALIZACIJE STREŽNIKOV . . . . . . . . . . . . . . . . . . . 6 2.1 Polna virtualizacija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.2 Paravirtualizacija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.3 Virtualizacija na nivoju operacijskega sistema . . . . . . . . . . . . . . . . 14 3 PROGRAMSKA REŠITEV DOCKER . . . . . . . . . . . . . . . . . . . . . . . 18 3.1 Zahteve in omejitve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.2 Namestitev . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.3 Postopek izdelave vsebnika LXC . . . . . . . . . . . . . . . . . . . . . . . . 28 3.3.1 Postopek izdelave vsebnika iz obstoječe slike z orodji LXC . . . . . . 29 3.3.2 Postopek izdelave vsebnika iz obstoječe slike z orodji Docker . . . . . 31 3.3.3 Postopek izdelave vsebnika po meri z orodji LXC . . . . . . . . . . . 32 3.3.4 Postopek izdelave vsebnika po meri z orodji Docker . . . . . . . . . 34 3.4 Uporaba in nadgradnja vsebnika LXC . . . . . . . . . . . . . . . . . . . . . 40 3.5 Varnostni vidik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 3.6 3.5.1 Jedrni imenski prostori . . . . . . . . . . . . . . . . . . . . . . . . . 47 3.5.2 Kontrolne skupine . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 3.5.3 Linux jedrne zmogljivosti . . . . . . . . . . . . . . . . . . . . . . . . 49 3.5.4 Ostale jedrne varnostne funkcionalnosti . . . . . . . . . . . . . . . . 51 3.5.5 Zaščita procesa Docker pred zlonamernimi napadi . . . . . . . . . . 52 Primerjava z ostalimi metodami virtualizacije . . . . . . . . . . . . . . . . 53 4 ANALIZA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.1 Metodologija analize scenarijev . . . . . . . . . . . . . . . . . . . . . . . . 63 4.2 Preizkus vsebnika LXC v vlogi storitve . . . . . . . . . . . . . . . . . . . . 64 4.3 4.2.1 Izdelava vsebnika za programsko rešitev Redis . . . . . . . . . . . . 65 4.2.2 Uporaba programske rešitve Redis v vsebniku . . . . . . . . . . . . . 67 Preizkus vsebnika LXC v vlogi razvojnega in izvajalnega okolja . . . . . . . 72 4.3.1 Medsebojno povezovanje vsebnikov . . . . . . . . . . . . . . . . . . . 72 4.3.2 Deljenje podatkov med vsebniki in gostiteljem . . . . . . . . . . . . . 76 4.3.3 Upravljanje različic slik vsebnikov . . . . . . . . . . . . . . . . . . . 78 4.4 Odločitveni model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 4.5 Rezultati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 5 ZAKLJUČEK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 5.1 Ocena učinkov . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 5.2 Pogoji za izvedbo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 5.3 Možnosti za nadaljnje raziskovanje . . . . . . . . . . . . . . . . . . . . . . 91 6 LITERATURA IN VIRI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 PRILOGI KAZALO SLIK Slika 1.1: Gartnerjev magični kvadrant virtualizacije za leto 2014 . . . . . . . . . . 2 Slika 2.1: Osnovni koncept virtualizacije računalniških fizičnih virov . . . . . . . . 7 Slika 2.2: Primerjava arhitekture nevirtualiziranega sistema z virtualiziranim . . . 8 Slika 2.3: Koncept programskega virtualnega strežnika (tip 2) . . . . . . . . . . . . 10 Slika 2.4: Koncept strojnega virtualnega računalnika (tip 1) . . . . . . . . . . . . . 10 Slika 2.5: Nivoji izvajanja, razdeljeni na obroče Slika 2.6: Pristop binarne translacije . . . . . . . . . . . . . . . . . . . . . . . . . 11 Slika 2.7: Pristop podpore na nivoju centralne procesne enote . . . . . . . . . . . 12 Slika 2.8: Koncept paravirtualizacije . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Slika 2.9: Koncept uporabe vsebnikov . . . . . . . . . . . . . . . . . . . . . . . . . 16 . . . . . . . . . . . . . . . . . . . 11 Slika 2.10: Čas, potreben za pripravo virtualnega izvajalnega okolja - po metodah . 17 Slika 3.1: Koncept pogona Docker . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Slika 3.2: Google trendi glede na virtualizacijsko metodo . . . . . . . . . . . . . . 20 Slika 3.3: Zasnova distribuirane aplikacije na nivoju vsebnika . . . . . . . . . . . . 21 Slika 3.4: Shema zgradbe datotečnega sistema vsebnika . . . . . . . . . . . . . . . 22 Slika 4.1: Razlike v času, potrebnem za izračun (med gostiteljem in vsebniki) . . . 59 Slika 4.2: Razlike v času, potrebnem za izračun (med KVM in vsebniki) . . . . . . 60 Slika 4.3: CPU Linpack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Slika 4.4: I/O pretok - sekvenčen dostop . . . . . . . . . . . . . . . . . . . . . . . 62 Slika 4.5: I/O pretok - naključen dostop . . . . . . . . . . . . . . . . . . . . . . . 63 Slika 4.6: Spletna stran na podlagi dveh vsebnikov . . . . . . . . . . . . . . . . . . 76 Slika 4.7: Polarni grafikon kriterijev odločitvenega modela Slika 4.8: Polarni grafikon analize kaj-če . . . . . . . . . . . . . . . . . . . . . . . 85 . . . . . . . . . . . . . 83 KAZALO TABEL Tabela 4.1: Časi izračunov števila 𝜋, ki smo jih dosegli na gostitelju . . . . . . . . 57 Tabela 4.2: Časi izračunov števila 𝜋, ki smo jih dosegli v vsebnikih . . . . . . . . . 58 Tabela 4.3: Časi izračunov števila 𝜋, ki smo jih dosegli v KVM . . . . . . . . . . . 58 Tabela 4.4: Drevo kriterijev odločitvenega modela in njihove zaloge vrednosti . . . 80 Tabela 4.5: Funkcije odločitvenega modela . . . . . . . . . . . . . . . . . . . . . . . 81 Tabela 4.6: Povprečne uteži kriterijev odločitvenega modela . . . . . . . . . . . . . 82 Tabela 4.7: Rezultati vrednotenja variant odločitvenega modela . . . . . . . . . . . 83 Tabela 4.8: Rezultati vrednotenja variant za analizo kaj-če . . . . . . . . . . . . . . 84 Tabela 4.9: Analiza SWOT - PSPN matrika . . . . . . . . . . . . . . . . . . . . . . 86 POVZETEK Z bliskovitim razvojem računalniške strojne opreme, ki je močno prehitel zahteve programske opreme, so se odprle nove možnosti na sicer že dolgo poznanem in zelo razširjenem področju virtualizacije strežnikov. Tradicionalni pristop polne virtualizacije, kjer virtualiziramo strežnik kot celoto, je preživet. Poleg potratnosti z viri je polna virtualizacija tudi rigidna in nerazdružljivo povezana s hipervizorjem, na katerem teče. Pogosto se zgodi, da je na virtualnem strežniku nameščena zgolj ena storitev, ali še slabše, na njem teče zgolj en proces, kljub temu pa je v ozadju polno virtualiziran celoten strežnik. Podobno zaskrbljujoč je primer, kjer na enem virtualnem strežniku, v enem izvajalnem okolju poganjamo množico storitev in procesov, ki so med seboj različno varnostno in performančno zahtevni. V okviru magistrske naloge smo na praktičnih primerih preučili tehnologije in predstavili metodo virtualizacije na nivoju operacijskega sistema, ki temelji na LXC-vsebnikih. Rezultate smo primerjali s tradicionalnimi metodami virtualizacije strežnikov in na podlagi tega ocenili njihov potencial. Predstavljena metoda koncept virtualizacije strežnikov redefinira v koncept láhkih, prilagodljivih in samozadostnih enot. KLJUČNE BESEDE: virtualizacija, vsebnik, hipervizor, LXC, Docker ABSTRACT With a rapid development of a computer hardware, that passed software’s resource requirements demand, new possibilities have opened up in widely accepted and widespread area of a server virtualization. The traditional approach of full virtualization, which virtualize the entire server stack, is not sustainable anymore. Besides high resource demands, it is also rigidly linked to its hypervisor. It often happens, that such virtual server was provisioned for running only one dedicated service, or even worse, running only one dedicated process, but the entire virtual server is still needed underneath. Similarly concerning is the case, where one virtual server has the same RTE for plurality of services and processes, which are mutually different, security and performance wise. In the context of the master’s thesis, we examined technologies and presented operating system-level virtualization based on LXC containers. Its potential had been evaluated, based on practical cases analysis and the result comparation with traditional methods of server virtualization. The presented method redefines server virtualization to lightweight, flexible, self-contained units. KEYWORDS: virtualization, container, hypervisor, LXC, Docker 1. UVOD Z bliskovitim razvojem računalniške strojne opreme, ki je močno prehitel zahteve programske opreme, so se odprle nove možnosti na sicer že dolgo poznanem in zelo razširjenem področju virtualizacije strežnikov. Tradicionalni pristop t. i. polne virtualizacije, kjer virtualiziramo strežnik kot celoto (vključno s celotnim operacijskim sistemom), je preživet. Poleg potratnosti z viri (angl. overhead) je polna virtualizacija tudi rigidna in nerazdružljivo povezana s hipervizorjem (angl. hypervisor) na katerem teče (Tang in drugi, 2014). Pogosto se zgodi, da je na takem sistemu nameščena zgolj ena namenska storitev, ali še slabše, na njem teče zgolj en namenski proces, kljub temu pa je v ozadju polno virtualiziran celoten strežnik. Podobno zaskrbljujoč je primer, kjer na enem virtualnem strežniku, v enem izvajalnem okolju poganjamo množico storitev in procesov, ki so med seboj različno varnostno in performančno zahtevni. Oba navedena primera bi lahko poskusili racionalizirati z uporabo t. i. vsebnikov (angl. container) oz. nadomestitvijo tradicionalnih virtualnih strežnikov z virtualizacijo na nivoju operacijskega sistema. S tem bi omogočili, da za posamezno storitev ali proces pripravimo ločene, prikrojene vsebnike, v katerih je okolje optimalno prilagojeno zahtevam vsebovane storitve ali procesa. Hkrati bi tako pripravljen vsebnik porabil precej manj sistemskih virov. Poenostavil bi se tudi postopek selitve storitve ali procesa med fizičnimi strežniki - gostitelji (angl. host), saj je vsebnikovo izvajalno okolje v precejšnji meri neodvisno od strežnika, na katerem teče. S tem bi presegli glavne slabosti tradicionalne polne virtualizacije, saj bi bistveno zmanjšali porabo sistemskih virov in bistveno pohitrili oskrbovanje (angl. provisioning) oz. pripravo novih “virtualnih strežnikov”, torej vsebnikov, hkrati pa bi na enem gostitelju lahko dosegli veliko večjo gostoto (angl. density) vsebnikov v primerjavi z gostoto, ki so jo sposobni doseči gostitelji virtualnih strežnikov. Z dodatno uvedbo orkestracije (angl. orchestration) bi lahko povečali odpornost (angl. resilience) storitve ali procesa zoper odpoved ali izpad. Omenjenih prednosti so se očitno začeli zavedati tudi v podjetjih, kjer so bili sicer tradicionalno naklonjeni predvsem tehnologijam polne virtualizacije. V zadnjem letu sta namreč dve vodilni podjetji na področju strežniške virtualizacije, Red Hat Inc. in VMware Inc., 1 podprli razvoj tehnologije vsebnikov. Pri tem je najbolj izpostavljen projekt Docker. Kot rečeno, sta podjetji to storili kljub temu, da imata obe že dobro uveljavljene rešitve za virtualizacijo strežnikov, ki temeljijo predvsem na tradicionalni polni in paravirtualizaciji (Red Hat Inc. 2013; VMware Inc. 2014). V tem kontekstu je pomemben podatek, da je podjetje VMware Inc. v Gartnerjevem1 kvadrantu (angl. Gartner Magical Quadrant; Slika 1.1) strežniške virtualizacije že več let zapored uvrščeno najbolje med vsemi podjetji tega področja (Surksum, 2014). Slika 1.1: Gartnerjev magični kvadrant virtualizacije za leto 2014 Vir: Surksum (2014) V magistrski nalogi bomo preučili in predstavili metodo virtualizacije na nivoju operacijskega sistema, ki temelji na t. i. vsebnikih LXC (angl. LXC - Linux Containters; v nadaljevanju LXC) (Hallyn in Graber, 2013). Potencial in uporabnost izbrane metode oz. tehnologije bomo ocenili glede na ostale metode virtualizacije strežnikov, na podlagi načrtovanja, izvedbe in analize konkretnih primerov uporabe. Pri tem bomo uporabili 1 Gartner Inc. je v svetovnem merilu vodilno podjetje, ki se ukvarja z raziskavami IKT. 2 odprtokodno programsko rešitev Docker, s katero bomo izdelali lastne testne vsebnike LXC, ki jih bomo uporabili v procesu analize. Glede na to, da vsebniki LXC trenutno tečejo zgolj na operacijskem sistemu Linux z jedrom različice 2.6.292 ali novejšim (ne glede na Linux distribucijo), bomo analizo omejili na to platformo operacijskega sistema. V zaključku magistrske naloge bomo interpretirali rezultate in predstavili oceno učinkov ter možnosti za nadaljnje raziskovanje. 1.1 Namen, cilji in raziskovalna vprašanja Namen magistrske naloge je na hipotetičnem primeru analizirati tehnologijo vsebnikov in predstaviti metodo, ki rešuje realen problem, torej analizirati metode virtualizacije, predvsem virtualizacije na nivoju operacijskega sistema, kot osnovo za izvajalno okolje v obliki láhkega, prilagodljivega, samozadostnega vsebnika LXC. Metode virtualizacije bomo analizirali tudi s pomočjo kvalitativne večparametrske analize DEX, s katero bomo še bolj jasno prikazali primernost uporabe predstavljene metode. V ta namen smo si zastavili tri glavne cilje, ki jih želimo doseči v okviru pričujoče magistrske naloge: ∙ predstaviti glavne prednosti in slabosti virtualizacije na nivoju operacijskega sistema oz. uporabe vsebnikov LXC, ∙ predstaviti področja, kjer je uporaba virtualizacije na nivoju operacijskega sistema oz. vsebnikov LXC primerna, ∙ predstaviti rezultate analize, iz katere bomo lahko sklepali, ali je virtualizacija na nivoju operacijskega sistema oz. ali so vsebniki LXC primerni za produkcijsko okolje. Z dosego ciljev bomo prišli do novih spoznanj, iz katerih bomo lahko oblikovali odgovore na raziskovalna vprašanja, ki si jih zastavljamo v izhodišču: ∙ Za katere scenarije je primerna virtualizacija na nivoju operacijskega sistema oz. vsebnikov LXC? ∙ Katere so glavne prednosti in slabosti virtualizacije na nivoju operacijskega sistema 2 LXC-podporo vsebuje že jedro verzije 2.6.27, vendar šele verzija jedra 2.6.29 nudi polno podporo. 3 oz. vsebnikov LXC? ∙ Ali je virtualizacija na nivoju operacijskega sistema oz. vsebnikov LXC primerna tudi za produkcijsko okolje? V zaključku magistrske naloge se bomo na podlagi izvedene analize lahko opredelili do teze: “Z virtualizacijo na nivoju operacijskega sistema oz. vsebnikov LXC lahko ustvarimo láhko, prilagodljivo, samozadostno in infrastrukturno neodvisno izvajalno okolje”. 1.2 Metode dela in struktura naloge V uvodnem delu magistrske naloge bomo na podlagi analize dokumentov in spletnih virov podrobno predstavili teoretična izhodišča in koncepte ter izbrali tehnologije oz. njihove implementacije, s katerimi bomo v nadaljevanju izvedli praktičen del naloge. V empiričnem delu naloge bomo uporabili kvalitativno metodo študije primera (angl. case study method; (Raya, 1984)). V ta namen bomo pripravili lastno testno okolje (angl. test bed), v katerem bomo na praktičnih primerih preizkusili izbrano metodo virtualizacije na nivoju operacijskega sistema LXC. Testiranju bo sledila analiza rezultatov na podlagi primerjalne metode (Demeyer, 2011). Podatke ostalih metod virtualizacije strežnikov bomo pridobili iz sekundarnih virov. Nato bomo izdelali odločitveni model in analizo SWOT (Minton, 2010, str. 80—81). V zaključku bomo povzeli ugotovitve, odgovorili na raziskovalna vprašanja, preverili, ali smo dosegli zastavljene cilje, ter se opredelili do teze, ki smo jo postavili v izhodišču. Opisane metode dela bodo potekale v naslednjih korakih: Prvi korak bo predstavljal širok in poglobljen pregled teoretičnih izhodišč. To bo osnova, na kateri bomo lahko gradili kritično primerjavo metod virtualizacije strežnikov, ki nas bo pripeljala do relevantnih zaključkov. Poseben izziv bosta v tem koraku predstavljala iskanje in študij relevantne literature, saj je izbrana testna tehnologija še zelo sveža, njen resen razvoj se je namreč začel šele pred dobrim letom in pol3 . Naslednji pomemben korak bo izbor tehnologij in implementacij, ki jih bomo postavili ob bok izbrani tehnologiji v preizkušanju - vsebniki LXC. Izbor bomo že v izhodišču omejili na odprtokodne rešitve. V tem koraku bo največji izziv predstavljala ocena, katera 3 http://blog.docker.com/2014/03/happy-birthday-docker/ 4 odprtokodna rešitev je primerna z vidika trenutnega in prihodnjega razvoja oz. podpore (angl. LTS - Long Term Support). Pri številnih odprtokodnih rešitvah se namreč rad pojavi problem, da se razvoj nenadoma ustavi iz takega ali drugačnega razloga. Pogosto se to pripeti pri odprtokodnih projektih, kjer je razvojna skupina majhna, zgolj nekaj ali samo en glavni (angl. core) razvijalec4 . V tretjem koraku bomo preučili, katere praktične situacije, konkretne storitve ali izvajalna okolja lahko uporabimo kot testne scenarije. Na podlagi teh bomo izdelali procedure testiranj, ki bodo kar najbolje odražale realno produkcijsko okolje in upoštevale njegove specifike. V tem koraku bo največji izziv predstavljala izdelava testnih scenarijev, saj bo potrebno programirati simulacije v kompleksnih orodjih ali celo ustvariti lastne testne module (npr. v programskem jeziku Python5 ). V četrtem koraku bomo v okviru kvalitativne večparametrske metode DEX določili kriterije, zalogo vrednosti odločitvenega modela in funkcijo koristnosti. Nato bomo na podlagi rezultatov, pridobljenih v prejšnjem koraku, določili vrednosti kriterijev posamezne variante. Pripravili bomo analizo SWOT in na podlagi ugotovitev s polarnim grafikonom prikazali ocene elementov matrike ter predstavili rezultate odločitvene analize. V tem koraku bo največji izziv predstavljala izdelava odločitvenega modela in izbor ustreznih kriterijev ter zalog vrednosti, saj bo od tega odvisen rezultat oz. kvaliteta primerjave. V zadnjem koraku bomo pripravili povzetek ugotovitev. Preverili bomo, ali smo dosegli vse zastavljene cilje magistrske naloge in ali je bil dosežen njen namen, ter se opredelili do teze, ki smo jo postavili v izhodišču. Struktura magistrske naloge bo skladna s strukturo IMRAD (angl. Introduction, Methods, Research and Discussion (Nair in Nair, 2014, str. 13—25)). Sestavljena bo iz štirih glavnih delov: uvoda, metodologije, raziskave in interpretacije ugotovitev. V uvodnem delu so predstavljeni namen in cilji, raziskovalna vprašanja ter teza magistrske naloge. Temu sledijo opis metodologije dela, predpostavke in omejitve. V nadaljevanju sledi teoretičen del raziskave z opisi tehnologij in konceptov. Drugi del se bo pričel z empirično raziskavo, za katero bo potrebno najprej pripraviti testno okolje, nato pa na konkretnih primerih izvesti testiranja. V zaključnem delu bomo analizirali in interpretirali rezultate, 4 5 Tisti razvijalec, ki koordinira razvoj in izdajanje novih različic programske opreme. https://www.python.org 5 na podlagi katerih bomo preverili dosego zastavljenih ciljev in namena magistrske naloge, si odgovorili na raziskovalna vprašanja in se opredelili do uvodoma postavljene teze ter podali izhodišče za nadaljnje raziskovanje. 1.3 Predpostavke in omejitve V magistrski nalogi se z vidika tehnologij, ki jih bomo uporabili za primerjalno referenco, omejujemo zgolj na odprtokodne rešitve. Zaradi tehničnih značilnosti preučevane metode oz. tehnologije vsebnikov LXC bomo pri vzpostavitvi testnega okolja uporabili operacijski sistem Linux, ki ima za to tehnologijo domorodno (angl. native) podporo. Predpostavljamo, da bodo preučevani viri tehnologije LXC večinoma spletni, saj je tehnologija še zelo mlada, stara zgolj dobro leto in pol. Tehnični okvir empiričnega dela magistrske naloge je hipotetičen, kljub temu z njim iščemo oz. skušamo najti rešitev za realen problem. 2. METODE VIRTUALIZACIJE STREŽNIKOV V uvodu tega poglavja bomo definirali, kaj virtualizacija strežnika sploh je in kako je potekal njen razvoj skozi čas. V nadaljevanju bomo podrobno predstavili vsako izmed treh metod virtualizacije strežnikov, ki jih bomo uporabili za medsebojno referenčno primerjavo. V splošnem lahko virtualizacijo definiramo kot abstrakcijo virov fizičnega računalnika. To običajno dosežemo tako, da med fizično strojno opremo oz. fizične vire in operacijski sistem vpeljemo dodatno abstraktno programsko raven (Mann, 2006). Imenujemo jo hipervizor6 (Slika 2.1). Ta poskrbi, da so fizični viri računalnika skriti operacijskemu sistemu (Slika 2.2), ki teče v virtualnem računalniku (angl. virtual machine - VM). Zato lahko iste vire enega fizičnega računalnika hipervizor deli med več vzporednih logič6 Termin izhaja iz IBM-a, drugi da večinoma imenujejo virtual machine monitor - VMM. 6 nih enot oz. virtualnih računalnikov, na katerih lahko tečejo različni operacijski sistemi hkrati. Goldberg virtualni računalnik definira kot: “učinkovit, izoliran, duplikat fizičnega računalnika”. Slika 2.1: Osnovni koncept virtualizacije računalniških fizičnih virov Vir: prirejeno po Goldberg (1973) Medtem ko razliko med virtualnim in fizičnim v realnem svetu opazimo, pa je za računalniške sisteme virtualno okolje povsem enako fizičnemu. Operacijski sistem in nameščene aplikacije delujejo v virtualnem okolju povsem enako kot na fizičnem računalniku. Osnovni namen virtualizacije je izboljšati izkoristek fizičnih računalniških virov preko enotne platforme, s katero lahko združujemo heterogene in avtonomne vire (Varian, 1997). Virtualizacija je danes sprejeta tehnologija, saj posredno pripelje do povečanja zanesljivosti sistemov, večje fleksibilnosti in znižanja stroškov. Zato se je razširila tudi na druge nivoje računalništva, kot sta npr. virtualizacija diskovnih polj in virtualizacija računalniških omrežij. Kot ena izmed glavnih podpornih tehnologij služi tudi pri sodobnih oblačnih storitvah, ki jih poznamo danes (predvsem pri infrastrukturi kot storitvi, angl. Infrastructure as a Service - IaaS). Začetki računalniške virtualizacije segajo v 60. leta prejšnjega stoletja, ko je podjetje IBM (pionir virtualizacije, več kot 10 let edini vlagal v razvoj tega področja) prvič razdelilo centralni računalnik (angl. mainframe) na več logičnih enot, ki so tekle na enem fizičnem gostitelju. Glavni vzrok za to je bilo naporno in obsežno vzdrževanje velikih centralnih strežnikov kot ene celote. Tako so zaradi težav pri vzdrževanju posredno prišli do spoznanja, da z uporabo logičnih enot lahko dosežejo hkratno poganjanje več procesov oz. aplikacij na enem fizičnem gostitelju (Varian, 1997). Virtualizacija, kot jo poznamo danes, pa se je resno začela razvijati šele v poznih 90. letih prejšnjega stoletja, ko je 7 Slika 2.2: Primerjava arhitekture nevirtualiziranega sistema z virtualiziranim Vir: Mihičinac, lastni prikaz (2014) podjetje VMware prvič predstavilo polno virtualizacijo x867 (Walters, 1999). V teh letih je namreč arhitektura x86 doživela razmah tudi v segmentu strežniških računalnikov, ko je procesor Pentium Pro izpodrinil do tedaj prevladujoče RISC procesorje. V letu 2003 je podjetje XenSource predstavilo prvi odprtokodni x86 hipervizor - Xen. Leta 2006, s prihodom podpore virtualizaciji na nivoju centralne procesne enote - procesorja (angl. central processing unit - CPU), ki sta jo ponujala tako Intel VT (Intel Corporation, 2006) kot AMD SVM (O’Brien, 2006), je na platformi Xen lahko tekel tudi operacijski sistem Microsoft Windows (Knuth, 2007). Glede na dolgo zgodovino razvoja polne in paravirtualizacije lahko tako polno virtualizacijo kot paravirtualizacijo označimo za tradicionalni virtualizaciji (The VAR Guy, 2014). Na področju vsebnikov oz. njegovih predhodnih tehnologij se je razvoj začel že okoli leta 2000, s prihodom FreeBSD 4.0 in njegove podpore t. i. “Jails” (The FreeBSD Documentation Project, 2000). Te ponujajo grob, konceptualni približek temu, kar danes imenujemo vsebnik. Istega leta se je začel tudi razvoj podpornih tehnologij, ki so šele v začetku leta 2014 pripeljale do izida tehnologije vsebnikov LXC8 . Uvodni pregled razvoja virtualizacije skozi čas lahko zaključimo s spoznanjem, da so današnji podatkovni centri (angl. datacenter) pravzaprav programsko definirani9 podatkovni 7 VMware Virtual Platform izide 8. 2. 1999. Stabilna različica LXC 1.0 izide 20. 2. 2014. 9 V celoti virtualizirani vsi računalniški sklopi. 8 8 centri. Vsi njihovi fizični viri so namreč virtualizirani in kot taki združeni v ogromen bazen (angl. pool) logičnih virov, ki je sestavljen iz: virtualnih procesorjev, virtualnega pomnilnika, virtualnih diskov, virtualnih podatkovnih shramb in virtualnih programsko definiranih računalniških omrežij, na katerih lahko poganjamo agilne, skalabilne in konsolidirane virtualne strežnike (Oracle Corporation, 2011). Kljub temu, da je tehnologija virtualizacije skozi čas močno napredovala, je njen pomen skozi čas ostal enak - neodvisnim sistemom omogočati hkratno deljenje istih računalniških virov. 2.1 Polna virtualizacija Termin polna virtualizacija izhaja iz dejstva, da se pri tej metodi virtualizacije lahko v virtualnih računalnikih poganja poln (angl. full) oz. nespremenjen operacijski sistem. Ta se ne “zaveda”, da teče v virtualiziranem okolju, in deluje povsem enako, kot bi deloval na fizičnem računalniku. Skozi čas se je ta definicija nekoliko spremenila oz. razširila - polna virtualizacija sedaj pomeni, da hipervizorju pri zagotavljanju virtualizacije pomaga tudi centralna procesna enota gostitelja10 , torej je virtualizacija polno podprta. Metodo polne virtualizacije delimo na dva tipa. V literaturi ju označujejo kot tip 1 (angl. type 1) in tip 2 (angl. type 2) ali z nazivom programski virtualni računalnik (angl. software virtual machines) ter strojni virtualni računalnik (angl. hardware virtual machines). Tako kot prikazuje Slika 2.3, v tem primeru hipervizor posreduje med operacijskim sistemom gostitelja in operacijskim sistemom virtualnega računalnika. Dostop do fizičnih računalniških virov gostitelja ima samo operacijski sistem gostitelja. Primer takega sistema sta predhodnik današnjega hipervizorja Hyper-V11 , Microsoft Virtual Server 2005, in predhodnik današnjega VMware ESX, VMware GSX. Oba sta za svoje delovanje potrebovala prednameščen operacijski sistem na gostitelju. Ta način virtualizacije za namene virtualizacije strežnikov ni več v uporabi (zgolj za virtualizacijo na namiznih računalnikih). Nadomestil ga je namreč bolj zmogljiv tip 1, strojni virtualni strežnik. V primeru strojnega virtualnega računalnika (Slika 2.4) gostitelj nima nameščenega operacijskega sistema, temveč hipervizor teče neposredno na fizičnih virih računalnika (angl. 10 11 Na primer: Intel VT-x ali AMD-V tehnologija. http://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx 9 Slika 2.3: Koncept programskega virtualnega strežnika (tip 2) Vir: Mihičinac, lastni prikaz (2014) bare metal). Na ta način performančno veliko pridobimo. Primer takega sistema je VMware ESX 12 . Slika 2.4: Koncept strojnega virtualnega računalnika (tip 1) Vir: Mihičinac, lastni prikaz (2014) Koncept strojnega virtualnega računalnika temelji na t. i. binarni translaciji (angl. binary translation) strojnih ukazov (angl. instruction) arhitekture x86 (Shanley, 2009). Le ta pozna štirinivojsko hierarhijo izvajanja strojnih ukazov (angl. instruction) oz. dostopa do fizičnih računalniških virov. Kot prikazuje Slika 2.5, se jih razdeli na nivoje: Ring 0, 1, 2 in 3, torej Obroč 0, 1, 2 in 3, pri čemer je nivo 0 najbolj privilegiran in ima posledično vedno možnost dostopa do fizičnih virov. Tako kot prikazuje Slika 2.6, uporabniške aplikacije običajno tečejo v obroču 313 , medtem ko operacijski sistem v virtualnem računalniku sistemske klice vedno posreduje prek hipervizorja. Ta za to potrebuje neposreden dostop do fizičnih virov (npr. pomnilnika) in posledično teče v najbolj privilegiranem obroču 0 (Shanley, 2009; VMware Inc. 2007). 12 13 http://www.vmware.com/products/esxi-and-esx/overview Vendar se nesistemski klici, zaradi performančnih izboljšav, neposredno predajo v izvajanje računal- niškim fizičnim virom. 10 Slika 2.5: Nivoji izvajanja, razdeljeni na obroče Vir: prirejeno po Welsh (2007) Glavne prednosti pristopa binarne translacije: ∙ operacijskega sistema v virtualnem računalniku ni potrebno prilagajati, ∙ operacijski sistem v virtualnem računalniku se ne “zaveda”, da teče v virtualiziranem okolju. Glavne slabosti pristopa binarne translacije: ∙ slab izkoristek fizičnih računalniških virov, ∙ kompleksna zasnova, zaradi pomanjkljive podpore za klasično virtualizacijo, t. i. “trap-and-emulate”. Slika 2.6: Pristop binarne translacije Vir: prirejeno po VMware Inc. (2007) S podporo virtualizaciji na nivoju centralne procesne enote je pridobil tudi strojni virtualni 11 računalnik (Slika 2.7), saj so s tem odpravili glavne pomanjkljivosti pristopa binarne translacije (podpora za virtualizacijo “trap-and-emulate”), kar se seveda najbolj odraža na povečanju zmogljivosti (hitrosti) (Yang, 2007; Shields, 2008; VMware Inc. 2007). Slika 2.7: Pristop podpore na nivoju centralne procesne enote Vir: prirejeno po VMware Inc. (2007) Glavne prednosti pristopa podpore na nivoju centralne procesne enote: ∙ močno povečana zmogljivost (pohitritev), ∙ ponudniki oz. razvijalci na trg pošljejo hipervizor kot namensko napravo (angl. appliance) oz. v obliki strežniškega operacijskega sistema. Glavna slabost pristopa podpore na nivoju centralne procesne enote: ∙ ponudniki oz. razvijalci hipervizorske programske opreme objavijo t. i. HCL (angl. hardware compatibility list) in s tem omejijo nabor strojne opreme, ki jo lahko uporabimo kot gostitelja. 2.2 Paravirtualizacija Predpona “para-” je grška izposojenka in v slovenskem prevodu pomeni: pri ali k eni strani, zraven, ob boku, poleg, vzporedno (npr. parabola - odstavek, paralelen - vzporeden). S to predpono običajno označimo pomožne predmete ali dejavnosti, predvsem takrat, ko označujemo zamenjavo ali spremembo, v skrajnih primerih tudi nepravilnost ali odmik 12 od ustaljenega (Dictionary.com LLC, 2014). Pri virtualizaciji strežnikov se predpona para- nanaša na komunikacijo med virtualiziranim operacijskim sistemom in hipervizorjem, v luči performančnega izboljšanja in povečanja učinkovitosti. Tako kot prikazuje Slika 2.8, se v tem primeru uporabi nestandardno, prilagojeno jedro operacijskega sistema, kar omogoči nadomeščanje strojnih ukazov, ki jih ni moč virtualizirati, s t. i. hiperklici (angl. hypercalls). Ti imajo možnost neposredne komunikacije s hipervizorjem, ki je hkrati tudi vmesnik za ostale kritične operacije jedra operacijskega sistema, kot npr.: upravljanje pomnilnika, rokovanje s prekinitvami (angl. interrupt handling) in vzdrževanje sinhronizacije ure (angl. timekeeping). Slika 2.8: Koncept paravirtualizacije Vir: prirejeno po VMware Inc. (2007) Glavna razlika med para- in polno virtualizacijo je v tem, da mora virtualiziran operacijski sistem v primeru paravirtualizacije uporabljati t. i. para-API14 , torej mora biti prilagojen, medtem ko so pri polni virtualizaciji sistemski klici virtualiziranega operacijskega sistema izvedeni prek binarne translacije, kar je za virtualiziran operacijski sistem transparentno. V primeru, ko operacijskega sistema ne moremo ali ne želimo prilagoditi, ga na ta način ne moremo virtualizirati. Obstaja sicer primer, kjer je pod licenco GPL15 odprtokodna skupnost razvila posebne gonilnike16 , ki omogočijo uporabo paravirtualizacije tudi na operacijskih sistemih, kjer to sicer ne bi bilo mogoče (Microsoft Windows). Vendar se 14 http://wiki.xen.org/wiki/Xen_Project_Software_Overview General Public License - http://www.gnu.org/copyleft/gpl.html 16 Xen GPLPV - http://wiki.xen.org/wiki/Xen_Windows_GplPv 15 13 rešitev v praksi ni obnesla, saj je performančno bistveno bolje take operacijske sisteme virtualizirati z metodo polne virtualizacije. Prednost paravirtualizacije se kaže predvsem v manjši skupni porabi virov (angl. overhead). Lahko jo celo kombiniramo z metodo polne virtualizacije na način, da gnezdimo dve virtualizaciji hkrati17 - v virtualni računalnik polne virtualizacije namestimo paravirtualizacijski hipervizor in na njem poganjamo virtualne računalnike s prilagojenim operacijskim sistemom. Omenjen scenarij se lahko na primer uporabi takrat, ko za virtualizacijo najamemo vire v oblaku, ki so kot taki že v osnovi virtualizirani. Ker v vseh primerih paravirtualizacije uporabljamo prilagojen operacijski sistem, to lahko povzroči težave pri nadgradnjah, kot tudi pri odpravljanju motenj (angl. troubleshooting), saj gre pri omenjenih prilagoditvah za posege globoko v jedro operacijskega sistema (Xen Project, 2013; Knuth, 2007). Vsekakor lahko prednosti tehtamo le, če poznamo vzrok za virtualizacijo nekega sistema in na podlagi tega ocenimo, katero metodo virtualizacije je najbolj smotrno izbrati. Tipičen primer paravirtualizacije je Xen project18 , ki s prilagoditvami jedra virtualizira centralno procesno enoto in pomnilnik, vhodno/izhodne (angl. input/output - I/O) naprave pa virtualizira prek namenskih gonilnikov na nivoju virtualiziranega operacijskega sistema. Skozi prizmo Xena predstavlja paravirtualizacija drugo generacijo virtualizacije, pri čemer polno virtualizacijo pojmuje kot prvo generacijo virtualizacije. Dejansko pa je paravirtualizacija že dolgo poznana metoda virtualizacije in na nek način zelo podobna IBM-ovim prvim poskusom virtualizacije. Skozi čas so tudi pri Xenu spoznali prednosti polne virtualizacije in tudi sami poleg rešitev za paravirtualizacijo ponudili rešitve za polno virtualizacijo (Xen Project, 2013). 2.3 Virtualizacija na nivoju operacijskega sistema Glauber Costa, eden izmed pomembnih razvijalcev Linux jedra, je že na konferenci LinuxCon 2012 Europe dejal: "I once heard, that hypervisors are living proof of operating system’s incompetence"(Costa, 2012), torej pravi: "Uporaba hipervizorjev kaže zgolj ne17 18 PV on HVM - http://wiki.xen.org/wiki/PV_on_HVM http://www.xenproject.org 14 zadovoljivo delovanje operacijskega sistema". Poznamo več implementacij virtualizacije na nivoju operacijskega sistema (Solaris Zones, BSD Jails, Parallels OpenVZ, Linux V-Server itd.), vendar le implementacija vsebnikov LXC že od svojega izida deluje na serijskem, nespremenjenem Linux jedru. Tehnologija LXC je relativno nova19 , saj je bilo treba izpolniti predpogoje na nivoju operacijskega sistema20 , da bi se lahko razvila tudi sama (Bottomley in Emelyanov, 2014). Dejstvo, da tehnologijo masovno uporablja tudi Google, jo naredi še bolj zanimivo. Googlov senior razvijalec oblačne platforme Joe Beda, je namreč na letošnji konferenci Gluecon21 med svojim predavanjem (Beda, 2014) z naslovom “Managing Containers at Scale on Google Compute Engines” oz. Upravljanje masovne uporabe vsebnikov za Google Compute Engines, med drugim podal dve zelo zanimivi dejstvi, citiram: ∙ “Everything at Google runs in a container.” - “Na Googlu vse teče oz. vse poganjamo v vsebnikih.”, ∙ “We start over two billion containers per week.” - “V ta namen tedensko zaženemo več kot dve milijardi vsebnikov.” Google pa pri tem ni osamljen, saj tehnologijo že od zgodnjih faz razvoja podpira Red Hat Inc., na zadnji konferenci VMworld 2014 je podporo najavil VMware Inc. (Wolf, 2014), pred njim na konferenci DockerCon 201422 tudi vsi “veliki”: IBM, Amazon, Facebook, Twitter, Rackspace ter pred nekaj dnevi, konkretno 16. oktobra 2014, sodelovanje napove tudi Microsoft (McAllister, 2014; Foley, 2014; Janakiram MSV, 2014). LXC-tehnologija je láhka (angl. lightweight) virtualizacijska metoda, s katero ustvarimo vsebnike, ki jih nato sočasno poganjamo na enem gostitelju. Vsebniki so med seboj “izolirani” (angl. isolated) na podlagi funkcionalnosti jedrnih kontrolni skupin (angl. kernel control groups - cgroups) in jedrnih imenskih prostorov (angl. kernel namespaces). Strogo tehnično gledano je vsebnik LXC sestavljen iz nekaj običajnih procesov, ki tečejo na jedru operacijskega sistema gostitelja. Z uporabo jedrnega imenskega prostora lahko ustvarijo lasten “pogled” na sistem gostitelja (npr. na omrežne naprave, na sistemsko drevo 19 20 LXC stabilna različica 1.0 izšla 20. 2. 2014, razvoj le te je trajal pet let (od leta 2008 dalje). Zagotoviti podporo za: jedrne imenske prostore (angl. kernel namespaces), ustrezen varnostni profil SElinux oz. AppArmor, funkcionalnost cgroups, chroots s pivot_root podporo, itd. 21 http://gluecon.com/2014/ 22 http://www.dockercon.com 15 procesov (angl. PID tree), na priklopne točke (angl. mountpoints) itd.). Z uporabo jedrnih kontrolnih skupin lahko upravlja, nadzira, dodeljuje in omejuje sistemske vire, ki so vsebniku na voljo. Vsebniki si lahko z gostiteljem delijo sistemske knjižnice in sistemsko programje, če oba potrebujeta oz. uporabljata iste. V primeru, da vsebnik potrebuje sistemske knjižnice in programje, ki ga ni na gostitelju ali ni združljivo z njegovo distribucijo, pa se v vsebnik lahko namestijo tudi ločeno (Slika 2.9). Slika 2.9: Koncept uporabe vsebnikov Vir: prirejeno po Walsh (2013) Konceptualno je tehnologija LXC podobna oz. je naslednik tehnologije chroot (Peikari in Chuvakin, 2004), njuna glavna razlika je v tem, da chroot lahkó izvajalno okolje (angl. runtime environment - RTE) izolira le na nivoju datotečnega sistema (angl. filesystem), medtem ko gre tehnologija LXC precej dlje, saj omogoča upravljanje in nadzor virov gostitelja. Njene glavne prednosti so (Oracle Corporation, 2012): ∙ izolacija na nivoju procesa in virov, ∙ skupna poraba virov (angl. overhead) se praktično ne poveča, posledično lahko na gostitelju dosežemo visoko gostoto (angl. density) virtualiziranih okolij, ∙ LXC upravlja vire v realnem času (angl. real-time), kar ga performančno postavlja ob bok nevirtualiziranemu okolju (libvirt.org, 2014), ∙ omogoča upravljanje strojnih virov gostitelja na relaciji s posameznim vsebnikom, ∙ zelo hitra in relativno lahka vzpostavitev (angl. deploy) vsebnika, z uporabo vnaprej pripravljenih predlóg (Slika 2.10). 16 8-24h 5-10min 150 100 15 50 nevirtualizirano polna virtualizacija Potreben čas za pripravo [𝑠] 600 86,400 Slika 2.10: Čas, potreben za pripravo virtualnega izvajalnega okolja - po metodah 10-15s vsebnik Vir: prirejeno po Strauss (2014) Omejitve tehnologije LXC: ∙ vsebniki tečejo znotraj jedra gostitelja, zato jedra v vsebniku ni mogoče prilagoditi, ∙ v vsebnikih lahko poganjamo zgolj operacijski sistem Linux, ∙ varnost je v pretežni meri odvisna od gostitelja, ∙ v zgodnjih razvojnih različicah je bila varnost vsebnikov LXC vprašljiva, predvsem zaradi nedokončanega razvoja že omenjenih podpornih tehnologij kot podpore v Linux jedru samem. Uporaba vsebnikov LXC dobi povsem novo dimenzijo, ko jo uporabimo skupaj z odprtokodno programsko rešitvijo Docker23 . Ta je namenjena razvijalcem in sistemskim administratorjem, ki s pomočjo Dockerja lahko ustvarijo, izmenjujejo, posredujejo in poganjajo distribuirane aplikacije oz. storitve. Naslednje poglavje bomo namenili predstavitvi programske rešitve Docker, ki poleg tehnologije LXC predstavlja glavno komponento, s katero bomo izpeljali empirični del magistrske naloge. 23 https://www.docker.com/ 17 3. PROGRAMSKA REŠITEV DOCKER Docker je odprtokodni pogon (angl. engine), ki omogoča avtomatizacijo namestitve aplikacije v vsebnik, nadaljnje verzioniranje, recikliranje in deljenje vsebnika ter gradnjo lastnih ekosistemov z orodji, vezanimi na njegov vmesnik API (angl. application programming interface). Ustvarili so ga v podjetju Docker Inc.24 in je na voljo prosto, v skladu z licenco Apache 2.025 . Razvoj se je pričel 18. januarja 2013, prva preizkusna različica 0.1.0 je bila objavljena 25. marca 2013, trenutno aktualna stabilna različica 1.3.0 pa je bila objavljena pred nekaj dnevi, 16. oktobra 2014. V osnovi je Docker sestavljen iz: ∙ pogona Docker (angl. engine) in orodij, torej tehnologije za upravljanje virtualizacije láhkih in zmogljivih odprtokodnih vsebnikov, ∙ definiranega toka (angl. workflow) izdelave in distribucije vsebnika (lahko tudi prek javnega zvezdišča Docker26 (angl. hub)). Tako kot prikazuje Slika 3.1, Docker na jedrnem operacijskem sistemu teče kot običajen proces, enako velja za vsebnike. Ker ni potrebe po hipervizorju, imamo v tem primeru minimalno povečano skupno porabo (angl. overhead) in performanse vsebnika, identične sistemskim. Primarno je namenjen razvijalcem programske opreme in sistemskim administratorjem. Docker definira tok razvoja, distribucije in poganjanja aplikacij znotraj vsebnikov (Turnbull, 2014; Docker Inc. 2014). To pripelje do poenostavitve postopka izolacije izbrane aplikacije in njenih odvisnosti (angl. dependency) v vsebnik. Na podlagi t. i. predloge Dockerfile27 namreč lahko postopek ustvarjanja vsebnika avtomatiziramo. Zato lahko hitro ustvarimo želeno množico prilagojenih izvajalnih okolij oz. vsebnikov, ki že vključujejo nameščen izoliran proces, aplikacijo ali storitev. Ne da bi bilo treba posegati v vsebnik, ta lahko teče tako na osebnem prenosnem računalniku kot v podatkovnem centru ali v 24 Pred tem se je podjetje imenovalo dotCloud Inc. PaaS (angl. Platform As A Service). in je bilo eno od prvih ponudnikov Sprememba naziva se je zgodila 29. http://blog.docker.com/2013/10/dotcloud-is-becoming-docker-inc/ 25 http://www.apache.org/licenses/LICENSE-2.0.html 26 https://hub.docker.com/account/signup/ 27 https://docs.docker.com/reference/builder/ 18 10. 2013 - Slika 3.1: Koncept pogona Docker Vir: prirejeno po Docker Inc. (2014) oblaku. Prehod iz okolja razvoja v fazo testiranja in nato v produkcijsko okolje teče veliko bolj gladko. Izvajalnega okolja namreč med fazami ni treba ponovno vzpostavljati. Po potrebi lahko storitev distribuiramo v več neodvisnih (povezanih) vsebnikov, ki tečejo na različnih gostiteljih. Na ta način storitev preprosto skaliramo. Končni rezultat je močno skrajšan cikel med fazo razvoja in fazo produkcije, infrastrukturno neodvisna ter skalabilna storitev. Dva najbolj pogosta primera uporabe sta: ∙ prilagojeno, samozadostno razvijalsko okolje, ∙ prilagojeno, samozadostno okolje procesa, (distribuirane) aplikacije ali storitve. Oba bomo v empiričnem delu magistrske naloge preizkusili na praktičnih primerih in ju podrobno analizirali. Zakaj smo izbrali ravno Docker? Na podlagi že omenjenih novih sklenjenih partnerstev med številnimi vodilnimi podjetji področja in na podlagi trendov, ki jih prikazuje Slika 3.2, lahko sklepamo, da smo v tem trenutku priča vzponu novih metod virtualizacije, pri čemer Docker predstavlja njihovo vodilno silo. Nedavno se jim je v odprtokodnih projektih pridružil zelo uspešen in prodoren manager Ben Golub28 , ki je prevzel funkcijo izvršnega direktorja, tako da se je ustanovitelj Solomon Hykes29 kot tehnični direktor posvetil zgolj razvoju. Pričakovati je, da bosta oba veliko prispevala k še hitrejšemu vzponu tehnologije. 28 29 https://www.linkedin.com/in/bengolub https://www.linkedin.com/in/solomonhykes 19 Slika 3.2: Google trendi glede na virtualizacijsko metodo Vir: Google Inc. (12. oktober 2014) Ta sprememba prinaša tudi zasuk pri zasnovi in postavitvi (angl. deploy) aplikacij oz. storitev. Te bodo glede na njihove logično zaključene gradnike čedalje bolj distribuirane po več med seboj povezanih vsebnikih, ki bodo tekli na katerikoli virtualizirani ali fizični infrastrukturi (Slika 3.3). Predstavljen koncept, ki se povsem ujema z dogajajočimi se organizacijskimi spremembami, tradicionalno ločene razvijalce in sistemske administratorje povezuje v t. i. heterogene skupine “DevOps” 30 . Nekatera večja IT podjetja (eBay, Spotify, Yandex, Baidu ...) že preizkušajo omenjeni model. Premik k distribuiranim aplikacijam oz. storitvam lahko merimo tudi na ravnokar ustanovljenem Docker Hub Registryju31 , kjer je v roku treh mesecev po zagonu storitve moč našteti že preko 35000 predpripravljenih osnovnih diskovnih slik (angl. disk images; v nadaljevanju slika). Verjetno bo preteklo še nekaj časa, preden bodo tudi tradicionalna poslovna okolja (finančne institucije, javna uprava itd.) sprejela ta koncept (Docker Inc. 2014; Turnbull, 2014). 30 31 http://www.gartner.com/it-glossary/devops https://registry.hub.docker.com 20 Slika 3.3: Zasnova distribuirane aplikacije na nivoju vsebnika Vir: Docker Inc. (2014) 3.1 Zahteve in omejitve Osnovne zahteve, ki jih moramo izpolniti se delijo na odvisnosti jedra gostitelja in odvisnosti izvajalnega okolja. Gostitelj mora imeti nameščen operacijski sistem Linux, ki poganja 64-bitno jedro različice 3.8 ali novejše (za razliko od tehnologije LXC, ki teče že na jedru verzije 2.6.29 ali novejšem). V izvajalnem okolju morajo biti nameščene naslednje komponente: iptables 1.4 ali novejši, git 1.7 ali novejši, procps (ali druga podobna komponenta, ki vsebuje orodje “ps”), XZ Utils 4.9 ali novejši in pravilno priklopljene (za vsak fizičen vir ločeno) jedrne kontrolne skupine cgroups. Privzeti datotečni sistem vsebnika, ki mora imeti podporo za tankoplastne sloje (angl. thin provisioned layers), je prilagojen Linux distribuciji gostitelja. Zahtevani sta podpori “union mount” 32 in “copy-on-write” 33 , ki omogočata, da se lahko več datotečnih sistemov, delujočih v načinu “samo za branje” (angl. read-only), hierarhično razvrsti v prekrivajoče se sloje ter vse te sloje hkrati priklopi tako, kot da bi šlo za enoten datotečni sistem (angl. union mount). Pri tem zgolj najvišji sloj deluje v načinu, kjer je omogočena možnost pisanja (Slika 3.4). Če spremenimo obstoječo datoteko na datotečnem sistemu, ki deluje v načinu “samo za branje”, se modificirana datoteka skopira v hierarhično najvišji sloj (angl. 32 33 Union mounts in 4.4BSD-lite (Pendry in McKusick, 1995) Copy On Write Based File Systems Performance Analysis And Implementation (Kasampalis, 2010) 21 copy-on-write), izvorna datoteka pa se prikrije. Tako dobimo vtis, kot da smo spremenili obstoječo datoteko na običajnem datotečnem sistemu. Docker lahko na ta način preprosto prikaže spremembe na datotečnem sistemu med različicami vsebnika (angl. diff) in zelo učinkovito sestavlja nove vsebnike, ker reciklira uporabo vseh datotečnih sistemov, ki delujejo v načinu “samo za branje”. V osnovi je priporočena uporaba tistih datotečnih sistemov, ki imajo zagotovljeno t. i. podporo “upstream” v jedru. Seveda pa mora podpirati dva primarna datotečna sistema, brez katerih ni moč poganjati operacijskega sistema Linux: bootfs, kjer je nameščeno jedro, in rootfs, kjer so dostopne sistemske mape /dev, /proc, /etc, /tmp, itd., če niso priklopljene na dodatne diskovne particije (Docker Inc. 2014; Turnbull, 2014). Slika 3.4: Shema zgradbe datotečnega sistema vsebnika Vir: Turnbull (2014) 3.2 Namestitev Docker smo seveda namestili na operacijski sistem Linux. Izbrali smo distribucijo CentOS verzije 734 , ker gre za brezplačno distribucijo, namenjeno podjetjem (angl. enterprise class35 ). Iz tega izvira tudi njeno ime “Community Enterprise Operating System”. Distribucijo po večini uporabljajo podjetja, ki za njeno uporabo ne potrebujejo plačljive 34 35 CentOS 7 izšel 7. 7. 2014. Se nanaša na zmožnost produkta - tak produkt lahko upravlja kompleksne procese oz. storitve (Gartner Inc. 2014). 22 podpore oz. certificiranih okolij. CentOS je sicer 100% “rebuild” 36 plačljive distribucije Red Hat Enterprise Linux - RHEL in je popolnoma skladen z njihovimi redistribucijskimi zahtevami. Skladno z zahtevami Dockerja smo uporabili 64-bitno arhitekturo jedra različice 3.10.0-123.8.1 in najnovejšo različico LXC 1.0.6. V uradnem repozitoriju CentOS še ni mogoče dobiti najnovejše Docker različice 1.337 , zato smo ga pred namestitvijo prenesli neposredno z Dockerjeve spletne strani. Strojna računalniška oprema oz. strežnik, na katerem smo poganjali programsko opremo, ima naslednje karakteristike: R Xeon○ R E5-2640 s taktom 2,5Ghz, ∙ dva šestjedrna, dvanajstnitna procesorja Intel○ ∙ 128GB DDR3 RAM, ∙ dva diska SAS Intel 300GB SSD, ∙ dva omrežna 1GB-priključka. V nadaljevanju bomo postopoma, po korakih predstavili postopek namestitve Dockerja in njegovih programskih odvisnosti. Opis postopka namestitve operacijskega sistema namenoma ni zajet v tem poglavju, saj gre za rutinsko opravilo, ki ga ni treba posebej pojasnjevati in presega okvirje te magistrske naloge. Postopek smo začeli z namestitvijo paketa rpm38 LXC. Ker je bila v uradnem repozitoriju CentOS na voljo najnovejša različica, smo paket namestili z ukazom (pakete iz repozitorijev nameščamo z orodjem yum, ki je CentOS privzeti sistemski upravljavec paketov za ukazno vrstico - CLI (angl. Command-Line Interface)): # yum install lxc lxc-templates 36 V celoti ponovno preveden (angl. compiled). Docker 1.3 izšel 16. 10. 2014 38 Sistem za upravljanje paketov (angl. package management system). Ime izhaja iz angleškega naziva 37 “Red Hat package manager”, kasneje so ga posplošili v “Recursive initialism”. 23 Uspešnost namestitve smo preverili z ukazom lxc-checkconfig. # lxc-checkconfig Kernel configuration not found at /proc/config.gz; searching... Kernel configuration found at /boot/config-3.10.0-123.8.1.el7.x86_64 –- Namespaces –Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: enabled Network namespace: enabled Multiple /dev/pts instances: enabled –- Control groups –Cgroup: enabled Cgroup clone_children flag: Cgroup device: Cgroup sched: enabled enabled Cgroup cpu account: enabled Cgroup memory controller: Cgroup cpuset: enabled enabled enabled –- Misc –Veth pair device: Macvlan: Vlan: enabled enabled enabled File capabilities: enabled Zgornji izpis je potrdil, da se je LXC rpm uspešno namestil, saj so vse njegove komponente omogočene oz. v stanju enabled. 24 V naslednjem koraku smo najnovejšo različico Dockerja 1.3 prenesli z njegove uradne spletne strani. Namestili smo ga v mapo /usr/local/bin ter mu dodelili sistemsko pravico izvajanja. To smo storili z ukazoma: # wget https://get.docker.com/builds/Linux/x86_64/docker-latest \ -O /usr/local/bin/docker # chmod +x /usr/local/bin/docker Ker smo binarno datoteko Docker namestili v sistemsko mapo, ki je že definirana v spremenljivki $PATH, smo jo lahko pognali brez navajanja eksplicitne poti, npr. tako, da smo izpisali različico ravnokar nameščene datoteke. To lahko storimo z ukazom: # docker –-version Docker version 1.3.0, build c78088f Docker je bil na tej točki že pripravljen za uporabo. Lahko smo ga ročno zagnali kot proces, ki se izvaja v ozadju (angl. daemon): # docker -d & Ta proces mora vedno teči pod korenskim uporabnikom root (angl. root access), saj komunicira prek vtičnice Unix (angl. Unix socket), katere lastnik je root. Kot rečeno, smo Docker sedaj uspešno namestili, vendar s tem še ni bil integriran v operacijski sistem kot sistemska storitev. Če bi ga namestili prek uradnega repozitorija, bi se to zgodilo samodejno. V primeru ročne namestitve, tako kot smo to storili mi, je treba tudi integracijo opraviti ročno. V ta namen smo z github repozitorija Docker prenesli dve konfiguracijski datoteki in ju namestili v sistemsko mapo /etc/systemd/system. To smo storili z naslednjim zaporedjem ukazov: # cd /etc/systemd/system # wget https://github.com/docker/docker/raw/master/contrib/init \ /systemd/docker.service -O docker.service # wget https://github.com/docker/docker/raw/master/contrib/init \ /systemd/docker.socket -O docker.socket 25 S tem smo zaključili integracijo storitve Docker v systemd39 CentOS-a. Na podlagi tega smo definirali politiko storitve, kot npr.: ali se ob zagonu sistema zažene tudi ta storitev, v katerih delovnih nivojih (angl. runlevel) se to zgodi in ali je storitev omogočena oz. onemogočena. Najprej smo preverili, ali je integracija uspela, kar smo storili tako, da smo z ukazom systemctl preverili status storitve: # systemctl status docker.service docker.service - Docker Application Container Engine Loaded: loaded (/etc/systemd/system/docker.service; disabled) Active: inactive (dead) since Tue 2014-10-21 22:56:32 CEST; 4min 35s ago Iz zgornjega izpisa lahko razberemo, da je integracija v systemd uspela, vendar je bila storitev še vedno onemogočena (angl. disabled). Torej z naslednjim korakom smo spremenili status storitve v omogočena (angl. enabled), kar pomeni, da se bo samodejno zagnala ob vsakem zagonu operacijskega sistema. To smo storili z ukazom: # systemctl enable docker.service ln -s ’/etc/systemd/system/docker.service’ ’/etc/systemd/system/multi-user.target.wants/docker.service’ Nato smo ponovno preverili stanje storitve docker.service: # systemctl status docker.service docker.service - Docker Application Container Engine Loaded: loaded (/etc/systemd/system/docker.service; enabled) Active: inactive (dead) since Tue 2014-10-21 22:56:32 CEST; 8min ago Docs: http://docs.docker.com Izpis nam je potrdil, da je storitev omogočena (enabled), vendar še ni bila zagnana, saj se samodejno zažene le ob zagonu operacijskega sistema. Zato smo jo zagnali ročno, kar smo storili z ukazom: 39 Linux upravljavec sistemskih storitev. 26 # systemctl start docker.service Ponovno smo izpisali status storitve docker.service in preverili njeno stanje: # systemctl status docker.service docker.service - Docker Application Container Engine Loaded: loaded (/etc/systemd/system/docker.service; enabled) Active: active (running) since Tue 2014-10-21 23:06:48 CEST; 1min 34s ago Docs: http://docs.docker.com Main PID: 22454 (docker) CGroup: /system.slice/docker.service 2454 /usr/local/bin/docker -d -H fd:// Namestitev, konfiguracija in integracija Dockerja v operacijski sistem so bile s tem zaključene. Zato smo lahko pričeli z gradnjo vsebnikov. Še pred tem smo si lahko ogledali informacije o okolju Docker, ki smo ga ustvarili z zagonom storitve docker.service. To smo storili z ukazom: # docker info Containers: Images: 0 0 Storage Driver: Pool Name: devicemapper docker-253:1-202236837-pool Pool Blocksize: Data Space Used: 65.54 kB Data Space Total: 307.2 MB 107.4 GB Metadata Space Used: Metadata Space Total: Library Version: 733.2 kB 2.147 GB Execution Driver: 1.02.82-git (2013-10-04) Kernel Version: native-0.2 Operating System: 3.10.0-123.8.1.el7.x86_64 CentOS Linux 7 (Core) 27 Glede na to, da v tem poglavju obravnavamo namestitev komponent LXC in Docker, je treba opozoriti tudi na dejstvo, da Docker za svoje delovanje uporablja iptables. V sklopu systemd za iptables skrbi storitev firewalld. Posebej moramo biti pazljivi, da se po vsakem ponovnem zagonu storitve firewalld ponovno zažene tudi storitev docker.service. V nasprotnem primeru se ob zagonu firewalld Dockerjeva pravila za firewalld ne ohranijo! 3.3 Postopek izdelave vsebnika LXC Vsebnik lahko ustvarimo na dva načina. Prva možnost je, da ga v celoti zgradimo sami, druga možnost je uporaba obstoječe slike (angl. image), ki jo nato samo prikrojimo glede na konkretne potrebe in nato iz nje naredimo svojo različico. Obstoječe slike so na voljo prek funkcije LXC “download” ali storitve Docker Registry. Pri tem je predpripravljenih slik LXC bistveno manj (zgolj po ena za nekaj glavnih Linux distribucij) kot slik v Docker repozitoriju, kjer jih lahko štejemo v tisočih. Za primere enostavnih testiranj se običajno poslužujemo ravno slik s prednameščenimi različnimi distribucijami Linux operacijskega sistema, na katero se nato namesti želena programska oprema oz. pripravi testno okolje. Slike so v repozitoriju Docker razdeljene na uradne (angl. official) in uporabniške. Seveda je iz varnostnih razlogov bolje uporabiti le uradne, uporabniške pa zgolj izjemoma. Za vsako Docker sliko v repozitoriju imamo na voljo podatek o datumu izdelave, številu prenosov (angl. download) in ugledu (angl. reputation). Vsaka slika ima lahko več podrazličic (angl. versioning). Če se odločimo namestiti točno določeno različico, to lahko eksplicitno definiramo, v nasprotnem uporabimo izraz latest, ki bo privzeto uporabil zadnjo različico slike. Iz do sedaj opisanega je že razvidno, kaj so nekateri izmed glavnih doprinosov Dockerja pri uporabi LXC-vsebnikov. V praktičnih primerih bomo prikazali razliko med izdelavo vsebnika na podlagi obstoječe slike z LXC-orodji in izdelavo z orodji Docker. Oba primera smo izvedli s pomočjo obstoječe slike oz. v drugem delu z izdelavo lastne slike vsebnika. 28 3.3.1 Postopek izdelave vsebnika iz obstoječe slike z orodji LXC Postopek izdelave vsebnika na podlagi obstoječe slike z LXC orodji smo pričeli z ukazom (z zastavico (angl. flag) -n smo določili ime novega vsebnika, z zastavico -t smo določili predlogo; v konkretnem primeru predlogo za prenos iz centralnega repozitorija): # lxc-create -n fedora-test -t download Le-ta izpiše seznam slik, ki so na voljo v repozitoriju. Želeno sliko smo izbrali tako, da smo vpisali ime distribucije, različico in izbrano arhitekturo. Nato so se komponente slike prenesle na naš računalnik, npr.: Distribution: Release: fedora 20 Architecture: amd64 Downloading the image index Downloading the rootfs Downloading the metadata The image cache is now ready Unpacking the rootfs –You just created a Fedora container (release=20, arch=amd64, variant=default) The default root password is: root Po zaključenem prenosu se je vsebnik na podlagi prenesenih komponent predpripravljene slike ustvaril samodejno. Kot tak je bil pripravljen za uporabo, zagnali smo ga z ukazom (z zastavico -n smo navedli ime vsebnika, ki smo ga želeli zagnati, z zastavico -d smo določili, da se bo vsebnik izvedel kot prikriti proces v ozadju (angl. daemonize)): # lxc-start -n fedora-test -d Nanj se lahko povežemo na več načinov. Če ima prednastavljene omrežne nastavitve, 29 lahko uporabimo ssh40 , povsem enako kot pri oddaljenem dostopu do običajnega strežnika. Če se na vsebnik povezujemo z gostitelja, lahko uporabimo dostop, ekvivalenten konzolnemu dostopu, npr. (z zastavico -n navedemo ime vsebnika, na katerega se želimo povezati): # lxc-console -n fedora-test Connected to tty 1 Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself Fedora release 20 (Heisenbug) Kernel 3.10.0-123.8.1.el7.x86_64 on an x86_64 (tty1) fedora-test login: ali pa se na vsebnik pripnemo (angl. attach) z ukazom (z zastavico -n smo navedli ime vsebnika, na katerega smo se želeli povezati): # lxc-attach -n fedora-test [root@fedora-test ]# V vsebniku lahko izvedemo ukaz, ne da bi se nanj prej povezali. To lahko naredimo samo z gostitelja, in sicer z uporabo ukaza (z zastavico -n smo navedli ime vsebnika, na katerega smo se želeli povezati): # lxc-attach -n fedora-test –- uname -a Linux fedora-test 3.10.0-123.8.1.el7.x86_64 #1 SMP Mon Sep 22 19:06:58 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux 40 http://www.openssh.com/faq.html#1.1 30 3.3.2 Postopek izdelave vsebnika iz obstoječe slike z orodji Docker Postopek izdelave vsebnika na podlagi obstoječe slike z orodji Docker smo pričeli z ukazom: # docker search fedora Zgornji ukaz nam je izpisal seznam slik, ki ustrezajo iskalnemu kriteriju fedora. Iz seznama smo izbrali želeno sliko in zagnali ukaz: # docker pull fedora:20 fedora:20: The image you are pulling has been verified 7d3f07f8de5f: Pull complete 511136ea3c5a: Already exists 782cf93a8f16: Already exists Status: Downloaded newer image for fedora:20 Docker je izbrano sliko želene različice, iz katere smo želeli ustvariti vsebnik, prenesel s centralnega repozitorija v lokalnega. Ko je bil prenos slike zaključen, smo lahko na podlagi te slike že zagnali nov vsebnik. To smo storili z ukazom (z zastavico -d smo določili, da se bo vsebnik izvedel kot prikriti proces v ozadju, z zastavico -i smo omogočili interaktivno povezavo na vsebnik prek standardnega vhoda (angl. STDIN), ob kateri se bo izvedel ukaz bash): # docker run -d -i fedora bash 14f9a8c8d6f99aaf9a91fc9aabd4050b9aa7f2e4a3f8853f03409bc7698f32ec Ob zagonu vsebnika se mu je določil enoličen identifikator “image ID” v obliki štiriinšestdesetmestnega alfa-numeričnega naključno generiranega niza. Uporabimo ga takrat, ko se referenciramo na želeno sliko. Za referenciranje slike zadostuje že prvih dvanajst znakov identifikatorja. V naslednjem koraku smo se povezali na ravnokar zagnan vsebnik. Namenoma smo uporabili univerzalno orodje nsenter41 , s katerim izpostavimo domorodno (angl. native) podporo sistema LXC-procesu. V ta namen smo morali najprej poiskati 41 http://man7.org/linux/man-pages/man1/nsenter.1.html 31 ID procesa vsebnika (angl. process identifier - PID), nato smo se nanj povezali in z zastavicami –-mount, –-uts, –-ipc, –-net, –-pid določili, v katere imenske prostore procesa se želimo preslikati: # docker inspect –-format “{{ .State.Pid }}” 14f9a8c8d6f99aaf9a91fc9aabd4050b9aa7f2e4a3f8853f03409bc7698f32ec 11720 # nsenter –-target 11720 –-mount –-uts –-ipc –-net –-pid 14f9a8c8d6f99aaf9a91fc9aabd4050b9aa7f2e4a3f8853f03409bc7698f32ec [root@14f9a8c8d6f9 /] # Iz zgornjega izpisa je razvidno, da smo se uspešno povezali na vsebnik, kjer se je ob vzpostavitvi povezave, tako kot smo to definirali ob zagonu vsebnika, izvedel program bash in nam kot tak omogočil dostop do ukazne lupine vsebnika. Z zadnjo posodobitvijo Docker 1.3 je bila predstavljena funkcionalnost, ki omogoča injiciranje (angl. injection) novega procesa v obstoječ, že zagnan vsebnik. Torej tudi če vsebnik v osnovi na primer ne vsebuje sistemske lupine bash (ali kateregakoli drugega procesa), jo lahko naknadno injiciramo. To storimo z ukazom docker in stikalom (angl. command) exec: # docker exec -it fedora bash root@14f9a8c8d6f9:/# S tem smo zaključili opis postopkov izdelave vsebnika iz obstoječe slike z orodji LXC in Docker. Iz prikazanega je razvidno, da je ta način izdelave slike z obema orodjema sorazmerno preprost. Seveda ima tudi svoje slabosti, ki se kažejo predvsem v omejenih možnostih prilagajanja vsebnika, ker je osnova zanj določena z izbrano uporabljeno sliko. Če želimo ustvariti vsebnik po meri oz. lastnih zahtevah, ga moramo zgraditi sami. 3.3.3 Postopek izdelave vsebnika po meri z orodji LXC Priprava predlog LXC je zelo kompleksna naloga, saj zahteva poglobljeno ekspertno poznavanje operacijskega sistema, za katerega želimo pripraviti predlogo, in hkrati ekspertno znanje pisanja skript ukazne lupine. Tu s pridom izkoristimo Docker, ki poenostavi izde- 32 lavo kompleksne predloge. V osnovi je predloga lupinska skripta (angl. shell script), ki namesti in konfigurira celoten operacijski sistem v izbrano mapo (angl. directory). Če želimo v vsebniku poganjati celoten operacijski sistem, potem je bolje, da uporabimo že predpripravljeno predlogo izbrane distribucije operacijskega sistema. Lastno predlogo pripravimo le v primeru, ko želimo ustvariti optimiran, prilagojen, minimalen vsebnik. Predloga je sestavljena iz treh glavnih sklopov akcij: ∙ namestitve operacijskega sistema, ∙ osnovne konfiguracije operacijskega sistema, ∙ priprave konfiguracijske LXC-datoteke. Minimalen vsebnik je običajno sestavljen iz inicializacijskega procesa (angl. init) in nekaj osnovnih dinamično povezanih sistemskih knjižnic. Inicializacijski proces je tisti, ki se ob zagonu operacijskega sistema zažene prvi in poskrbi, da se zaženejo sistemske podporne storitve in posledično zažene operacijski sistem kot celota. V preteklosti so Linux distribucije uporabljale inicializacijski sistem System V42 (angl. system five), danes pa prednjači systemd43 . V minimalnem vsebniku ni nujno, da izberemo katerega izmed naštetih, lahko naredimo svojega ali uporabimo preprost, minimalističen nadomestek. Eden izmed takih je program “busybox” 44 , ki v eni izvršilni datoteki vsebuje preprost init sistem in prek tristo standardnih orodij Linux CLI (angl. command-line interface) v obliki vgrajenih modulov. Tudi predloga za minimalen vsebnik LXC je lahko dolga sto in več vrstic, zato je v jedru naloge ne bomo predstavili, v celoti pa se primer take predloge nahaja med prilogami. Bolj podrobno smo se posvetili predlogi Docker, ker smo jo uporabili tudi v empiričnem delu naloge. 42 http://www.linfo.org/system_v.html http://freedesktop.org/wiki/Software/systemd/ 44 http://www.busybox.net/about.html 43 33 3.3.4 Postopek izdelave vsebnika po meri z orodji Docker Priprava slike Docker je precej preprostejša. Postopek izdelave slike bomo predstavili v nekaj korakih. V vsebnik smo namestili že prej omenjeni program busybox. Pripravo lahko izvedemo ročno ali pa v ta namen napišemo skripto, ki nam sestavi vse potrebno za izdelavo slike. V našem primeru smo izvedli in opisali ročni postopek. Postopek smo začeli tako, da smo najprej ustvarili mapo, v kateri smo zbrali komponente, ki smo jih želeli pretvoriti v okolje vsebnika. Pri tem smo predpostavili, da je busybox na gostitelju že nameščen, torej pripravljen za namestitev v vsebnik. Z ukazom cp smo ga prekopirali v za ta namen ustvarjeno mapo bin: # mkdir -p /opt/docker/busybox/bin # cp ‘which busybox‘ /opt/docker/busybox/bin Zaradi preprostejše uporabe busyboxa smo vsak vsebovani modul oz. orodje preslikali v simbolično povezavo (angl. symlink). V nasprotnem primeru bi morali ukaze vedno izvajati preko busybox-a, npr.: namesto klica ukaza awk z awk bi morali uporabiti ukaz busybox awk. Ker je modulov veliko, smo jim preslikave naredili s pomočjo enostavne zanke v ukazni lupini: IFS=$’\n’ modules=($(bin/busybox –-list-modules)) unset IFS for module in “$modules[@]”; do mkdir -p “$(dirname “$module”)” ln -sf /bin/busybox “$module” done Najprej smo torej naredili seznam modulov, ki so vključeni v busybox, in jih v seznamu razvrstili glede na mapo, v kateri se morajo nahajati. Nato je zanka iterirala skozi seznam, pri čemer je naredila ustrezno drevesno strukturo in vanjo razporedila simbolične povezave (angl. symlink) modulov. 34 Rezultat je bil naslednja drevesna struktura map: ./bin ./usr ./usr/bin ./usr/sbin ./sbin in preslikav modulov, ki so bili razvrščeni v mape glede na nivo dostopa (/bin in /usr/bin za uporabniški nivo, /sbin in /usr/sbin korenski dostop (angl. root)): lrwxrwxrwx 1 root root 12 Oct 26 02:57 ash -> /bin/busybox lrwxrwxrwx 1 root root 12 Oct 26 02:57 base64 -> /bin/busybox lrwxrwxrwx 1 root root 12 Oct 26 02:57 cat -> /bin/busybox lrwxrwxrwx 1 root root 12 Oct 26 02:57 chattr -> /bin/busybox lrwxrwxrwx 1 root root 12 Oct 26 02:57 chgrp -> /bin/busybox lrwxrwxrwx 1 root root 12 Oct 26 02:57 chmod -> /bin/busybox ... Z naslednjim ukazom smo pripravljeno drevesno strukturo in pripadajoče datoteke zapakirali v datoteko busybox-test.tar45 (z zastavico –-numeric-owner smo določili, da se za posamezno datoteko podatke o lastniku in skupini shrani zgolj v numerični obliki, z zastavicami -c smo določili, da se bo izvajal proces kreiranja, z zastavico -v smo omogočili podroben izpis poteka kreiranja, z zastavico -f smo določili ime novoustvarjene datoteke .tar) ter z zadnjim parametrom ukaza definirali še pot do mape, ki smo jo zapakirali v datoteko .tar): # tar –-numeric-owner -cvf busybox-test.tar ./ Tako pripravljeno datoteko .tar smo uvozili v Docker, ki jo je shranil v lokalni repozitorij v obliki slike Docker. To smo storili tako, da smo z ukazom cat posredovali vsebino datoteke busybox-test.tar ukazu docker import, pri čemer smo navedli ime, ki ga je slika dobila v lokalnem repozitoriju Docker: 45 http://www.gnu.org/software/tar/ 35 # cat busybox-test.tar | docker import - busybox-test 5d69328520272469914039c99c79cf7c53c769bb6ff067e2db84339eb52d90f5 Ob uvozu Docker sliki, enako kot pri prenosu obstoječe slike s centralnega repozitorija, določi enoličen identifikator v obliki štiriinšestdesetmestnega alfa-numeričnega naključno generiranega niza. Uspešnost uvoza v lokalni repozitorij smo preverili z ukazom: # docker images REPOSITORY busybox-test TAG latest IMAGE ID 5d6932852027 CREATED 28 seconds ago VIRTUAL SIZE 2.571 MB Izpis potrjuje, da smo ročno pripravljene komponente okolja uspešno pretvorili in uvozili v sliko Docker ter jo uspešno shranili v njegov lokalni repozitorij. Ročni postopek bi lahko avtomatizirali tako, da bi potrebne korake zapisali v predlogi lupinske skripte. S tem bi močno pohitrili postopek oskrbovanja (angl. provisioning) novih vsebnikov. Če želimo, lahko lasten vsebnik javno delimo z ostalimi uporabniki Dockerja, tako da ga naložimo v centralni repozitorij Docker. Iz slike smo naredili vsebnik tako, da smo jo referencirali kot predlogo ob zagonu novega vsebnika. Le tega lahko zaženemo kot prikriti proces (angl. daemon), ki bo tekel v ozadju, ali pa ga zaženemo samo toliko, da se v vsebniku izvede zgolj en ukaz (take vsebnike imenujemo vsebniki za enkratno uporabo). Ravno to smo storili tudi mi. Nov vsebnik na podlagi ravnokar ustvarjene slike busybox-test smo zagnali le za toliko, da se je v njem izvedel ukaz ps aux, ki je izpisal vse procese, ki so tekli v vsebniku. To smo storili z ukazom: # docker run -i -t busybox-test ps aux PID USER 1 0 TIME 0:00 COMMAND ps aux Izpis nam potrdi, da je v času izvajanja ukaza ps aux v vsebniku tekel zgolj ta ukaz. Ali se je ukaz v izbranem vsebniku busybox-test resnično izvedel, lahko preverimo tudi za nazaj, in sicer v ta namen ukazu docker ps dodamo zastavico -a, ki poleg trenutno aktivnih vsebnikov izpiše tudi tiste, ki ne tečejo več. Primer: 36 # docker ps -a CONTAINER ID 280c07c17d7e IMAGE COMMAND CREATED STATUS busybox-test:latest "ps aux" 2 seconds ago Exited (0) Stolpec “STATUS” nam potrdi, da se je ukaz uspešno izvedel, saj je izstopna koda napake enaka 0 (angl. error code). V stolpcu “CREATED” je naveden podatek, kdaj se je vsebnik zagnal, v stolpcu “COMMAND”, kateri ukaz se je izvedel, v stolpcu “IMAGE”, na podlagi katere slike se je ustvari vsebnik, ter v stolpcu “CONTAINER ID” podatek o tem, pod katerim ID-jem je tekel vsebnik. V sklopu izdelave lastnega vsebnika z orodji Docker obstaja še ena možnost, ki je kombinacija obeh do sedaj predstavljenih metod. V tem primeru izdelamo t. i. datoteko Dockerfile, ki je konceptualno do neke mere podobna že predstavljenim predlogam za izdelavo slik. V tej datoteki navedemo, na podlagi katere obstoječe slike bomo zasnovali lasten vsebnik, nato pa imamo možnost sliko dodelati tako, da določimo, katera dodatna programska oprema naj se ob gradnji vsebnika vanj namesti in kateri ukazi naj se izvedejo ob prvem zagonu vsebnika ter določimo omrežne in nastavitve izvajalnega okolja, skrbnika vzdrževalca slike ipd. Z naslednjim primerom bomo opisali postopek izdelave vsebnika z datoteko Dockerfile. Pripravili smo ga na podlagi ubuntu Linux distribucije, nanj smo namestili storitev varne lupine sshd (angl. secure shell)46 in smo se nanj nato poskusili povezati. Na začetku datoteke Dockerfile smo z instrukcijo FROM najprej definirali, na kateri obstoječi sliki bo bazirala naša slika. Referencirali bi lahko sliko, ki se nahaja v lokalnem ali centralnem repozitoriju Docker. Poleg naziva slike, lahko navedemo tudi različico želene slike, v našem primeru smo navedli različico latest, torej najnovejšo dosegljivo. 46 http://tools.ietf.org/html/rfc4252 37 FROM ubuntu:latest MAINTAINER Aleksander Mihičinac RUN apt-get update && apt-get install -y openssh-server RUN mkdir /var/run/sshd RUN adduser tester RUN echo ’tester:tojetest123’ | chpasswd EXPOSE 22 CMD ["/usr/sbin/sshd", -D"] Nato smo izvedli zaporedje instrukcij RUN, s katerimi smo v sliki najprej posodobili operacijski sistem, nato smo namestili program openssh-server, ustvarili testnega uporabnika tester in mu določili geslo tojetest123. V zadnjem sklopu smo z instrukcijo EXPOSE sliki določili omrežna vrata (angl. port), na katerih se bo zagnani vsebnik odzival. Docker poskrbi, da se izbrana vrata ustrezno samodejno preslikajo (angl. port mapping) na primerna (višja od 1024) vrata gostitelja. Na koncu smo navedli še instrukcijo CMD, s katero smo določili, kateri program se bo zagnal ob zagonu vsebnika. Datoteko Dockerfile smo tako pripravili in jo uporabili za izgradnjo nove slike. Gradnjo smo zagnali z ukazom docker s stikalom build ter z zastavico -t določili ime nove slike, kot zadnji parameter smo navedli pot, kjer se je nahajala datoteka Dockerfile (zaradi preglednosti smo v spodnjem izpisu odstranili za prikaz postopka nepomembne podrobnosti): 38 # docker build -t sshd-test . Sending build context to Docker daemon 3.072 kB Sending build context to Docker daemon Step 0 : FROM ubuntu:14.04 Step 1 : MAINTAINER Aleksander Mihičinac Step 2 : RUN apt-get update && apt-get install -y openssh-server Step 3 : RUN mkdir /var/run/sshd Step 4 : RUN adduser tester Step 5 : RUN echo ’tester:tojetest123’ | chpasswd Step 6 : EXPOSE 22 Step 7 : CMD /usr/sbin/sshd -D Successfully built f69bd195f107 Gradnja slike se je uspešno zaključila. Iz zgornjega izpisa je razvidno, da je Docker za vsako instrukcijo, ki smo jo navedli v datoteki Dockerfile, izvedel po en korak. Na koncu je izpisal enolični ID slike v lokalnem repozitoriju. Z ukazom docker images smo preverili, ali se je slika resnično nahajala v lokalnem repozitoriju: # docker images REPOSITORY sshd-test TAG latest IMAGE ID f69bd195f107 CREATED 13 minutes ago VIRTUAL SIZE 260.5 MB Izpis potrjuje, da je slika bila v lokalnem repozitoriju in na voljo za izdelavo novega vsebnika. Postopek izdelave vsebnika se ne razlikuje od tistega, ki je bil predstavljen že prej, zato ga na tem mestu ne bomo ponovno pojasnjevali. S tem smo zaključili opise postopkov izdelave lastnega vsebnika in na ta način zaokrožili pregled različnih postopkov in orodij, ki so na voljo za izdelavo slik in vsebnikov. Pri izdelavi lastnega vsebnika smo sedaj prvič opazili prednosti, ki jih prinaša sinergija med LXC in Dockerjem. Pri izdelavi vsebnika na podlagi obstoječe slike večje razlike med postopki in orodji LXC ter Docker ni bilo, medtem ko je pri izdelavi lastnega vsebnika ta razlika zelo očitna. Kompleksnost priprave predloge, na podlagi katere izdelamo lasten vsebnik, je pri LXC bistveno večja, saj so tipične LXC-predloge lahko dolge tudi blizu 39 tisoč vrstic kode, medtem ko so primerljive predloge Docker dolge le od nekaj deset do okoli sto vrstic. Še za razred enostavnejše oz. krajše so datoteke Dockerfile. Ravno to je eden izmed razlogov, ki v osnovi zelo kompleksno tehnologijo naredi zanimivo tudi za širše množice. 3.4 Uporaba in nadgradnja vsebnika LXC V tem poglavju bomo predstavili ukaze Docker (angl. commands), s katerimi upravljamo slikame in vsebnike ter tudi Docker sam. Nekaj smo jih v predhodnih poglavjih že uporabili. Najbolj zanimiva oz. uporabna stikala bomo na konkretnih primerih uporabe tudi podrobneje predstavili. Sintaksa uporabe ukaza docker s pripadajočimi stikali in zastavicami je naslednja: # docker [ZASTAVICE] STIKALO [argumenti...] pri čemer uporaba zastavic in argumentov ni obvezna. Če pri zagonu ukaza docker ne uporabimo nobenega stikala, Docker izpiše seznam vseh možnih stikal. V nadaljevanju jih bomo za namen predstavitve razdelili v tri sklope, najprej bomo predstavili stikala, ki se nanašajo na proces Docker, nato stikala za upravljanje slik in nenazadnje še stikala za upravljanje vsebnikov. Stikala procesa Docker: ∙ info — izpis sistemskih parametrov Docker ∙ login — prijava v centralni repozitorij Docker ∙ logout — odjava s centralnega repozitorija Docker ∙ port — prikaz omrežnih preslikav javnih vrat gostitelja na vrata vsebnika ∙ version — prikaz informacij o različicah komponent Docker Če objavljamo svoje slike ali vsebnike na centralnem repozitoriju Docker, se moramo vanj najprej registrirati. To storimo prek spletne strani https://registry.hub.docker.com. Nato se lahko vanj prijavimo z uporabniškim imenom in geslom. V okviru te magistrske naloge ne bomo javno objavljali naših testnih vsebnikov, zato teh stikal ne bomo uporabljali. Iz prvega sklopa stikal je najbolj zanimivo docker port, ki prikaže stanje preslikav omrežnih 40 vrat med gostiteljem in vsebnikom, npr.: # docker port 8ede9965baa4 22/tcp -> 0.0.0.0:49161 Iz zgornjega izpisa je razvidno, da vsebnik z ID 8ede9965baa4 posluša prek protokola TCP (angl. transmission control protocol) na omrežnih vratih 22 (standardna vrata za storitev oddaljenega dostopa SSH), ki so preslikana na vrata 49161 gostitelja. Tako je SSH storitev v vsebniku posredno prek gostitelja dostopna zunanjim uporabnikom. Stikala za upravljanje slik: ∙ build — zgradi sliko na podlagi datoteke Dockerfile ∙ history — prikaži zgodovine sprememb slike ∙ images — prikaži seznama slik v lokalnem repozitoriju ∙ import — izdelaj sliko datotečnega sistema iz .tar datoteke ∙ load — naloži sliko iz .tar datoteke ∙ pull — prenesi sliko s centralnega repozitorija Docker ∙ push — prenesi sliko v centralni repozitorij Docker ∙ rmi — izbriši eno ali več slik hkrati ∙ save — shrani obstoječo sliko v .tar datoteko ∙ search — poišči sliko v centralnem repozitoriju Docker ∙ tag — označi sliko v lokalnem repozitoriju z značko Nekatera stikala za upravljanje slik smo že uporabili v predhodno predstavljenih primerih. V splošnem stikala tega sklopa omogočajo manipuliranje s slikami na način uvoz/izvoz oz. shrani/izbriši sliko. Zato bomo raje predstavili stikalo docker history, s katerim izpišemo pregled zgodovine sprememb izbrane slike in na ta način dobimo vpogled v to, kako je bila slika zgrajena, npr.: # docker history sshd-test IMAGE CREATED CREATED BY SIZE 24c01e31f32d 25 hours ago /bin/sh -c #(nop) EXPOSE map[22/tcp:] 0fe2f1c5fb97 25 hours ago /bin/sh -c adduser tester ... 41 0 B 333.5 kB Zadnji sklop sestavljajo stikala, ki jih upravljamo z vsebniki. Nekaj jih je konceptualno zelo podobnih ekvivalentnim stikalom za upravljanje slik, le da se v tem primeru seveda nanašajo na vsebnike (npr. stikala za ustvarjanje, uvoz/izvoz in shranjevanje/brisanje vsebnikov). Ostala stikala se v večini nanašajo predvsem na spreminjanje stanja vsebnika, npr. zagnan, vnovič zagnan, ustavljen, v stanju mirovanja. Nekaj stikal je zelo specifičnih in eno izmed teh bomo predstavili tudi v primeru. Stikala za upravljanje vsebnikov: ∙ attach — vzpostavi povezavo z zagnanim vsebnikom, ∙ commit — izdelaj novo sliko iz obstoječega modificiranega vsebnika ∙ cp — kopiraj datoteke/mape iz vsebnika na gostitelja ∙ create — izdelaj nov vsebnik ∙ diff — prikaži seznam sprememb datotečnega sistema vsebnika ∙ events — v realnem času prikazuj sistemske dogodke Dockerja ∙ exec — izvedi ukaz v zagnanem vsebniku ∙ export — izvozi vsebnik v datoteko .tar ∙ inspect — prikaži nizko nivojske podatke o vsebniku ∙ kill — pokončaj zagnan vsebnik ∙ logs — izpiši STDOUT/STDERR vsebnika ∙ pause — preklopi zagnan vsebnik v stanje mirovanja ∙ ps — izpiši seznam vseh zagnanih vsebnikov ∙ restart — vnovič zaženi že zagnan vsebnik ∙ rm — izbriši enega ali več vsebnikov hkrati ∙ run — zaženi ukaz v novem vsebniku ∙ start — zaženi ustavljen vsebnik ∙ stop — ustavi zagnan vsebnik ∙ top — izpiši seznam aktivnih procesov v vsebniku ∙ unpause — izklopi stanje mirovanja vsebnika ∙ wait — blokiraj vsebnik, dokler se ta ne zaustavi in izpiši izhodno kodo Primer iz sklopa stikal za upravljanje vsebnikov se nanaša na nadgrajevanje le-teh. Tako kot smo zapisali že v naslovu tega poglavja, bomo poleg uporabe vsebnikov predstavili tudi eno izmed metod nadgrajevanja vsebnikov. Predhodno smo že omenili, da je z zadnjo 42 različico Docker 1.3 med drugim pridobil tudi novo stikalo za upravljanje vsebnikov docker exec. To omogoča injiciranje ukaza v že zagnani vsebnik. Ravno to pa nam omogoča, da v vsebniku poleg obstoječega procesa zaženemo tudi sistem za upravljanje paketov (npr. yum), pri čemer uporabimo njegovo funkcijo za nadgrajevanje sistema. Postopek bomo predstavili na neposodobljenem vsebniku CentOS, ki smo ga v ta namen prenesli s centralnega repozitorija Docker. Po uspešnem zagonu vsebnika smo začeli postopek posodobitve: # docker exec f8d0a37b5bc0 yum -y update Loading mirror speeds from cached hostfile * base: ftp.arnes.si ... Resolving Dependencies –> Running transaction check –-> Package systemd-libs.x86_64 0:208-11.el7_0.2 will be updated –> Finished Dependency Resolution Dependencies Resolved Package Arch Version Repository Size Updating: systemd-libs x86_64 208-11.el7_0.4 updates 153 k ... Updating : systemd-libs-208-11.el7_0.4.x86_64 1/1 Updated: systemd-libs.x86_64 0:208-11.el7_0.4 Complete! Iz zgornjega zapisa smo odstranili podrobnosti, ki za konkretni prikaz delovanja nadgradnje vsebnika niso relevantni. Ne glede na to je razvidno, da se je v postopku posodobitve namestila novejša različica paketa systemd-libs. Iz posodobljenega vsebnika smo nato naredili novo sliko, ki jo lahko kasneje uporabimo pri ustvarjanju novih vsebnikov. Ob tem smo novi sliki določili ime in značko, npr.: # docker commit f8d0a37b5bc0 centos:posodobljen 43 Z ukazom docker images smo preverili, ali je v lokalnem repozitoriju vidna ustvarjena slika: # docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos posodobljen 4444ad09a979 29 minutes ago 295.8 MB centos latest 87e5b6b3ccc1 3 weeks ago 224 MB Zgornji izpis potrjuje, da smo iz posodobljenega vsebnika uspešno ustvarili novo sliko. Ta nam omogoča, da obstoječi prilagojeni in posodobljeni vsebnik po potrebi preprosto recikliramo. Zaradi tega dosežemo zelo hitro oskrbovanje z novimi vsebniki, ne da bi morali ponovno skozi postopek ustvarjanja in prilagajanja le-teh. Ob koncu poglavja, kjer predstavljamo uporabo vsebnikov Docker, moramo izpostaviti še poseben primer njihove uporabe. Ta se nanaša na vsebnik, v katerem želimo poganjati več primarnih procesov. V osnovi vsebnik Docker tega ne omogoča, zato v ta namen uporabimo orodje za upravljanje procesov Supervisor 47 . Običajno želimo poleg osnovnega procesa v vsebniku imeti vsaj še SSH-proces, saj s tem omogočimo oddaljen dostop do vsebnika. Supervisor sicer omogoča nadzor nad procesi tudi prek enostavnega spletnega vmesnika, vendar prek njega ne moremo dostopati do ukazne lupine vsebnika. Za izpis seznama procesov takega vsebnika smo uporabili ukaz docker top, ki nam je prikazal trenutno zagnane procese v vsebniku. V ta namen smo izdelali in tudi predhodno zagnali vsebnik supervisor-test, vanj pa smo poleg Supervisorja namestili SSH in spletni strežnik Apache48 . Nato smo z ukazom docker ps preverili, ali je vsebnik resnično zagnan: # docker ps CONTAINER ID IMAGE COMMAND PORTS b69a35dacee9 supervisord-test:latest /usr/bin/supervisor 22/tcp, 80/tcp Zgornji izpis nam je potrdil, da se je vsebnik z nameščenim Supervisorjem zagnal. Opazimo lahko, da je ta poslušal tako na omrežnih vratih 22 kot na omrežnih vratih 80 (oboje prek omrežnega protokola TCP). Na omrežnih vratih 22 je torej poslušala storitev za oddaljeni dostop SSH in na omrežnih vratih 80 storitev spletni strežnik Apache. 47 48 http://supervisord.org http://httpd.apache.org 44 Nato smo z ukazom docker top preverili, kateri procesi so dejansko tekli znotraj vsebnika supervisor-test: # docker top b69a35dacee9 UID PID TTY CMD root 3251 pts/14 /usr/bin/python /usr/bin/supervisord root 3264 pts/14 /usr/sbin/sshd -D root 3265 pts/14 /usr/sbin/apache2 -DFOREGROUND Tako kot smo napovedali, v tem vsebniku ni tekel en sam primaren proces, temveč kar trije. Seveda lahko po potrebi nabor procesov še razširimo. S tem smo zaključili poglavje predstavitve uporabe in nadgradnje vsebnikov, v nadaljevanju pa bomo predstavili varnostni vidik uporabe virtualizacije na nivoju operacijskega sistema. 3.5 Varnostni vidik Na celotnem področju informacijskih tehnologij se varnosti posveča veliko pozornosti. Prek medmrežja smo namreč nepretrgoma izpostavljeni možnosti hekerskega napada, še posebej če so sistemi in orodja, ki jih uporabljamo, nevzdrževani oz. neposodobljeni ter kot taki ranljivi. Glede na arhitekturo vsebnika in podpornih tehnologij bomo tveganje vsakega izmed njih varnostno ocenili. V luči intenzivnega razvoja je težko enoznačno trditi, da je uporaba vsebnikov nevarna oz. privzeto varna. K izboljšanju mnenja niso pripomogle dvomljive izjave posameznih vplivnih strokovnjakov, kot na primer izjava Red Hatovega inženirja virtualizacijskih tehnologij Daniela Berrangéja49 leta 2011: “LXC is not secure yet. If I want real security, I will use KVM,” torej “Tehnologija LXC še ni dovolj varna. Če želim varno okolje, izberem KVM”. Seveda je od te izjave preteklo že nekaj let in v tem času se je tudi Linux jedro precej spremenilo, LXC-tehnologija pa je dozorela50 . Podobno je na letošnji DockerCon konferenci trdil tudi bivši vodja razvoja SELinux-a in sedanji vodja projekta integracije Dockerja v RHEL Daniel J. Walsh51 , ko je 49 http://uk.linkedin.com/pub/daniel-berrange/0/7a9/ba3 Prišla do prve stabilne različice po petih letih razvoja. 51 https://www.linkedin.com/pub/dan-walsh/2/29b/a87 50 45 izjavil “Containers do not contain”, torej “Vsebniki ne vsebujejo (varnosti)”. Seveda sta obe izjavi namenoma potencirani, da izpostavita varnostni vidik oz. zavedanje, da vsebniki sami po sebi niso nič bolj varni kot katerikoli drug proces na gostitelju. To pomeni, da je za varnost na gostitelju in v vsebniku treba ustrezno (po)skrbeti. Seveda to pomeni, da moramo s to miselnostjo pristopiti k stvari že v samem začetku, ko npr. predpripravljeno sliko prenesemo s centralnega repozitorija Docker na gostitelja. Nikoli namreč ne vemo, kaj se v sliki nahaja, še posebej v primeru, ko je avtor neznan posameznik in slika ne prihaja iz uradnega vira. Kot smo že omenili, se take slike iz repozitorija uporablja izključno za testne namene, za produkcijsko okolje pa ustvarimo lastne slike ali uporabimo slike, ki so digitalno podpisane s strani razvijalcev uradne distribucije. Ko sliko zaženemo in postane vsebnik, se moramo držati osnovnih načel, ki veljajo tudi za vse ostale procese na sistemu: ∙ procesu dodeli samo tiste sistemske pravice, ki jih resnično potrebuje, ∙ procese oz. storitve zaganjaj brez polnih sistemskih pravic (angl. non-root access) povsod, kjer je to mogoče, ∙ obravnavaj polni sistemski dostop v vsebniku povsem enako, kot bi šlo za polni sistemski dostop na gostitelju ∙ redno posodabljaj operacijski sistem gostitelja in nameščeno programje, ∙ nadzoruj dnevniške zapise, ∙ vedno uporabi varnostne politike SELinux52 oz. AppArmor53 . Analogijo lahko potegnemo tudi z nameščanjem programskih paketov na operacijskem sistemu (.rpm, .pkg), ki naj se vedno nameščajo zgolj z uradnih repozitorijev uporabljene distribucije. Še posebej takrat, ko bomo nameščeno programsko opremo poganjali s polnimi sistemskimi pravicami. Na gostitelju vsebnikov imamo torej opravka z večslojnimi varnostnimi mehanizmi (angl. layered security, tudi layered defense)(Shenk, 2013). Operacijski sistem CentOS 7, ki ga uporabljamo za izvedbo empiričnega dela magistrske naloge, ima domorodno podporo za varnostne mehanizme, ki jih bomo predstavili v nadaljevanju. 52 53 http://selinuxproject.org http://wiki.apparmor.net 46 3.5.1 Jedrni imenski prostori Jedrni imenski prostori (angl. kernel namespaces) predstavljajo ključni in najbolj primaren nivo izolacije procesov. Z njimi dosežemo, da se procesi, ki tečejo v vsebnikih, med seboj ne “vidijo” oz. ne morejo vplivati na izvajanje drug drugega. Docker uporablja naslednje jedrne imenske prostore, ki se nanašajo na različne vire gostitelja: ∙ pid — skrbi, da so v vsakem vsebniku procesi številčeni povsem ločeno od procesov na gostitelju. LXC procesu podrejeni podprocesi ne morejo komunicirati niti s podprocesi na istem nivoju niti z nadrejenimi procesi višje po drevesni hierarhiji procesov. ∙ user — skrbi za ločeno številčenje uporabnikovega ID (angl. user identifier - UID) med uporabniki na gostitelju in uporabniki v vsebniku. ∙ net — se nanaša na omrežni sklad (angl. network stack) in omrežne vire gostitelja; omogoča, da si procesi oz. vsebniki delijo iste strojne omrežne vire, ne da bi se tega zavedali ali bili sposobni to zaznati ali bili sposobni posegati v komunikacijo drugega vsebnika. Vsak net jedrni imenski prostor ima svojo tabelo usmerjanja (angl. routing table), svoje veriženje iptables54 in pripadajoče tabele pravil iptables. ∙ ipc — skrbi za izolacijo sistemskih semaforjev (angl. semaphores), sporočilnih čakalnih vrst (angl. message queues) in deljenih pomnilniških segmentov (angl. shared memory segments). V splošnem gre za podedovano podporo (angl. legacy support), saj jih je v modernih sistemih nadomestil POSIX IPC55 . Kljub temu nekatere storitve še vedno uporabljajo IPC, tak primer je PostgeSQL (The PostgreSQL Global Development Group, 2014). ∙ mnt — se nanaša na priklopne točke (angl. mountpoint), ki so vidne vsebniku. Samo procesi v istem jedrnem imenskem prostoru kot določena priklopna točka jo bodo videli in imeli možnost priklopa (angl. mount), za ostale procese v drugih jedrnih imenskih prostorih pa so nevidne. 54 55 http://www.netfilter.org http://docs.oracle.com/cd/E23824_01/html/821-1602/svipc-posixipc.html 47 ∙ uts — se nanaša na ime gostitelja, ki ga lahko na podlagi tega jedrnega imenskega prostora spreminjamo za vsak vsebnik posebej. Tako lahko vsebnikom določimo imena (angl. hostname), kot bi to počeli na gostitelju. Povezovanje na že zagnan proces oz. vsebnik, ki uporablja jedrne imenske prostore, je dobilo domorodno podporo v Linux jedru 3.0 in novejših (ki podpira sistemski klic setns56 ). 3.5.2 Kontrolne skupine Kontrolne skupine (angl. control groups) predstavljajo naslednjo ključno komponento vsebnikov. Z njimi nadzorujemo in omejujemo količine virov (pomnilnika, procesorja, diska), ki so vsebniku na voljo. S tem dosežemo granularno delitev virov med vsebniki in gostiteljem, in kar je najpomembneje, vsebnike omejimo do te mere, da ne ogrozijo delovanja gostitelja. Pomembno vlogo igrajo tudi pri branjenju gostitelja oz. vsebnikov pred napadi porazdeljene ohromitve sistema (angl. distributed denial of service attack DDoS). Docker uporablja tudi posebne kontrolne skupine, imenovane kontrolne skupine naprav (angl. device control groups). S pomočjo teh lahko določimo, katere naprave lahko uporabljamo znotraj vsebnika. Na ta način onemogočimo dostop do naprav, ki bi jih lahko vsebnik izkoristil za napad na gostitelja. Prek naprav te vrste namreč lahko do določene mere vplivamo na konfiguracijo jedra gostitelja. Naprave, ki se ob zagonu v vsebniku samodejno ustvarijo, so: ∙ /dev/console — fizični vmesnik sistemskega upravljalnika (angl. console), ∙ /dev/null — podatki, zapisani na napravo, se zavržejo, branje s te naprave vedno vrne znak za konec datoteke (angl. end of file - EOF), ∙ /dev/zero — branje s te naprave vedno vrača ničelne znake (angl. null character); ena od tipičnih uporab je zagotavljanje znakovnega toka pri inicializaciji podatkovne shrambe, 56 http://man7.org/linux/man-pages/man2/setns.2.html 48 ∙ /dev/full — naprava, ki vedno vrača kodo napake ENOSPC (angl. no space left on device), običajno se uporablja za testiranje obnašanja programov ob polno zasedenem disku, ∙ /dev/tty* — psevdoterminal, ki poveže proces z izvajalnim okoljem, ∙ /dev/urandom — naprava oz. generator neomejenih naključnih števil, ∙ /dev/random — naprava oz. generator blokov naključnih števil, ∙ /dev/fuse — naprava, prek katere dostopamo do datotečnega sistema v uporabniškem prostoru (angl. filesystem in user space). Docker slike se priklopijo na vsebnik na način nodev 57 , kar v praksi pomeni, da tudi če slika vsebuje naprave, ki jih Docker privzeto ne omogoča, v vsebniku te naprave ne bodo vidne. Če želimo popolnoma onemogočiti kreiranje novih naprav v vsebniku, lahko to storimo z odstranitvijo jedrne zmogljivosti MKNOD. O tem več v nadaljevanju. Kontrolne skupine so nepogrešljive na gostiteljih, kjer tečejo vsebniki več najemnikov (angl. multi tenant). Tipičen primer so ponudniki javnih oblakov tipa PaaS (angl. platform as a service), kjer kontrolne skupine zagotavljajo konsistentno delovanje in konsistentne zmogljivosti vsebnikov, tudi če se kateri izmed njih začne vesti nepredvidljivo. Kontrolne skupine so v uporabi že od leta 2006, kasneje se je podpora zanje preselila v Linux jedro, ki jim je z verzijo 2.6.24 prvič omogočilo domorodno podporo (angl. native support). 3.5.3 Linux jedrne zmogljivosti Docker vsebnike privzeto zažene z zelo omejenim naborom jedrnih zmogljivosti (angl. Linux Kernel Capabilities). Z njimi sistemu, ki drugače loči zgolj med polnim (angl. root access) in uporabniškim nivojem (angl. non-root access) sistemskih pravic oz. nivojem dostopa, omogoči veliko bolj granularen sistem kontrole pravic in dostopa. V praksi to pomeni, da npr. spletni strežnik, ki posluša prek omrežnih vrat 80 (ali katerihkoli rezerviranih omrežnih vrat pod 1024), za delovanje ne potrebuje polnega nivoja sistemskih pravic, 57 http://linux.die.net/man/8/mount 49 zadostuje že to, da se mu omogoči jedrna zmogljivost net_bind_service. Po tem vzoru Linux jedro operira še z množico drugih jedrnih zmogljivosti58 , kjer bi sicer potrebovali polni nivo sistemskih pravic. Privzeto ima Docker omogočene naslednje jedrne zmogljivosti: CHOWN, DAC_OVERRIDE, FOWNER, KILL, SETGID, SETUID, SETPCAP, NET_BIND_SERVICE, NET_RAW, SYS_CHROOT, MKNOD, SETFCAP in AUDIT_WRITE. Ostale lahko po potrebi vklopimo oz. izklopimo ob zagonu vsebnika. To storimo z ukazoma: docker run –-cap-drop in docker run –-cap-add. V naslednjem primeru bomo onemogočili jedrno zmogljivost chown in nato v vsebniku poskusili datoteki spremeniti lastništvo: # docker run –-cap-drop chown -t -i centos-test /bin/bash root@f35db49164c8:/# touch /tmp/test root@f35db49164c8:/# chown nobody:nobody /tmp/test chown: changing ownership of ’test’: Operation not permitted Iz zgornjega izpisa je razvidno, da je jedrna zmogljivost onemogočila spremembo lastništva datoteke, čeprav je bil ukaz izveden s polnimi sistemskimi pravicami, torej z najvišjimi sistemskimi pravicami uporabnika root. Poleg že omenjenih privzeto omogočenih jedrnih zmogljivosti lahko ob zagonu vsebnika omogočimo oz. onemogočimo dodatne nivoje dostopa prek naslednjih jedrnih zmogljivosti: ∙ SYS_MODULE — namesti/odstrani jedrni modul, ∙ SYS_RAWIO — spremeni jedrni modul, ∙ SYS_PACCT — konfiguriraj nadzor procesa (angl. accounting), ∙ SYS_NICE — spremeni prioriteto procesa, ∙ SYS_RESOURCE — spremeni omejitve procesa, ∙ SYS_TIME — spremeni sistemsko uro, ∙ SYS_TTY_CONFIG — konfiguriraj naprave tty 59 , ∙ AUDIT_CONTROL — konfiguriraj glasovni podsistem, 58 59 http://manpages.ubuntu.com/manpages/raring/man7/capabilities.7.html http://man7.org/linux/man-pages/man4/tty.4.html 50 ∙ MAC_OVERRIDE — ignoriraj jedrno MAC politiko, ∙ MAC_ADMIN — nastavi MAC konfiguracijo, ∙ SYSLOG — spremeni jedrno funkcijo “printk”, ∙ NET_ADMIN — konfiguriraj omrežne nastavitve, ∙ SYS_ADMIN — spremeni sistemske nastavitve. Vse zgoraj naštete jedrne zmogljivosti so privzeto onemogočene zaradi varnostnih razlogov. Še posebej velja izpostaviti zadnji dve našteti NET_ADMIN in SYS_ADMIN, ki vsebniku omogočita tako visoke sistemske pravice, da lahko postane “nevaren” za gostitelja in morebitne ostale vsebnike, ki tečejo na istem gostitelju. Nevarnost predstavlja zato, ker ima možnost posega v nastavitve gostitelja in posledično nastavitve ostalih vsebnikov na tem gostitelju. Če želimo vsebniku omogočit vse jedrne zmogljivosti razen SYS_ADMIN, lahko to storimo z ukazom: # docker run –-cap-add all –-cap-drop sys_admin -ti centos-test Seveda kaj takega v praksi redko storimo, saj moramo biti pri višanju nivoja sistemskega dostopa skrajno konzervativni, kajti le tako nam bodo jedrne zmogljivosti v pomoč pri zagotavljanju ustreznega nivoja varnosti vsebnikov in gostitelja samega. 3.5.4 Ostale jedrne varnostne funkcionalnosti Poleg jedrnih zmogljivosti poznamo tudi druge jedrne varnostne metode, kot npr.: SELinux60 , AppArmor61 , TOMOYO62 , GRSEC63 . Docker v osnovi domorodno podpira zgolj jedrne zmogljivosti, vendar uporaba omenjenih dodatnih metod ne ruši privzetega koncepta, saj se le-te nanašajo na celoten sistem gostitelja, povsem neodvisno od uporabe vsebnikov. Prav tako lahko v vsebniku neodvisno od gostitelja namestimo npr. AppArmor oz. SELinux in s tem še dodatno povečamo stopnjo varnosti. Nekatere Linux distribucije 60 http://selinuxproject.org http://wiki.apparmor.net 62 http://tomoyo.sourceforge.jp 63 https://grsecurity.net 61 51 privzeto že vsebujejo varnostne predloge za omenjeni metodi, npr. distribucija Ubuntu64 ima privzeto nameščene varnostne predloge AppArmor za LXC-vsebnike. Uporaba dodatnih jedrnih varnostnih metod je v produkcijskem okolju vsekakor zaželena, saj ne posega v delovanje vsebnikov, zagotavlja pa dodatno plast zaščite, s katero še nekoliko povečamo stopnjo varnosti. 3.5.5 Zaščita procesa Docker pred zlonamernimi napadi Če želimo na gostitelju poganjati Docker vsebnike, moramo predhodno namestiti in zagnati Docker prikriti proces (angl. daemon). Ta na gostitelju teče z vsemi sistemskimi pravicami, zato moramo biti pri tem pozorni na naslednje pomembne podrobnosti. Z Docker prikritim procesom naj upravljajo zgolj sistemski administratorji, ki imajo isti nivo dostopa. Docker in tudi druge virtualizacijske metode namreč omogočajo, da si vsebniki in gostitelj med seboj delijo datoteke in mape. Če vsebniku omogočimo dostop do mape na gostitelju, ima vsebnik do njene vsebine polne pravice. Torej pravice za branje, pisanje, brisanje in izvajanje. Če je ta mapa, ki si jo delita vsebnik in gostitelj, kar korenska mapa (angl. root folder /) gostitelja, lahko iz vsebnika dostopamo in spreminjamo vse datoteke na datotečnem sistemu gostitelja. Če uporabnikom vsebnikov omogočimo upravljanje le-teh prek spleta (posredno prek Docker API), moramo dostop do te spletne strani omogočiti zgolj prek varne kriptirane povezave SSL/HTTPS65 . Zagotoviti moramo sintaktično preverjanje vseh vnosov v spletnih formah, da s tem preprečimo vrivanje zlonamerne kode (angl. cross site scripting - XSS) in morebiten prevzem nadzora nad gostiteljem ter posledično vsebniki. Seveda lahko uporabnikom omogočimo tudi neposreden dostop do Docker API, pri čemer moramo biti še bolj previdni, npr. omogočimo dostop zgolj iz varnih omrežij ali VPN-a66 . To poglavje lahko zaključimo z ugotovitvijo, da je vsebnikom možno zagotoviti visoko stopnjo varnosti. Ta pa žal ne pride sama od sebe, temveč je zanjo treba poskrbeti. Najbolje je to storiti večplastno, tako kot smo to predstavili v tem poglavju. Še vedno nekako 64 http://www.ubuntu.com/server https://tools.ietf.org/html/rfc2818 66 https://tools.ietf.org/html/rfc4026 65 52 velja prepričanje, da je klasična virtualizacija s hipervizorjem bolj varna od vsebnikov. Vendar, kot rečeno, lahko z upoštevanjem dobrih praks dosežemo praktično enako stopnjo varnosti pri obeh metodah virtualizacije. 3.6 Primerjava z ostalimi metodami virtualizacije Tradicionalne virtualizacijske metode, kot npr. Xen, KVM in VMware v javnosti še vedno veljajo za varnejše kot virtualizacija na nivoju operacijskega sistema, predvsem zato, ker zagotavljajo dodaten nivo izolacije med virtualnim okoljem in gostiteljem. Vsebnik namreč lahko izvede sistemske klice neposredno v jedru gostitelja, medtem ko pri tradicionalni virtualizaciji taki klici niso mogoči. Virtualni računalnik lahko v takem primeru izvede zgolj hiperklice, ki se izvedejo v hipervizorju. Na ta način je dosežena omenjena dodatna stopnja izolacije. V resnici pa so visoko stopnjo varnosti dosegli predvsem z zrelostjo tehnologije, saj se v produkciji uporablja že dolgo časa. Posledično so se skozi čas in uporabo odkrile ter odpravile varnostne pomanjkljivosti. Vsebniki so na drugi strani mlada tehnologija, ki se bo glede na trende še imela možnost razvijati. Glede na karakteristike vsebnikov, ki so v primerjavi s tradicionalnimi virtualnimi računalniki bistveno manj potratni z viri in veliko bolj agilni, gre pričakovati, da bo razvoj zelo hiter. Zagovorniki tradicionalnih metod virtualizacije namigujejo, da bi lahko ranljivost v Linux jedru omogočila napad na gostitelja iz vsebnika. Vendar je zgodba pri tradicionalni virtualizaciji podobna, saj bi ranljivost hipervizorja imela enake posledice. Še posebej, če imamo v mislih, da je hipervizorjeva koda zelo kompleksna in kot taka podvržena večji možnosti za napake. Celo več, kritični popravki Linux jedra so običajno na voljo v zelo kratkem času, medtem ko to za varnostne popravke hipervizorja ne velja vedno. Poleg tega je razlika tudi v samem postopku odpravljanja varnostne pomanjkljivosti. Pri gostitelju z vsebniki je namreč dovolj nadgraditi Linux jedro gostitelja in s tem se odpravi ranljivost tudi v vsebnikih. Pri tradicionalni virtualizaciji moramo ločeno nadgrajevati hipervizor in operacijske sisteme v virtualnih računalnikih. Gostitelj z vsebniki celo omogoča (z vidika vsebnika) transparenten prehod med različnimi jedrnimi varnostnimi mehanizmi in njihovo prekrivanje, ne da bi morali posegati v slike ali vsebnike. S sofisticiranimi orodji67 , 67 https://www.ksplice.com 53 ki omogočijo nadgradnjo Linux jedra brez ponovnega zagona sistema in živo migracijo vsebnikov68 (angl. live migration), dosežemo nemoteno delovanje tudi pri nameščanju kritičnih popravkov. To pa so že lastnosti, ki lahko zelo kmalu prevesijo tehtnico v prid vsebnikov tudi pri zagotavljanju visokega nivoja varnosti. Seveda pa je treba narediti primerjavo tudi med implementacijami virtualizacije na nivoju operacijskega sistema. Razdelimo jih lahko na tri osnovne kategorije: ∙ vsebniki, ki temeljijo na tehnologiji LXC, ∙ vsebniki, ki ne temeljijo na tehnologiji LXC, ∙ vsebniki, ki ne temeljijo na operacijskem sistemu Linux. Vsebniki, ki temeljijo na tehnologiji LXC, torej tudi Docker, lahko na nivoju sistema ponudijo enak nivo varnosti, saj imajo na voljo isti nabor mehanizmov. Če bi ena izmed implementacij ponudila kako novo rešitev, bi to pomenilo, da jo je moč uporabiti v katerikoli LXC-implementaciji. Vsebniki, ki ne temeljijo na tehnologiji LXC (npr. OpenVZ69 ), so z vidika varnosti precej zanesljivi, saj se v produkciji uporabljajo že dolgo. Toda veliko njihovih razvijalcev sodeluje tudi pri razvoju tehnologije LXC, ki je grobo rečeno modernejša različica OpenVZ. Vendar ima tehnologija LXC pomembno prednost, saj je domorodno podprta v Linux jedru, kar za OpenVZ ne velja. Lahko pričakujemo, da bo v prihodnosti tehnologija LXC popolnoma nadomestila OpenVZ. Vsebniki, ki ne temeljijo na operacijskem sistemu Linux, so tudi zelo napredni in zanesljivi (npr. BSD Jails, Solaris Zones), vendar v njih ne moremo učinkovito in zanesljivo poganjati Linux procesov. Če nam v take vsebnike ni treba nameščati procesov, temveč glede na operacijski sistem neodvisne vsebine, lahko to brez težav počnemo tudi s to vrsto vsebnikov. Vsekakor tako početje predstavlja neke vrste “eksotiko”, saj ima uporaba vsebnikov na osnovi operacijskega sistema Linux neprimerno večji razvojni zagon in še večjo uporabniško skupnost. V zaključku tega poglavja moramo omeniti tudi dejstvo, da je Docker z zadnjimi različicami prek sistema vtičnikov poleg tehnologije LXC omogočil uporabo tudi drugih sorodnih 68 69 http://criu.org http://openvz.org 54 tehnologij (libcontainer70 , libvirt71 , systemd-nspawn72 ). Ta funkcionalnost je še v zgodnji fazi razvoja, zato še ne bo kmalu zrela za produkcijsko okolje. 4. ANALIZA V prvem delu tega poglavja bomo na podlagi dveh izbranih scenarijev prikazali praktične primere uporabe vsebnikov. Hkrati smo skladno z raziskovalnimi vprašanji in cilji magistrske naloge opredelili metodologijo, na podlagi katere smo prišli do odgovorov na zastavljena vprašanja in do spoznanj, ki nam omogočajo opredelitev do v uvodu postavljene teze. V ta namen smo izdelali odločitveni model oz. nivojsko odločitveno drevo. Definirali smo kriterije (atribute) in njihove zaloge vrednosti, na podlagi katerih smo presojali. Vsakemu od vodilnih atributov smo določili tudi funkcijo koristnosti. Rezultate smo strnili v analizi SWOT73 in predstavili s polarnimi grafi. Uvod v primere scenarijev bomo pričeli z generičnim performančnim testom (angl. benchmark), kjer bomo na gostitelju, v testnem vsebniku in KVM74 zagnali skripto za izračun števila 𝜋 na 100, 1.000 in 10.000 decimalnih mest natančno. Skripta deluje tako, da izračuna arkustangens števila 1, kar je enako 41 𝜋, zato vse skupaj pomnožimo s številom 4 in tako dobimo končni rezultat 𝜋. Pred tem seveda določimo, na koliko mest natančno ga želimo izračunati. Skripta z imenom pi.sh, ki bo izvedla izračun na gostitelju, v vsebnikih in KVM, je sestavljena iz: #!/bin/bash { time echo “scale=$1; 4*a(1)” | bc -l ; } 2 >> ./result-$RANDOM.txt Pri tem spremenljivka scale predstavlja natančnost izračuna oz. število decimalnih mest 70 https://github.com/docker/libcontainer http://libvirt.org 72 http://0pointer.de/public/systemd-man/systemd-nspawn.html 73 http://ctb.ku.edu/en/table-of-contents/assessment/assessing-community-needs-and-resources/swot71 analysis/main 74 V KVM-okolju, kot referenčno točko za primerjavo s polno virtualizacijo. 55 rezultata (podamo jo kot argument pri zagonu skripte pi.sh, npr. pi.sh 100), oznaka 𝑎() pa funkcijo arkustangens. Definirano funkcijo posredujemo v izračun programu bc75 . Čas izvajanja izračuna merimo z orodjem time, ki se izvede hkrati z ukazom za izračun. Rezultat vsake posamične meritve zapišemo v ločene datoteke z generičnim imenom result-<naključniniz>.txt. Te nam po zaključku izračuna predstavljajo podatkovno množico (angl. dataset), nad katero izvedemo analizo. Vendar to zadošča le za izvedbo testa, ki opravi zgolj en sam izračun hkrati. Če želimo povečati število hkratnih izračunov, moramo uporabiti paralelizacijo (Pas, 2010). Pri tem si pomagamo z orodjem GNU Parallels (Tange, 2011), ki omogoči 𝑛 vzporednih zagonov skripte. Ukaz, s katerim npr. zaženemo izračun števila 𝜋 v stotih vsebnikih na tisoč decimalnih mest natančno, je sestavljen iz: # docker ps -q | head -100 | parallel –-max-procs=100 docker \ exec -dti {1} ./pi.sh 1000 V prvem delu ukaza z docker ps -q generiramo seznam ID-jev zagnanih vsebnikov, nato s seznama z ukazom head -100 izberemo prvih sto ID-jev zagnanih vsebnikov. Seznam kot argument posredujemo orodju parallel, ki na podlagi le tega izbranim stotim vsebnikom sočasno, z ukazom docker exec -dti <IDvsebnika>, posreduje ukaz za izvedbo skripte pi.sh. Za izvedbo identičnega testa oz. meritve na gostitelju ukaz ustrezno prilagodimo: # seq 100 | parallel –max-procs=100 -n0 ./pi.sh $2 & Uporabimo orodje seq , s katerim generiramo niz števil od 1 do 100, za vsako število v nizu z orodjem parallel ustvarimo paralelen klic skripte pi.sh, ki se izvede v ozadju. V nadaljevanju bomo predstavili izračune, ki smo jih izvedli kot običajen proces na gostitelju, kot proces v vsebniku in kot proces v KVM, ter dobljene rezultate primerjali. Na podlagi tega smo določili časovno izvedbeno osnovo (angl. baseline). Nato smo testiranje razširili. Na gostitelju in KVM smo pognali 10, 100 in 1.000 vzporednih izračunov, nato isto ponovili z vsebniki, pri čemer je vsak vzporeden izračun tekel v svojem namenskem vsebniku. Vse to smo ponovili trikrat, za vsako že prej definirano natančnost rezultata, 75 http://www.gnu.org/software/bc/ 56 torej 100, 1.000 in 10.000 decimalnih mest natančno. Skozi primerjavo rezultatov smo ugotovili, za koliko se poveča skupna poraba (angl. overhead), ko procese poganjamo iz vsebnikov. Tabela 4.1 prikazuje rezultate, ki smo jih dobili s performančnimi testi na gostitelju. Časovna izvedbena osnova v tem primeru znaša 0,003 sekunde. Ugotovimo lahko, da pri majhni kompleksnosti (v našem primeru majhnem številu decimalnih mest) večanje števila hkratnih izračunov teh ne upočasni bistveno. V našem primeru so nekateri rezultati celo identični. Z večanjem kompleksnosti se čas izračuna bistveno poveča. Opazimo, da se to zgodi takrat, ko je kompleksnost izračuna velika in hkrati število vzporednih izračunov preseže število procesorskih jeder oz. niti (angl. threads), ki so na voljo. Tabela 4.1: Časi izračunov števila 𝜋, ki smo jih dosegli na gostitelju št. procesov / št. dec. mest 100 1000 10000 1 proces 0,003s 0,394s 2m19,085s 10 procesov 0,003s 0,397s 2m19,240s 100 procesov 0,003s 2,329s 14m18,685s 1000 procesov 0,003s 20,938s 2h22m5,203s Vir: Mihičinac, lastna raziskava (2014) Tabela 4.2 prikazuje rezultate, ki smo jih dobili s performančnimi testi v vsebnikih. Časovna izvedbena osnova tudi v tem primeru znaša 0,003 sekunde. Ugotovimo lahko, da so rezultati zelo podobni tistim, ki smo jih dobili s performančnimi testi na gostitelju. S tem smo potrdili teoretsko izhodišče (Felter in drugi, 2014), da je povečanje skupne porabe pri rabi vsebnikov zanemarljivo majhna. Tabela 4.3 prikazuje rezultate, ki smo jih dobili s performančnimi testi v virtualnem računalniku, ki teče na polni virtualizaciji KVM. Časovna izvedbena osnova tudi v tem primeru znaša 0,003 sekunde. Ugotovimo lahko, da so rezultati podobni tistim, ki smo jih dobili s performančnimi testi na gostitelju in vsebnikih, vendar pri manj kompleksnih izračunih. Takoj ko kompleksnost izračuna naraste, je tudi razlika v času, potrebnem za posamezen izračun, bistveno večja, kar je posledica povečane skupne porabe na račun hipervizorja (Li in drugi, 2013). 57 Tabela 4.2: Časi izračunov števila 𝜋, ki smo jih dosegli v vsebnikih št. vsebnikov / št. dec. mest 100 1000 10000 1 vsebnik 0,003s 0,396s 2m9,114s 10 vsebnikov 0,003s 0,404s 2m19,333s 100 vsebnikov 0,003s 2,431s 14m18,911 1000 vsebnikov 0,003s 21,003s 2h22m5,653s Vir: Mihičinac, lastna raziskava (2014) Tabela 4.3: Časi izračunov števila 𝜋, ki smo jih dosegli v KVM št. procesov / št. dec. mest 100 1000 10000 1 proces 0,003s 0,506s 2m57,800s 10 procesov 0,003s 0,525s 2m58,580s 100 procesov 0,003s 3,124s 19m51,073s 1000 procesov 0,003s 28,896s 3h48m25,409s Vir: Mihičinac, lastna raziskava (2014) V naslednjem koraku smo izračune razvrstili po skupinah glede na število računskih enot, torej število procesov ali število vsebnikov. Nato smo primerjali razlike v času izračuna tako znotraj posamezne skupine kot med skupinami. Slika 4.1 je vizualizacija rezultatov, ki smo jih predstavili v Tabela 4.1 in Tabela 4.2. Nato smo podobno kot v prejšnjem koraku primerjali razlike v času izračuna tako znotraj posamezne skupine kot med skupinami. Tokrat smo primerjali razlike med časi, ki smo jih dosegli v vsebnikih in časi, ki smo jih dosegli v polni virtualizaciji KVM. Slika 4.2 je vizualizacija rezultatov, ki smo jih predstavili v Tabela 4.2 in Tabela 4.3. Tu lahko opazimo že bistveno večja odstopanja, kadar imamo opravka s kompleksnimi operacijami. Pri najkompleksnejšem izračunu našega testa razlika znaša več kot eno uro in dvajset minut v prid vsebnika, kar predstavlja več kot šestdesetodstotno razliko med doseženima časoma izračunov. Če bi bil naš testni izračun bolj I/O intenziven, bi se razlika še dodatno povečala, in sicer na račun translacije sistemskih klicev v hiperklice. Slika 4.1 tako še bolj razvidno prikaže, s kako majhnimi razlikami imamo opravka, ko 58 0.45 Slika 4.1: Razlike v času, potrebnem za izračun (med gostiteljem in vsebniki) 0.3 0.2 Razlika v čau [𝑠] 1000 0.16 2 · 10−3 7 · 10−3 0.1 6.5 · 10−2 100 2.9 · 10−2 0 0 0 0 0.23 0.4 0.1 10000 0 Število decimalnih mest 𝜋 1 samostojen 10 hkratnih 100 hkratnih 1000 hkratnih Vir: Mihičinac, lastni prikaz (2014) primerjamo performančne zmogljivosti gostitelja in vsebnika. Absolutno največja razlika namreč znaša manj kot pol sekunde (0,45 s), ostale razlike so še bistveno manjše. Tega ne moremo trditi pri primerjavi vsebnikov in KVM polne virtualizacije, saj so razlike pri kompleksnih operacijah zelo velike. Kot zanimivost lahko omenimo, da je bil pri najkompleksnejših izračunih strežnik maksimalno obremenjen, kar kaže tudi velikost parametra load 76 , ki ga izpiše ukaz uptime (Walker, 2006): up 1 day, 7:32, 5 users, load average: 1000.12, 999.41, 924.29 Iz zgornjega izpisa lahko razberemo, da je v povprečju zadnjih 15 minut na vire centralne procesne enote čakalo približno tisoč procesov, kar se povsem ujema z našim testnim modelom. Ravno naš najkompleksnejši test je namreč izvajal tisoč hkratnih izračunov števila 𝜋 na deset tisoč decimalnih mest natančno. Rezultate lastnih testiranj oz. meritev smo primerjali z raziskavo, ki jo je opravila korporacija IBM (Felter in drugi, 2014). Naše ugotovitve namreč želimo podkrepiti z dvema 76 http://man7.org/linux/man-pages/man5/proc.5.html 59 50 40 30 7.89 20 10 0.11 0.12 0.69 0 0 0 0 100 1000 Razlika v čau [𝑠] 38.69 39.18 322.17 5,179.76 Slika 4.2: Razlike v času, potrebnem za izračun (med KVM in vsebniki) 10000 0 Število decimalnih mest 𝜋 1 samostojen 10 hkratnih 100 hkratnih 1000 hkratnih Vir: Mihičinac, lastni prikaz (2014) izmed njihovih meritev: ∙ “CPU-Linpack77 ” — izračun kompleksnih matematičnih operacij linearne algebre, ∙ I/O78 pretok (angl. throughput) — testira zmogljivosti sekvenčnega (angl. sequential) in naključnega (angl. random) I/O pretoka. Slika 4.3 predstavlja prvo meritev, kjer je razvidno, da tudi v tem primeru praktično ni performančne razlike med gostiteljem in vsebnikom. Oba sta namreč dosegla identičen rezultat GFLOPS79 (angl. floating-point operations per second; ena milijarda FLOPSov je ekvivalentna enemu GFLOPS-u). Bistveno slabše se je odrezal predstavnik polne virtualizacije KVM, ki je dosegel več kot polovico slabši rezultat. To je predvsem posledica abstrakcije strojne opreme v obliki hipervizorja, za katerega Linpack ne more natančno 77 http://www.netlib.org/linpack/ Vhodno-izhodne naprave (angl. input/output) 79 Enota za število izvršenih operacij s plavajočo vejico v sekundi, s katero se opredeli hitrost izračuna 78 ali hitrost procesorja. 60 ugotoviti, kateri nabor strojnih instrukcij je podprt v fizičnem procesorju oz. katere zgolj posnema (angl. emulate). Zaradi tega Linpack uporablja bolj splošne algoritme, ki seveda niso tako hitri, kot bi lahko bili, če bi jih prilagodili tipu strojne opreme oz. procesorja, na katerem se izvaja. Slika 4.3: CPU Linpack 250 200 150 100 Linpack GFLOPS 300 50 gostitelj vsebnik KVM 0 Vir: prirejeno po Felter in drugi (2014) Druga meritev se nanaša na zmogljivosti I/O pretoka in je sestavljena iz dveh testov. Prvi prikazuje dosežene hitrosti pretoka (v megabajtih na sekundo - MB/s) pri sekvenčnem dostopu do podatkov, tako za sekvenčno branje kot sekvenčno pisanje podatkov. Slika 4.4 prikazuje, da pri sekvenčnem branju podatkov ni velikih razlik med doseženimi rezultati na gostitelju, vsebniku in KVM. Tudi pri sekvenčnem pisanju podatkov razlike niso velike, vendar že opazne. Pri tej meritvi se v časovnem oknu šestdesetih sekund meri povprečna dosežena hitrost (pri velikosti I/O en megabajt). Meritev zmogljivosti I/O pretoka naključnega dostopa (Slika 4.5) je pokazala že bistveno večjo performančno razliko. Rezultata meritev na gostitelju in v vsebniku sta pričakovano poravnana, KVM pa dosega zgolj okoli petdeset odstotkov njunih zmogljivosti - IOPSov80 . Pri tej meritvi se izvede 128 hkratnih operacij, ki pri branju oz. pisanju uporabljajo blok velikosti 4 kilobajte (angl. kilobyte - kB). Kot rečeno, pri uporabi vsebnika ni prišlo do povečanja skupne porabe, medtem ko je pri KVM zaradi izvajanja operacij 80 http://www.symantec.com/connect/articles/getting-hang-iops-v13 61 Slika 4.4: I/O pretok - sekvenčen dostop 600 400 MB/s 800 200 pisanje branje 0 sekvenčen način gostitelj vsebnik KVM Vir: prirejeno po Felter in drugi (2014) prek hipervizorja (QEMU81 ) skupna poraba bistveno večja. Na splošno so performanse omenjenega KVM virtualiziranega računalnika sicer še vedno v mejah normale. Vendar rezultati meritve povedo, da bo tak virtualiziran računalnik porabil več procesorskih ciklov (angl. CPU cycle) za vsako I/O operacijo, kar posledično pomeni, da jih za aplikacije ostane toliko manj. Uvodno analizo performančnih meritev in dobljenih rezultatov lahko zaključimo z naslednjimi ugotovitvami. Procesi se v vsebniku izvajajo praktično enako hitro kot neposredno na gostitelju. Pri tem se skupna poraba ne poveča opazneje. Ko vsebnike primerjamo s polno virtualizacijo, pa že opazimo relevantne razlike v performansah. Vse meritve se v vseh scenarijih izvedejo enako hitro, dokler izvajamo enostavne operacije in število vzporednih operacij ne preseže števila jeder centralne procesne enote. Prvi mejnik nastopi, ko vzporedno izvajamo večje število kompleksnih operacij, kot je razpoložljivih jeder. Naslednji mejnik nastopi, ko enostavne operacije nadomestimo s kompleksnimi. Seveda največje razlike v meritvah dobimo, ko v enem scenariju združimo pogoje obeh mejnikov, torej sočasno izvedemo veliko število vzporednih kompleksnih operacij. V tem scenariju se polna virtualizacija izkaže veliko slabše, rezultati meritev na gostitelju in v 81 http://wiki.qemu.org 62 Slika 4.5: I/O pretok - naključen dostop 120,000 100,000 60,000 IOPS 80,000 40,000 20,000 pisanje branje branje in pisanje 0 naključni način gostitelj vsebnik KVM Vir: prirejeno po Felter in drugi (2014) vsebniku so skoraj identični. V naslednjih poglavjih smo fokus usmerili na testiranje realnih scenarijev uporabe dveh tipičnih storitev, ki smo ju virtualizirali z uporabo vsebnikov. S tem smo poleg že izmerjenih dobrih performans preizkusili še uporabniško izkušnjo z vidika sistemskega administratorja in razvijalca. Z vidika končnega uporabnika bo ta sprememba transparentna, zato je ne bomo posebej obravnavali. Preden smo se posvetili omenjenim testom, smo definirali še metodologijo analize obeh scenarijev. 4.1 Metodologija analize scenarijev V sklopu analize realnih scenarijev smo najprej pripravili ustrezno okolje. Za vsak scenarij posebej smo izdelali prikrojeno namensko datoteko Dockerfile, iz nje ustvarili sliko in jo nato zagnali v vsebniku. Z različnimi orodji smo izvedli meritve in testiranja ter s tem pridobili nekatere primarne podatke, ki smo jih kasneje kot kriterije uporabili pri izdelavi odločitvenega modela. Med analizo smo torej spremljali naslednje parametre: ∙ kompleksnost — stopnja kompleksnosti vzpostavitve delovanja storitve v vsebniku, 63 ∙ agilnost — stopnja neodvisnosti vsebnika od infrastrukture, ∙ varnost — stopnja varnosti, ki jo lahko zagotovimo v vsebniku, ∙ generalnost — stopnja prenosljivosti rešitve na druge scenarije, ∙ zanesljivost — stopnja zanesljivosti delovanja vsebnika. Nato smo ugotovitve povzeli v analizi SWOT, kjer smo definirali prednosti, slabosti, priložnosti in nevarnosti uporabe vsebnikov v produkciji. V končni interpretaciji rezultatov lastne raziskave smo predstavili ugotovitve in spoznanja, do katerih smo prišli prek uvodnega kritičnega pregleda literature oz. tehnologij ter izvedenih praktičnih primerov. 4.2 Preizkus vsebnika LXC v vlogi storitve Za preizkus scenarija vsebnika LXC kot storitve smo izbrali brezplačno odprtokodno82 programsko rešitev Redis83 . Ta služi kot napredna “key-value” (ključ-vrednost) shramba podatkovnih struktur, kot npr.: nizov (angl. string), zgoščenih vrednosti (angl. hash), polj84 (angl. list), seznamov85 (angl. sets), urejenih seznamov (angl. sorted sets), bitnih map86 (angl. bitmaps) in tako imenovanih “hyperloglogs - HLL” 87 . Podatkovno shrambo v celoti hrani v pomnilniku, zato iz nje zelo hitro vrača želene podatke. Med svetovno znane uporabnike programske rešitve Redis sodijo: Twitter, Github, Weibo, Pinterest, Snapchat, Flickr, StackOverflow idr. Običajen scenarij uporabe je hranjenje serializiranih88 podatkov sej (angl. session data) tretjih storitev. Nad shranjenimi podatki omogoča atomarne operacije89 , kot npr.: pripenjanje vrednosti nizom (angl. appending), povečevanje vrednosti (angl. increment), 82 Izdan pod licenco BSD - https://www.gnu.org/licenses/license-list.html#ModifiedBSD http://redis.io 84 http://redis.io/topics/data-types-intro#lists 85 http://redis.io/topics/data-types-intro#sets 86 http://redis.io/topics/data-types-intro#bitmaps 87 http://redis.io/topics/data-types-intro#hyperloglogs 88 Serializacija na nivoju programskega jezika je proces pretvorbe objekta v niz bitov, ki je primeren za 83 zapis v podatkovno shrambo ali prenos prek komunikacijskega kanala. 89 Atomarna operacija je tista, ki jo sistem zazna, kot da se izvede v trenutku; kot taka je osnova za sočasno procesiranje podatkov. 64 uvrščanje elementov v polja (angl. push), izračun preseka seznamov (angl. set intersection), izračun unije in razlike ali izpis največjega oz. najmanjšega člena v urejenem seznamu. Poleg tega ima podporo za napredne funkcionalnosti kot so transakcije (angl. transactions), t. i. paradigmo “Publish-Subscribe”, podporo skriptnemu jeziku LUA, podporo nastavitvi življenjske dobe paru ključ-vrednost (angl. time to live - TTL), podporo samodejnemu čiščenju podatkovne shrambe in možnost vzpostavitve nadomestnega načina delovanja (angl. failover setup) (Sanfilippo, 2014). Redis smo za ta scenarij izbrali zato, ker je v osnovi podporna storitev in kot taka idealna za preizkus virtualizacije v vsebniku. Virtualizirana v vsebniku bo predstavljala infrastrukturno neodvisno oz. samozadostno podporno storitev, kar predstavlja prvi korak k infrastrukturno neodvisni storitvi kot celoti oz. storitvi, ki temelji na nespremenljivi infrastrukturi (angl. immutable infrastructure). Če se bo scenarij z nameščenim Redisom izkazal, bi ga v prihodnosti želeli uporabiti v produkcijskem okolju že obstoječe storitve. Uporabili bi ga v navezi s programsko rešitvijo ApacheSpamAssasin90 in amavisd91 v sklopu sistema elektronske pošte. Redis v sistemu shranjuje Spamassasinove podatke za samoprepoznavo neželene (angl. spam) pošte, amavis pa vanj shranjuje podatke, katera e-poštna sporočila so že bila obdelana s strani e-poštnih strežnikov. Sama postavitev presega okvir te magistrske naloge, vendar predstavlja motiv, s katerim utemeljujemo koristnost izvedbe tega scenarija. 4.2.1 Izdelava vsebnika za programsko rešitev Redis Splošen postopek izdelave vsebnika smo predstavili že v predhodnih poglavjih, zato smo v nadaljevanju izpostavili zgolj pomembnejše korake in izpustili razlago s tem povezanih rutinskih opravil. Za izdelavo slike Redis smo pripravili naslednjo datoteko Dockerfile: 90 91 http://spamassassin.apache.org http://www.amavis.org 65 FROM dockerfile/ubuntu RUN apt-get update RUN cd /tmp && wget http://download.redis.io/redis.tar.gz && \ tar xvzf redis-stable.tar.gz && cd redis-stable && \ make && make install && ... CMD ["redis-server", "/etc/redis/redis.conf"] EXPOSE 6379 Sestavljajo jo trije glavni sklopi. V začetnem sklopu definiramo, na kateri uradni distribuciji bazira slika (v našem primeru je to Ubuntu), ki jo v fazi izdelave naše slike posodobimo. V naslednjem sklopu s spleta prenesemo in namestimo programsko rešitev Redis. V zadnjem sklopu definiramo privzeti ukaz ob zagonu vsebnika ter omogočimo dostop do omrežnih vrat vsebnika, na katerih bo poslušal Redis. Nato z ukazom docker build izdelamo sliko, ki jo zaženemo v vsebniku. # docker build -t redis . Sending build context to Docker daemon 3.584 kB Sending build context to Docker daemon Step 0 : FROM dockerfile/ubuntu Step 1 : RUN apt-get update Step 2 : RUN cd /tmp && wget http://download.redis.io/redis... Step 3 : RUN cd /opt && mkdir redis Step 4 : CMD redis-server /etc/redis/redis.conf Step 5 : EXPOSE 6379 Successfully built c713a927c32d Nadaljevali smo z izdelavo vsebnika na podlagi slike, ki smo jo ravnokar pripravili. To smo storili z ukazom docker create: # docker create -ti redis d90d211ad44ecca7f0bfd65b5215cff98d96c97b8811eea37d577a781fa62074 Vsebnik je bil s tem pripravljen na zagon. Zagnali smo ga z ukazom docker start in 66 nato še z ukazom docker ps preverili, ali teče: # docker start d90d211ad44e # docker ps CONTAINER ID d90d211ad44e IMAGE STATUS redis:latest Up 4 minutes PORTS 6379/tcp Iz zgornjega izpisa je razvidno, da se je vsebnik uspešno zagnal. Z njim seveda tudi Redis, ki je bil prek omrežnih vrat 6379 na voljo za poizvedbe. Odzivnost smo preizkusili z naslednjim ukazom: # docker exec d90d211ad44e redis-cli ping PONG Z ukazom docker exec smo z gostitelja injicirali ukaz redis-cli ping v vsebnik, na podlagi katerega nam je Redis odgovoril z nizom PONG. Prek ukazne vrstice smo poskusili izvršiti tudi vpis in poizvedbo: # docker exec d90d211ad44e redis-cli set datum 20141108 OK # docker exec d90d211ad44e redis-cli get datum 20141108 Postopek virtualizacije Redisa v vsebnik je s tem zaključen. V naslednjem koraku smo nabor testov še razširili, pri čemer smo spremljali parametre oz. prihodnje kriterije, ki smo jih predstavili v uvodu tega poglavja. 4.2.2 Uporaba programske rešitve Redis v vsebniku Uporabo programske rešitve Redis v vsebniku smo preverili s testiranjem oddaljenega dostopa in za ta namen v programskem jeziku Python92 napisali preprosto skripto. Z njo smo preverjali povezljivost oz. simulirali dostop hipotetične storitve do Redisa, pri čemer se storitev in Redis ne nahajata na istem strežniku. Nato smo izvedli primerjalni 92 https://www.python.org/about/ 67 performančni test, kjer smo primerjali zmogljivosti Redis na gostitelju in v vsebniku. Test smo izvedli z orodjem redis-benchmark, ki je del distribucije Redis. V zadnjem sklopu uporabe programske rešitve Redis v vsebniku smo preverili agilnost uporabljenega vsebnika, torej možnost prenosa obstoječega vsebnika oz. storitve z enega gostitelja na drugega. Test povezljivosti vsebnika Redis, smo izvedli s preprosto skripto Python. Pred tem smo morali na strežniku, kjer želimo pognati skripto Python, namestiti modul python-redis. To smo storili z ukazom: # yum install python-redis -y Našo skripto Python smo poimenovali r.py. Sestavljena je iz: #!/usr/bin/env python # -*- coding: utf-8 -*- import sys import redis if len(sys.argv) < 3: ....sys.stderr.write(’Uporaba: ’ + sys.argv[0] + ’ CMD <ključ> <vrednost>\n’) ....sys.exit(1) rs = redis.Redis(’172.17.0.19’) if ’set’ in sys.argv: ....rs.set(sys.argv[2], sys.argv[3]) ....print(’Vrednost ’ + sys.argv[3] + ’ shranjena.’) if ’get’ in sys.argv: ....print(’Ključu ’ + sys.argv[2] + ’ pripada vrednost: ’ + rs.get(sys.argv[2])) Najprej smo uvozili (angl. import) knjižnici sys in redis, ki ju potrebujemo za realizacijo želene funkcionalnosti. Nato smo definirali naslov IP, kjer je dosegljiv vsebnik z nameščenim Redisom, uporabo in zajem argumentov skripte ter dve stikali: set in get. S prvim stikalom vrednost shranimo v Redis, z drugim pa jo iz njega pridobimo. Primer: 68 # ./r.py set datum 20141108 Vrednost 20141108 shranjena. # ./r.py get datum 20141108 Ključu datum pripada vrednost: 20141108 Performančne meritve smo v Redisu izvedli z orodjem redis-becnhmark. Uporabili smo zastavico -q, ki izpis omeji le na končne rezultate, in zastavico -n, s katero navedemo skupno število zahtevkov (sočasno se lahko izvaja 50 zahtevkov). Meritev smo izvedli na gostitelju in v vsebniku, rezultati na gostitelju so bili naslednji: # redis-benchmark -q -n 100000 PING_INLINE: 95785.44 requests per second PING_BULK: 96711.80 requests per second SET: 97087.38 requests per second GET: 96711.80 requests per second INCR: 98522.17 requests per second LPUSH: 98039.22 requests per second LPOP: 97943.19 requests per second SADD: 97370.98 requests per second SPOP: 97276.27 requests per second LPUSH (needed to benchmark LRANGE): 98328.42 requests per second LRANGE_100 (first 100 elements): 42265.43 requests per second LRANGE_300 (first 300 elements): 19770.66 requests per second LRANGE_500 (first 450 elements): 14152.28 requests per second LRANGE_600 (first 600 elements): 11090.16 requests per second MSET (10 keys): 78247.26 requests per second 69 V vsebniku smo enako meritev izvedli z ukazom: # docker exec d90d211ad44e redis-benchmark -q -n 100000 PING_INLINE: 102986.61 requests per second PING_BULK: 102040.81 requests per second SET: 102774.92 requests per second GET: 103519.66 requests per second INCR: 105485.23 requests per second LPUSH: 105263.16 requests per second LPOP: 104275.29 requests per second SADD: 104384.13 requests per second SPOP: 103950.10 requests per second LPUSH (needed to benchmark LRANGE): 104931.80 requests per second LRANGE_100 (first 100 elements): 49212.60 requests per second LRANGE_300 (first 300 elements): 20379.05 requests per second LRANGE_500 (first 450 elements): 14617.75 requests per second LRANGE_600 (first 600 elements): 11511.45 requests per second MSET (10 keys): 85689.80 requests per second Iz primerjave obeh meritev je razvidno, da je vsebnik izvedel večje število zahtevkov kot gostitelj. Brez poznavanja ozadja bi lahko rekli, da gre za paradoks, saj se je v virtualiziranem okolju izvedlo večje število zahtevkov, kot na gostitelju samem. Vendar ima pojav racionalno razlago. Gostiteljev operacijski sistem je nameščen s privzetimi nastavitvami, medtem ko vsebnik za svoje delovanje uporablja kontrolne skupine cgroups, ki poskrbijo za optimizacijo izvajanja procesov. V konkretnem primeru gre za t. i. “CPU pinning” oz. “CPU Affinity”, ki poskrbi, da paralelni oz. sočasni procesi v vsebniku (z vidika gostitelja LXC-proces in njegovi podprocesi) tečejo na istem jedru in uporabljajo pomnilnik, ki je z arhitekturnega vidika temu jedru najbližje (IBM Inc. 2014). Na ta način se procesi izvedejo hitreje, kar je razvidno tudi iz naših rezultatov meritev. Seveda bi lahko z optimizacijo gostitelja dosegli izboljšanje rezultatov, vendar smo namenoma obe meritvi izvedli v nespremenjenih okoljih, torej takšnih, kot so takoj po namestitvi. V naslednjem koraku smo preizkusili še agilnost vsebnika, tako da smo vsebnik Redis z enega gostitelja prenesli na drugega gostitelja in ga tam poskusili zagnati. Postopek smo 70 pričeli z izvozom slike, iz katere smo naredili vsebnik Redis. To smo storili z ukazom: # docker save redis:latest > redis.tar # ll redis.tar -rw-r–r– 1 root root 880720896 Nov 8 20:44 redis.tar Na ta način smo sliko pripravili na transport, zato smo jo lahko kopirali na drugega testnega gostitelja (pomožni testni strežnik, ki je dosegljiv na naslovu IP 172.17.0.20) in jo tam poskusili uvoziti v Docker. To smo storili z naslednjim ukazom: # scp redis.tar root@172.17.0.20:/tmp redis.tar 100% 840MB 105.0MB/s 00:08 na drugem testnem gostitelju smo izvedli uvoz in nato izpisali seznam slik, ki so bile na drugem testnem gostitelju voljo: # docker load < /tmp/redis.tar # docker images REPOSITORY TAG redis-test latest IMAGE ID c713a927c32d CREATED VIRTUAL SIZE 7 hours ago 855 MB Prenos in uvoz slike sta uspela, zato smo sliko zagnali v vsebnik: # docker run -tid redis 391bfe9b558ebeda26c591583085242035b2db4b73aa9560eea9dcf97ffbd992 Tudi zagon vsebnika je potekal brez težav. Iz izpisa lokalnega repozitorija po uvozu slike lahko vidimo, da slika obdrži isto ime in ID tudi na drugem strežniku, ID vsebnika pa se pri tem spremeni. Preizkus agilnosti vsebnika je s tem zaključen, ugotovimo lahko, da je potekal brez težav in da bi lahko prikazani postopek po potrebi popolnoma avtomatizirali. 71 4.3 Preizkus vsebnika LXC v vlogi razvojnega in izvajalnega okolja Za preizkus scenarija vsebnika LXC kot razvojnega in izvajalnega okolja smo izbrali dve odprtokodni programski rešitvi. To sta spletni strežnik Apache HTTP93 in podatkovni strežnik MariaDB94 . Vsako izmed njiju smo namestili v ločen vsebnik, ki smo ju nato povezali v skupno razvojno okolje. V tem scenariju je poudarek na pripravi in uporabi razvojnega ter izvajalnega okolja, zato tu nismo izvajali meritev ali performančnih testov, kot smo to počeli v predhodnem scenariju. Preizkusili smo povezovanje vsebnikov v enotno razvojno okolje, deljenje podatkov med vsebniki ter upravljanje z različicami slik vsebnikov. V prvem koraku smo pripravili sliki za oba vsebnika. Postopek izdelave je zelo podoben tistemu iz prvega scenarija, zato smo izpostavili samo dele postopka, ki se razlikujejo od že predstavljenega oz. so pomembni in jih je potrebno posebej izpostaviti. V primerih smo na primer prvič uporabili možnost lastnega poimenovanja vsebnikov. 4.3.1 Medsebojno povezovanje vsebnikov Vsebniki lahko med seboj komunicirajo na povsem običajen način, na primer tako, da prek izbranih omrežnih vrat omogočijo dostop do storitve. To lahko realiziramo na dva načina, in sicer z omejeno komunikacijo med vsebniki prek privatnih naslovov IP samo prek gostitelja ter s komunikacijo med vsebniki prek javnih naslovov IP. Poleg omenjenega pa je na voljo še poseben način povezovanja, t. i. “container linking” oz. povezovanje vsebnikov. Pri tem načinu se ustvari varen tunel med vsebnikoma, za kar ni potrebno dodatno definirati ali javno izpostaviti dostopa do omrežnih vrat vsebnika. Povezana vsebnika si namreč podatke izmenjata prek okoljskih spremenljivk (angl. environment variables) in nastavitve lokalne statične DNS95 -preslikave v datoteki /etc/hosts. Koncept povezovanja vsebnikov je zasnovan na izvornem in ciljnem vsebniku, pri čemer izvorni vsebnik dostopa oz. koristi storitve ciljnega vsebnika. V ta namen se po vzposta93 http://httpd.apache.org https://mariadb.org/en/about/ 95 http://tools.ietf.org/html/rfc1035 94 72 vitvi povezave na izvornem vsebniku nastavijo že omenjene okoljske spremenljivke. Tako izvorni vsebnik dobi informacijo, prek katerih omrežnih vrat ciljnega vsebnika so mu dostopne njegove storitve. Na podlagi tega smo pripravili tudi praktičen primer, kjer smo dovolili javen dostop samo do izvornega vsebnika z nameščenim spletnim strežnikom, ciljni vsebnik pa ni javno dostopen. Na ta način dosežemo želeno arhitekturo storitve, kjer je javno dostopen samo spletni strežnik, podatkovnega strežnika pa javno ne izpostavljamo. Do njega lahko dostopa le izvorni vsebnik prek predhodno definirane in vzpostavljene povezave. V naslednjem primeru smo preizkusili delovanje omenjene funkcionalnosti povezovanja vsebnikov. Iz slik, ki smo jih pripravili, smo ustvarili vsebnika. Najprej smo zagnali ciljni vsebnik, ki je vseboval podatkovni strežnik MariaDB. To smo storili z ukazom: # docker run -d –-name baza mariadb a138705dacfdcc6e17284062d83f42091156c98905946d2c468e45fca89903aa # docker ps CONTAINER ID IMAGE COMMAND dad93f3b32da mariadb start.sh PORTS NAMES 3306/tcp baza Iz zgornjega izpisa je razvidno, da se je ciljni vsebnik uspešno zagnal, da lokalno posluša na omrežnih vratih 3306 in da ima novo ime baza. Sledil je zagon izvornega vsebnika, ki je vseboval spletni strežnik Apache HTTP. To smo storili z ukazom: # docker run -d -P –name splet –link baza:dblink httpd e3d98e162287e31b215bde135f0db57031a9a0defb4bbbb60d5d73871afab65b # docker ps CONTAINER ID 4cdae4cd0124 dad93f3b32da IMAGE httpd mariadb COMMAND httpd PORTS 0.0.0.0:8080->80/tcp start.sh 3306/tcp NAMES splet baza Iz zgornjega zapisa je razvidno, da se je tudi izvorni vsebnik uspešno zagnal, da posluša na javnih omrežnih vratih 8080 gostitelja (ki so preslikana na lokalna vrata 80 vsebnika), da je povezan z vsebnikom z imenom baza (njuna povezava se imenuje dblink) in da ima tudi ciljni vsebnik novo ime splet. V naslednjem koraku smo preverili, ali vzposta- 73 vljena povezava med vsebnikoma dejansko deluje. Najprej smo preverili, ali so okoljske spremenljive v izvornem vsebniku nastavljene. To smo storili z ukazom: # docker exec -ti splet env | grep -i dblink DBLINK_PORT=tcp://172.17.0.24:3306 DBLINK_PORT_3306_TCP=tcp://172.17.0.24:3306 DBLINK_PORT_3306_TCP_ADDR=172.17.0.24 DBLINK_PORT_3306_TCP_PORT=3306 DBLINK_PORT_3306_TCP_PROTO=tcp DBLINK_NAME=/splet/dblink Zgornji izpis potrjuje, da so se okoljske spremenljive ustrezno nastavile, zato smo preverili še, kako je z nastavitvijo lokalne statične DNS-preslikave. To smo storili z ukazom: # docker exec -ti splet cat /etc/hosts 172.17.0.24 dblink Vse nastavitve smo preverili in so pravilne. Zato smo se lahko lotili izvedbe praktičnega preizkusa. Iz izvornega vsebnika splet smo se povezali na podatkovni strežnik v ciljnem vsebniku baza. To smo storili z naslednjim nizom ukazov: # docker exec -ti splet /bin/bash root@4cdae4cd0124# mysql -h $DBLINK_PORT_3306_TCP_ADDR -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 6 Server version: 5.5.39-MariaDB MariaDB Server Type ’help;’ or ’\h’ for help. Type ’\c’ to clear the current input statement. mysql> Z uporabo okoljske spremenljivke $DBLINK_PORT_3306_TCP_ADDR smo se iz izvornega vsebnika splet uspešno povezali na podatkovni strežnik baza. Preostal nam je le še preizkus dostopa do podatkovnega strežnika prek spleta. V ta namen smo predhodno 74 ustvarili enostavno podatkovno bazo in testno PHP96 spletno stran, s katerima smo preizkusili delovanje povezave. PHP spletna stran je bila sestavljena iz: <?php $con = new mysqli(“172.17.0.24”,“root”,“geslo”,“primer”); $result = $con->query(“SELECT id, data FROM splet”); $row = $result->fetch_assoc(); echo $row[“data”]; print_r($_SERVER); mysqli_close($con); ?> V prvem delu testne PHP-strani smo definirali povezavo do podatkovne baze oddaljenega sistema (vsebnika), nato smo sestavili enostavno SQL97 -poizvedbo in rezultat poizvedbe prikazali na spletni strani. Podatkovna baza v vsebniku je bila sestavljena iz ene same enostavne tabele: mysql> desc splet; Field Type Null Key Default Extra id int(11) YES NULL data varchar(255) YES NULL mysql> select * from splet; id data 1 To so podatki iz db ciljnega vsebnika. V njej se je nahajala zgolj ena vrstica, ki je vsebovala stavek: “To so podatki iz db ciljnega vsebnika.” V okviru zadnjega preizkusa v tem sklopu smo odprli spletno stran na gostitelju oz. izvornem vsebniku in preverili, ali le-ta izpiše vsebino, ki se nahaja na podatkovnem strežniku v ciljnem vsebniku. Slika 4.6 je potrdila naša pričakovanja. Tudi zadnji preizkus v tem sklopu nam je uspel. Iz izpisa spletne strani je razvidno, da se je iz podatkovnega strežnika na ciljnem vsebniku 96 97 http://php.net http://www.w3schools.com/sql/sql_intro.asp 75 Slika 4.6: Spletna stran na podlagi dveh vsebnikov Vir: Mihičinac, lastni prikaz (2014) prenesla vsebina na izvorni vsebnik, kjer jo je spletni strežnik uspešno prikazal. Poleg te vsebine smo izpisali še okoljske spremenljive izvornega vsebnika, ki potrjujejo izvedbo na njem. Opisani princip povezovanja vsebnikov seveda deluje tudi v primeru, ko med seboj želimo povezati več kot dva vsebnika hkrati. Zaradi uporabe okoljskih spremenljivk in lokalne statične DNS-preslikave se povezava med vsebniki ohrani tudi, če se jim med ponovnim zagonom ali zaradi česarkoli drugega spremeni naslov IP. 4.3.2 Deljenje podatkov med vsebniki in gostiteljem Vsebniki si lahko med seboj delijo lastne podatkovne sklope ali namenske podatkovne vsebnike. Lahko pa si delijo tudi podatke, ki se nahajajo na gostitelju. V naslednjem primeru smo preizkusili tako deljenje podatkov med vsebniki kot deljenje podatkov med vsebniki in gostiteljem. V tem primeru smo uporabili sliko vsebnika, ki smo jo v prejšnjem primeru izdelali za 76 vsebnik splet. V prvem koraku smo tako ustvarili dva vsebnika (aplikacija in podatki), ki sta si vzajemno delila mapo /opt/data, ki se je nahajala na vsebniku podatki. To smo storili z nizom ukazov: # docker run -d -v /opt/data –-name podatki httpd bb8f3bb24220224552c40524d42e42d0a9161c3e70d895b1e0911de831855eae # docker run -d –-volumes-from podatki –-name aplikacija httpd 731690f85d0f2c8052a046db88d9d098b5af5ed841d34d48deddeaffc821ebf6 Oba vsebnika smo uspešno zagnali. Ob zagonu smo pri vsebniku podatki z zastavico -v /opt/data definirali mapo, ki je bila na voljo za deljenje. Nato smo v vsebniku aplikacija z zastavico –-volumes-from podatki vanj povezali mapo, ki jo je delil vsebnik podatki. # docker exec aplikacija ls /opt/data # docker exec podatki touch /opt/data/test.txt # docker exec aplikacija ls /opt/data test.txt Delovanje deljenja mape smo preizkusili tako, da smo v vsebniku podatki v deljeni mapi ustvarili datoteko test.txt. Nato smo v vsebniku aplikacija preverili, ali vidi novo ustvarjeno datoteko. Zgornji izpis potrjuje, da je deljenje datotek med vsebniki delovalo. Če bi bilo to potrebno, bi lahko definirali več ločenih map za deljenje. V drugem koraku smo med obstoječima vsebnikoma delili vsebino mape /opt/www/, ki se je nahajala na gostitelju. To smo storili z naslednjim nizom ukazov: # docker run -d -v /opt/www/:/var/www/html –-name www1 httpd 9b7111c63f2de17f9d448963ae4522af98bd87967a8634eb4fe59cff9708a729 # docker run -d -v /opt/www/:/var/www/html –-name www2 httpd bcb47fdf0a8efeaee9bb3832e43c0f53802aca41bb1facfe5ca053d4dfcb8609 S tem smo v dva ločena vsebnika z imeni www1 in www2 delili vsebino hipotetične spletne strani, ki se nahaja v mapi /opt/www/ na gostitelju. Na ta način bi lahko isto vsebino preizkušali v dveh ali več različnih razvojnih okoljih hkrati. Poleg tega pa bi lahko vsebino urejali samo na enem mestu, spremembe pa bi bile vidne v obeh okoljih testnih vsebnikov. 77 Ta način deljenja ni primeren samo za deljenje celotne vsebine mape, temveč lahko delimo tudi samo eno izbrano datoteko (npr. konfiguracijsko datoteko). 4.3.3 Upravljanje različic slik vsebnikov Spremembe v vsebnikih lahko shranimo z ukazom docker commit. Pri tem se izvorni sliki vsebnika doda nov sloj (angl. layer) oz. nova različica, ki vsebuje zgolj spremembe (angl. delta). Vsako različico lahko označimo z izbrano značko (angl. tag), prek katere jo lahko kasneje referenciramo. Vedno lahko namreč zaženemo katerokoli različico slike vsebnika. Na ta način se povsem približamo konceptu nadzora različic (angl. version control), ki ga za shranjevanje sprememb datotek uporabljajo razvijalci. Dve najpogosteje uporabljeni orodji tega tipa sta SVN98 in git99 . Različice obstoječe slike v lokalnem repozitoriju izpišemo z ukazom: # docker images –-tree |–df7546f9f060 Virtual Size: 0 B |––e433a6c5b276 Virtual Size: 154.7 MB Tags: |––-e72ac664f4f0 Virtual Size: splet:init 160.3 MB Tags: |–––-cc5dfd0e1839 Virtual Size: splet:test |––––-c16dd1f24652 Virtual Size: 161.2 MB Tags: 329.4 MB Tags: splet:working |––––––9e2c455f906e Virtual Size: splet:update 329.4 MB Tags: |–––––––xeaba9acdab3b Virtual Size: 457.1 MB Tags: splet:phpreconfig splet:latest Skozi praktične primere obeh scenarijev smo prikazali uporabno vrednost tehnologije vsebnikov tudi z vidika razvojnega in izvajalnega okolja. V naslednjih poglavjih smo tehnologijo ocenili s pomočjo odločitvenega modela in nato ugotovitve povzeli še v analizi SWOT. 98 99 http://subversion.apache.org http://git-scm.com 78 4.4 Odločitveni model Odločitveni model temelji na kvalitativni večparametrski metodi DEX100 . Z njo smo na podlagi desetih izbranih kriterijev ocenili posamezno virtualizacijsko metodo. Kriterije smo strukturirali v drevo, ki je sestavljeno iz dveh osrednjih kriterijev in osem podkriterijev. Odločitveni model smo oblikovali s pomočjo programske rešitve DEXi101 . Izbor kriterijev v pretežni meri temelji na ključnih parametrih, ki so bili predmet opazovanja že pri testih in meritvah v empiričnem delu magistrske naloge. Osnovna delitev kriterijev na razvijalski in administratorski vidik izhaja iz paradigme “DevOps”, saj temelji na organizaciji dela v heterogenih skupinah, kjer v eni skupini sodelujejo tako razvijalci kot sistemski administratorji. Kljub temu imajo vsak svoj pogled na izbor ustrezne virtualizacijske metode. Pri razvijalskem vidiku so bistvenega pomena performanse, predvsem čim manjše povečanje skupne porabe oz. performanse, primerljive z nevirtualiziranim okoljem. Drugi sicer ne tako pomemben kriterij razvijalcev se nanaša na generalnost, torej neke vrste recikliranje oz. možnosti uporabe že izdelanega izvajalnega okolja v novih različnih scenarijih. Za oba kriterija smo uporabili enako lestvico, kjer smo se odločali med tremi vrednostmi. Če je varianta v celoti ustrezala posameznemu kriteriju, je dobila oceno “visoko”, če je ustrezala le deloma, je dobila oceno “srednje”, v primeru neustreznosti pa oceno “nizko”. Na podlagi funkcije koristnosti se je izpeljanemu kriteriju “Razvijalski vidik” določila ena izmed vrednosti z lestvice: ne ustreza, pogojno ustreza oz. ustreza. Vidik sistemskega administratorja je bolj kompleksen, saj mora sistemski administrator upravljati in zagotavljati nemoteno delovanje virtualizacijskega okolja, za razliko od razvijalca, ki je zelo posplošeno rečeno zgolj uporabnik tega okolja. Da bi zajeli vse pomembne aspekte, smo v okviru administratorskega vidika definirali šest atributov. Glede na to, da sta “varnost” in “zanesljivost” pričakovani pri vseh virtualizacijskeih metodah, pri variantah merimo zgolj zagotavljanje njune stopnje (od nizke do visoke). Kot ključna smo zato raje izpostavili dva atributa, ki pri izbiri virtualizacijskega okolja nista tako samoumevna, to sta “kompleksnost” in “agilnost”. Če bi nam uspelo najti virtualizacijsko 100 101 http://www-ai.ijs.si/MarkoBohanec/dex.html http://www-ai.ijs.si/MarkoBohanec/dexi.html 79 metodo, kjer bi bila kompleksnost nizka in agilnost visoka, bi to že predstavljalo trdno osnovo za izvedbo láhkega samozadostnega izvajalnega okolja. Tudi ta dva atributa smo ocenjevali glede na zagotavljanje njune stopnje pri posamezni varianti (od nizke do visoke). Naslednji zelo pomemben atribut administratorskega vidika je “podpora”. Pri njem smo ocenjevali ustreznost vzdrževanja oz. komercialne podpore, ki jo lahko najamemo pri proizvajalcu ali partnerskem podjetju. Tu ne gre za podporo končnim uporabnikom, temveč podporo sistemskim administratorjem v primeru težav z delovanjem programske opreme. Ta kriterij smo ocenili na podlagi lestvice z vrednostmi od “ne ustreza” do vrednosti “ustreza”. Kot zadnji obrobni atribut administratorskega vidika smo definirali še razširjenost posamezne virtualizacijske metode. Variante smo ocenjevali zgolj na podlagi spletne prisotnosti. Tabela 4.4: Drevo kriterijev odločitvenega modela in njihove zaloge vrednosti Primernost virtualizacijske metode...ni primerna; pogojno primerna; primerna Razvijalski vidik........................ne ustreza; pogojno ustreza; ustreza performanse..........................................nizke; srednje; visoke generalnost..........................................nizka; srednja; visoka Administratorski vidik .................. ne ustreza; pogojno ustreza; ustreza kompleksnost ........................................ visoka; srednja; nizka agilnost.............................................nizka; srednja; visoka varnost .............................................. nizka; srednja; visoka zanesljivost ........................................ nizka; srednja; visoka podpora ................................ ne ustreza; pogojno ustreza; ustreza razširjenost ........................................ nizka; srednja; visoka Vir: Mihičinac, lastna raziskava (2014) Potem ko smo sestavili drevo kriterijev, smo jim določili zalogo vrednosti (Tabela 4.4). Ta je organizirana od manj zaželenih do bolj zaželenih vrednosti. V vseh primerih je zaloga vrednosti sestavljena iz trinivojskih parametrov, in sicer negativne, srednje in pozitivne vrednosti. Za to metodo je značilno, da uporablja diskretne oz. simbolične parametre. Zaloga vrednosti je običajno majhna in sestavljena iz opisnih vrednosti (Bohanec, 2006). V naslednjem koraku smo osrednjim kriterijem določili funkcijo koristnosti, pri čemer smo definiranim pravilom ročno določili vrednosti (Tabela 4.5). Vrednotili smo na podlagi primarnih podatkov, ki smo jih dobili z izvedbo empiričnega dela magistrske naloge, lastnih izkušenj z metodami virtualizacije ter podatkov, ki smo jih pridobili iz literature in drugih virov. Na ta način smo določili preslikave med resničnimi vrednostmi vhodnih parame80 trov v stopnje ocen alternativ, izražene z uporabljenimi kriteriji. Iz metode DEX izhaja, da je funkcija koristnosti definirana s tabelo, v kateri vsem kombinacijam podrejenih parametrov določimo vrednosti, ki neposredno določajo vrednost nadrejenega parametra. Kombinacije s točkami predstavljajo odločitveno pravilo “če-potem” in kot take definirajo funkcijo koristnosti. DEXi lahko sam izračuna vrednost agregirane funkcije, če mu definiramo vsaj dve odločitveni pravili in ustrezne uteži (Bohanec, 2006). Tabela 4.5: Funkcije odločitvenega modela Primernost virtualizacijske metode .......... št.pravil:9, def.:100%, določ:100% Razvijalski vidik .......................... št.pravil:9, def.:100%, določ:100% performanse generalnost Administratorski vidik .................. št.pravil:729, def.:100%, določ:100% kompleksnost agilnost varnost zanesljivost podpora razširjenost Vir: Mihičinac, lastna raziskava (2014) V izhodišču metode DEX predpostavljamo, da je funkcija koristnosti ravnina, v kateri so vsi kriteriji enakomerno uteženi, torej ustrezajo modelu utežene vsote. Na podlagi tega programska rešitev DEXi za izpeljane kriterije sestavi agregirana pravila. Če tabelo pravil ročno definiramo, tako kot smo to storili mi, funkcija koristnosti preide v aproksimacijsko ravnino z različno uteženimi kriteriji (Jereb, Bohanec, in Rajkovič, 2003). V našem primeru smo na podlagi definiranih pravil kriterijem določili lokalne in globalne uteži, tako kot to prikazuje Tabela 4.6. Iz Tabela 4.6 je razvidno, da sta osrednja kriterija Razvijalski vidik in Administratorski vidik ovrednotena enakovredno, torej vsak po 50%. Podkriteriji so ovrednoteni zelo različno. Pri razvijalskem vidiku nosi glavno težo kriterij, ki se nanaša na performanse, in sicer kar 83%, medtem ko generalnost nosi preostalih 17%. Pri administrativnem vidiku so uteži med kriterije razporejene po naslednjem ključu: kompleksnost (21%), agilnost (21%), varnost (19%), zanesljivost (19%) in podpora (17%). Izjema je kriterij razširjenost (2%), ki ima zgolj obroben pomen in bi ga kot nerelevantnega lahko izločili iz odločitvenega modela. V naslednjem koraku smo določili variante, ki izhajajo iz treh predhodno že podrobno 81 Tabela 4.6: Povprečne uteži kriterijev odločitvenega modela Primernost virtualizacijske metode Razvijalski vidik...................................lokalne: performanse.......................................lokalne: generalnost.......................................lokalne: Administratorski vidik ............................. lokalne: kompleksnost ..................................... lokalne: agilnost..........................................lokalne: varnost ........................................... lokalne: zanesljivost ..................................... lokalne: podpora ........................................... lokalne: razširjenost ..................................... lokalne: 50, 83, 17, 50, 21, 21, 19, 19, 17, 02, globalne: globalne: globalne: globalne: globalne: globalne: globalne: globalne: globalne: globalne: 50 42 08 50 11 11 10 10 08 01 Vir: Mihičinac, lastna raziskava (2014) predstavljenih virtualizacijskih metod (polna virtualizacija, paravirtualizacija in virtualizacija na nivoju operacijskega sistema), zato jih na tem mestu ne bomo ponovno predstavljali. Rezultati vrednotenja variant so predstavljeni v Tabela 4.7. Iz zapisanega lahko ugotovimo, da sta z administratorskega vidika ustrezni dve varianti, z razvijalskega vidika pa samo ena. Ko upoštevamo oba vidika hkrati, se kot primerna metoda izkaže virtualizacije na nivoju operacijskega sistema. Pogojno uporabna je metoda polne virtualizacije, kot neprimerna se je zaradi predstavljenih specifik izkazala paravirtualizacija. Niti metoda polne virtualizacije niti metoda virtualizacija na nivoju operacijskega sistema pri nobenem kriteriju nista bili ocenjeni kot neprimerni. Rezultati so na nek način pričakovani, saj to potrjujejo že uvodoma obravnavani trendi, težnje po organizacijskih spremembah (DevOps), kot tudi vzbujeno zanimanje za tehnologijo vsebnikov pri vodilnih svetovnih podjetjih, katerih osnovna dejavnost je razvoj strežniške virtualizacije. Rezultate vrednotenja variant odločitvenega modela smo vizualizirali s polarnim grafikonom Slika 4.7, iz katerega je jasno razvidna razlika med variantami. Med variantama polne virtualizacije in virtualizacije na osnovi operacijskega sistema smo izvedli tudi t. i. analizo “kaj-če”. V ta namen smo si zastavili vprašanje, kaj se zgodi z rezultatom, če polni virtualizaciji v sklopu razvijalskega vidika zvišamo oceno atributa performanse. Hkrati varianti virtualizacije na nivoju operacijskega sistema znižamo oceno atributa podpora. Slika 4.8 vizualizira rezultat analize “kaj-če” (Tabela 4.8), iz katerega je razvidno, da 82 Tabela 4.7: Rezultati vrednotenja variant odločitvenega modela Kriteriji \Variante polna virt. paravirt. virt. na nivoju OS Primernost virt. met. pogojno primerna ni primerna Razvijalski vidik pogojno ustreza pogojno ustreza ustreza performanse srednje srednje visoke generalnost srednja nizka srednja Administratorski vidik pogojno ustreza ne ustreza ustreza kompleksnost srednja visoka nizka agilnost srednja nizka visoka varnost visoka srednja srednja zanesljivost visoka srednja srednja podpora primerna primerna pogojno primerna razširjenost visoka srednja visoka primerna Vir: Mihičinac, lastna raziskava (2014) Slika 4.7: Polarni grafikon kriterijev odločitvenega modela generalnost kompleksnost performanse agilnost podpora razširjenost varnost zanesljivost — polna virtualizacija, — paravirtualizacija, Vir: Mihičinac, lastni prikaz (2014) 83 — virtualizacija na nivoju OS Tabela 4.8: Rezultati vrednotenja variant za analizo kaj-če Kriteriji \Variante polna virt. paravirt. virt. na nivoju OS Primernost virt. met. pogojno primerna ni primerna Razvijalski vidik ustreza pogojno ustreza ustreza performanse visoke srednje visoke generalnost srednja nizka srednja Administratorski vidik pogojno ustreza ne ustreza ne ustreza kompleksnost srednja visoka nizka agilnost srednja nizka visoka varnost visoka srednja srednja zanesljivost visoka srednja srednja podpora primerna primerna ne ustreza razširjenost visoka srednja visoka ni primerna Vir: Mihičinac, lastna raziskava (2014) se skupna ocena variante polne virtualizacije ne spremeni, saj sklop administratorskega vidika še vedno ostaja pogojno ustrezen, skupna ocena pa je lahko primerna le, če sta oba vidika ocenjena kot ustrezna. Po znižanju ocene atributa podpora varianta virtualizacije na nivoju operacijskega sistema ni več ocenjena kot primerna virtualizacijska metoda. Iz tega lahko sklepamo, da je izbrana virtualizacijska metoda virtualizacija na osnovi operacijskega sistema zelo blizu meje neprimernosti. 4.5 Rezultati Na podlagi primarnih podatkov, ki smo jih dobili z izvedbo empiričnega dela magistrske naloge, iz lastnih izkušenj z metodami virtualizacije in podatkov, ki smo jih pridobili iz literature ter drugih virov, smo prišli do zaključkov, ki smo jih strnili v analizi SWOT (Tabela 4.9). Po metodi analize SWOT smo pod drobnogled vzeli štiri aspekte: prednosti, slabosti, priložnosti in nevarnosti. Prva dva se nanašata na okolje lastnega vpliva, torej notranje okolje, v katerem imamo možnost ukrepanja. Druga dva se nanašata na zunanje okolje, torej okolje, na katero nimamo vpliva in se moramo nanj znati prilagoditi (Minton, 84 Slika 4.8: Polarni grafikon analize kaj-če generalnost kompleksnost performanse agilnost podpora razširjenost varnost zanesljivost — polna virtualizacija, — virtualizacija na nivoju OS Vir: Mihičinac, lastni prikaz (2014) 2010). Vse štiri aspekte gledamo skozi prizmo pozitivnega oz. negativnega vpliva na dosego cilja. Seveda se na pozitiven vpliv nanašajo prednosti in priložnosti, na negativen vpliv pa slabosti in nevarnosti. V splošnem je glavni namen analize SWOT pomoč pri strateških odločitvah, v smislu kam usmeriti poslovanje, katere programe opustiti oz. katere podpreti. Končna strategija predvideva, da gradimo na prednostih, pri čemer hkrati skušamo v največji meri odpraviti pomanjkljivosti. Pri tem si želimo identificirane priložnosti kar najbolj izkoristiti in se v največji možni meri izogniti identificiranim nevarnostim (Minton, 2010). Pri analizi SWOT virtualizacije na nivoju operacijskega sistema smo identificirali številne prednosti. Izpostavili smo le nekaj najpomembnejših. Z uporabo metode virtualizacije na nivoju operacijskega sistema močno poenostavimo postopke priprave novega virtualnega okolja, pa tudi upravljanja in recikliranja obstoječih vsebnikov. Zaradi praktično nične povečane stopnje skupne porabe lahko veliko bolje izkoristimo strojne vire, ki so nam na voljo. Performančni testi v empiričnem delu magistrske naloge so namreč vsi po vrsti 85 Tabela 4.9: Analiza SWOT - PSPN matrika Pozitiven vpliv Negativen vpliv PREDNOSTI: poenostavitev po- SLABOSTI: uvajanje nove tehno- stopkov virtualizacije; boljša iz- logije zahteva nova znanja in spre- koriščenost virov; hitrejša vzpo- tnosti; omogoča virtualizacijo za stavitev; hitrejši prehod med fa- in zgolj na Linux operacijskem zami razvoja in produkcijo; agil- sistemu; (še) ni podpore gručam; nost vsebnikov; vsebniki za enkra- omrežno usmerjanje odvisno od ip- tno uporabo; razvojni peskovnik; tables; varnostno (še) ne povsem brezplačna odprtokodna rešitev. preverjena rešitev. PRILOŽNOSTI: atomizacija oz. NEVARNOSTI: ni uradne komer- poenostavitev kompleksnih več ni- cialne podpore; prehod na plačljiv vojskih storitev; sprememba or- model; veliko sprememb zaradi hi- ganizacijskega modela v hetero- trega razvoja; zastoj razvoja za- gene DevOps skupine; konku- radi sovražnega prevzema; nego- infrastrukturno tova prihodnost, ker se tehnologija neodvisno delovanje; partnersta s na trgu še ni ustalila; pojav konku- ključnimi podjetji branže. renčne, naprednejše tehnologije. Zunanje okolje (na področje nimamo vpliva) (področje lastnega vpliva) Notranje okolje (na dosego cilja) (na dosego cilja) P S P N renčna prednost; Vir: Mihičinac, lastna raziskava (2014) dokazovali, da je ta metoda performančno enakovredna nevirtualiziranemu okolju. Pomemben faktor uporabe vsebnikov predstavlja tudi boljše povezovanje razvojnih skupin in skupin, ki skrbijo za sistemsko administracijo. Z vsebniki namreč ni potrebno poustvarjati razvojnega, testnega in produkcijskega okolja. Vse tri oz. prehod med njimi lahko izpeljemo na obstoječem okolju preprostega vsebnika. Agilnost vsebnikov je naslednja identificirana prednost, namreč vsebnik lahko zelo preprosto posredujemo med gostitelji oz. med vpletenimi uporabniki, razvojniki in sistemskimi administratorji. Prav tako lahko zaradi preproste priprave vsebnika le-tega prikrojimo do te mere, da je uporaben namensko, lahko tudi samo za enkratno uporabo, lahko v vlogi testnega peskovnika ali specifičnega izvajalnega okolja. Nenazadnje še pomembna prednost, celotna programska rešitev in vsa uporabljena tehnologija sta brezplačni in temeljita na odprti kodi. 86 Identificirane slabosti virtualizacije na osnovi operacijskega sistema so naslednje. Uvajanje nove tehnologije je vedno stresno in naporno početje, saj posega v ustaljene in preverjene postopke dela. Za to je poleg usposobljenega kadra, ki ima ustrezna znanja in spretnosti, potrebno tudi stremljenje zaposlenih k nenehnim izboljšavam. Prva tehnična omejitev rešitve se nanaša predvsem na dejstvo, da omenjena virtualizacijska metoda deluje zgolj na gostiteljih z nameščenim Linux operacijskim sistemom, hkrati pa lahko v vsebnike virtualiziramo samo Linux procese. Naslednja tehnična omejitev je odsotnost podpore gručam. To pomeni, da posameznih gostiteljev ne moremo povezovati v gruče, kjer bi si lahko vsebniki delili vire celotne gruče. Glede omrežnega usmerjanja prometa v vsebnike sicer nismo identificirali pomanjkljivosti, vendar zaradi neposredne odvisnosti vsebnikov od omrežnega usmerjanja od gostiteljeve storitve “iptables” 102 to dejstvo štejemo za slabost. Tehnologija je sicer že zrela za uporabo v produkcijskem okolju, vendar se zaradi kratke zgodovine uporabe varnostno še ni povsem izkazala. Zato smo varnostni vidik zapisali pod identificirane slabosti. Vse omenjene tehnične pomanjkljivosti so razvijalci programske rešitve Docker že identificirali in obljubljajo, da jih bodo v prihodnjih različicah programske opreme odpravili. V aspektu priložnosti smo izpostavili naslednje. Z uporabo vsebnikov in metode atomizacije lahko kompleksne večnivojske (angl. n-tier) programske rešitve oz. storitve z atomizacijo poenostavimo. Na ta način lahko posamezne vsebnike in storitve kot celoto naredimo infrastrukturno neodvisne. Uporaba virtualizacije na nivoju operacijskega sistema lahko prinese tudi spremembo organizacijskega modela, kjer do nedavnega strogo ločene skupine razvijalcev in sistemskih administratorjev združimo v heterogene skupine, v katerih sodelujejo poprej oddelčno in funkcijsko ločeni strokovnjaki. Glede na to, da je tehnologija še zelo mlada, lahko s hitro uvedbo (angl. adoption) dosežemo določeno stopnjo konkurenčne prednosti v primerjavi s ponudniki tradicionalnih metod virtualizacije, kot tudi prek povezovanja in vzpostavljanja partnerstev s ključnimi podjetji obravnavane branže. Na koncu smo izpostavili še najpomembnejše nevarnosti, ki smo jih definirali pri virtualizaciji na osnovi operacijskega sistema. V produkcijskih okoljih velikih korporacij mora biti za uporabljene strojne in programske vire običajno na voljo možnost najema komercialne podpore oz. vzdrževanja za primer napake na strojni opremi ali odkritih pomanjkljivosti 102 http://www.netfilter.org/projects/iptables/index.html 87 v programski opremi. Ta raven podpore trenutno še ni na voljo, vendar gre pričakovati, da jo bodo Docker oz. njegova partnerska podjetja ponudila kmalu, saj koncept plačevanja podpore za sicer brezplačno odprtokodno programsko opremo velja za vzdržnega v odprtokodnem okolju. Vsekakor je uvedba nove tehnologije, ki je še v fazi intenzivnega razvoja, povezana z nenehnimi spremembami postopkov uporabe, kar lahko sistemskim administratorjem v fazi uvajanja povzroči nepredvidene težave oz. dodatna vzdrževalna dela. V sklopu nevarnosti smo identificirali tudi bojazen, da lahko pride do zastoja razvoja zaradi sovražnega prevzema. Takim scenarijem smo bili v preteklosti že priča (npr. Oraclov prevzem podjetja Sun Microsystems103 ). Prihodnost je negotova tudi zaradi tega, ker je tehnologija še mlada in se na trgu še ni ustalila. Kot vedno, med nevarnosti lahko prištevamo morebiten pojav nove naprednejše konkurenčne tehnologije, ki bi izpodrinila obstoječo. 5. ZAKLJUČEK Na področju virtualizacije strežnikov se v zadnjem času odvija proces korenitih sprememb. V magistrski nalogi smo na podlagi teoretičnih izhodišč, trendov in prikaza scenarijev uporabe predstavili kritično primerjavo med različnimi metodami virtualizacije strežnikov. Osrednjo pozornost smo namenili obetavni virtualizaciji na nivoju operacijskega sistema oz. tehnologiji LXC-vsebnikov. V povezavi s programsko rešitvijo Docker trenutno predstavlja vodilno gonilno silo sprememb. Njen potencial se je nakazoval že v uvodoma predstavljenih dejstvih, skozi empiričen del magistrske naloge pa se je samo še potrdil. Tehnologija vsebnikov spreminja koncept tradicionalne virtualizacije strežnikov v koncept láhkih samozadostnih vsebnikov, ki vpliva tudi na organizacijske spremembe oz. spremembe načina in organizacije dela, ter se osredotoča predvsem na aplikacijo kot tako (angl. application centric). V empiričnem delu magistrske naloge smo prikazali vse prednosti omenjene tehnologije, predvsem tu izstopajo performančni vidik, agilnost in nizka stopnja kompleksnosti. Pose103 http://www.zdnet.com/is-it-time-for-oracle-to-donate-mysql-to-apache-7000011803/ 88 bej moramo poudariti nično povečanje skupne porabe, kar je za vse ostale virtualizacijske metode nedosegljivo. Tehnologija vsebnikov se je pokazala kot zrela, vendar se je zaradi svoje kratke zgodovine obstoja do sedaj uspela uveljaviti le v podjetjih, ki se ukvarjajo z informacijsko tehnologijo ali razvojem programske opreme. Ravno v času priprav na izdelavo te magistrske naloge je tehnologija doživela veliko podporo s strani pomembnih podjetij, kot so: Red Hat, VMware in Microsoft. Zato ne gre dvomiti, da se bo uporaba razširila tudi na podjetja drugih branž. Na podlagi primarnih podatkov, ki smo jih pridobili prek izvedbe testiranj v empiričnem delu magistrske naloge, lastnih izkušenj z virtualizacijskimi metodami in podatkov iz literature ter drugih virov, smo izdelali odločitveni model, ki temelji na kvalitativni večparametrski metodi DEX. Rezultat vrednotenja variant je pokazal, da je tudi s tega vidika tehnologija virtualizacije na nivoju operacijskega sistema oz. tehnologija vsebnikov LXC najprimernejša izbira. Tu smo upoštevali dva vidika, in sicer vidik razvijalcev in sistemskih administratorjev, medtem ko vidik končnega uporabnika v tem primeru ne sme biti relevanten, saj mora biti menjava virtualizacijske tehnologije zanj transparentna. Rezultate smo v zaključku analize strnili v PSPN-matriko (SWOT-analiza), kjer smo izpostavili prednosti, slabosti, priložnosti in nevarnosti, ki se pojavijo ob uporabi tehnologije LXC-vsebnikov. Ugotovili smo, da je pozitiven vpliv prevladujoč, negativen pa se nanaša predvsem na pomanjkljivosti, ki so posledica intenzivnega razvoja, s katerim bodo odpravili tudi trenutne pomanjkljivosti. Prepričani smo, da so bili namen magistrske naloge in uvodoma zastavljeni cilji v celoti doseženi. Podrobno smo namreč analizirali tehnologijo vsebnikov ter na hipotetičnih primerih predstavili metode, ki jih lahko uporabimo za reševanje realnih problemov. Predstavili smo glavne prednosti in slabosti virtualizacije na nivoju operacijskega sistema oz. uporabe vsebnikov LXC in rezultate analize. Na podlagi tega lahko podamo odgovore na vsa zastavljena raziskovalna vprašanja, ki smo si jih zastavili uvodoma. Podrobno smo jih utemeljili že tekom izdelave empiričnega dela magistrske naloge, povzamemo lahko naslednje: ∙ Virtualizacija na nivoju operacijskega sistema oz. vsebnikov LXC je splošno primerna za različne scenarije uporabe, glavna omejitev je človeški faktor, torej sistem- 89 ski administrator, ki potrebuje ustrezna znanja in sposobnosti, da novo tehnologijo koristno uporabi. ∙ Glavne prednosti virtualizacije na nivoju operacijskega sistema oz. vsebnikov LXC. Prednosti: nično povečanje skupne porabe, odlične performanse, nizka stopnja kompleksnosti in agilnost. Slabosti: zaradi kratke zgodovine obstoja tehnologija še ni uveljavljena in ima nekaj manjših tehničnih pomanjkljivosti, ki jih že odpravljajo. ∙ Tehnologija virtualizacije na nivoju operacijskega sistema oz. vsebnikov LXC je primerna za produkcijsko okolje, vendar zgolj tam, ker imamo na voljo usposobljeno ekipo strokovnjakov, saj komercialna podpora še ni na voljo. Z novimi spoznanji, do katerih smo prišli ob izdelavi tega magistrskega dela, se lahko opredelimo tudi do uvodoma postavljene teze, torej z virtualizacijo na nivoju operacijskega sistema oz. vsebnikov LXC lahko ustvarimo láhko, prilagodljivo, samozadostno in infrastrukturno neodvisno izvajalno okolje. Vendar le, če se omejimo na Linux. Glede na to, da je med drugimi podporo napovedal tudi Microsoft, se teza v prihodnosti morda v celoti in brez zadržkov potrdi. 5.1 Ocena učinkov Tehnologijo vsebnikov je do sedaj najbolje izkoristilo podjetje Google. Pri njih praktično vse teče v vsebnikih. Že samo podatek, da tedensko zaženejo več kot 2 milijardi vsebnikov, je dovolj, da pokaže zrelost in zaupanje v tehnologijo (Beda, 2014). Kljub temu tudi pri Googlu vsebnike poganjajo zgolj interno in jih še ne ponujajo zunanjim uporabnikom. Ocenjujemo, da bo pravi razmah tehnologija dosegla, ko bodo njene prednosti oz. vrednost zaznali tudi v podjetjih, v katerih primarna dejavnost ni povezana z informacijsko tehnologijo. Povsem novo dimenzijo vsebnikov pa gre pričakovati, ko bo tehnologijo tudi v praksi podprl Microsoft. Takrat bo namreč lahko prišlo do fuzije procesov različnih operacijskih sistemov, na podlagi katere bomo imeli možnost uporabe infrastrukturno neodvisnih programskih rešitev, storitev ali procesov. 90 5.2 Pogoji za izvedbo Pogoji za izvedbo so v največji meri povezani z ustrezno usposobljenimi kadri in primerno organizacijsko strukturo oz. organizacijo dela. Uporabljena programska oprema je v celoti odprtokodna in brezplačna, zato finančni vidik tu ni odločilni dejavnik. S tehničnega vidika je pomembna vpeljava programske rešitve Docker, ki poskrbi za bistveno znižanje ravni kompleksnosti izdelave vsebnikov in za poenostavitev procesov, povezanih z agilnostjo vsebnikov. Pred uvedbo virtualizacije na nivoju operacijskega sistema v produkcijsko okolje se je potrebno zavedati, da je le-ta še vedno v fazi razvoja. To je seveda povezano s potrebo po nenehnem sledenju novostim in upoštevanju le-teh v produkcijskem okolju. Zadnji in tudi najpomembnejši pogoj za izvedbo je dejstvo, da je tehnologija vsebnikov LXC podprta le na operacijskem sistemu Linux. Zato lahko na ta način virtualiziramo samo Linux procese oz. programske rešitve ali storitve, ki tečejo na tem operacijskem sistemu. V prihodnosti je moč pričakovati, da se bo podpora razširila tudi na druge operacijske sisteme, vendar lahko v tem trenutku za marsikoga to predstavlja nepremostljivo oviro. 5.3 Možnosti za nadaljnje raziskovanje Možnosti za nadaljnje raziskovanje je ogromno in težko bi izpostavili zgolj eno. Orkestracija vsebnikov je prva izmed zelo zanimivih možnosti za nadaljnje raziskovanje. Na podlagi tega bi lahko avtomatizirali nadzor nad velikim številom vsebnikov hkrati. Po potrebi bi se samodejno ustvarili novi oz. samodejno izklopili tisti, ki jih ne bi več potrebovali. Veliko prostora za raziskovanje omogočajo tudi infrastrukturna področja, kot na primer: podpora gručam, napredne podatkovne shrambe in podpore programsko definiranim omrežjem (angl. software defined networking - SDN). Gradnja lastnega ekosistema oz. platform na podlagi vsebnikov je še ena iztočnica za nadaljnje raziskovanje. V okviru tega bi lahko dali še večji poudarek razvoju distribuiranih oz. razpršenih aplikacij, ki bi se bile znotraj ekosistema zmožne med seboj odkrivati in 91 sinergijsko povezovati. Na ta način bi lahko prešli s koncepta počasnega razvoja prek monolitnih aplikacij do dinamičnih distribuiranih aplikacij. 92 6. LITERATURA IN VIRI 1. BEDA, JOE (2014) Containers At Scale. Dostopno prek: https://speakerdeck.com/jbeda/containers-at-scale (12. 10. 2014). 2. BOHANEC, MARKO (2006) Odločanje in modeli. Ljubljana: Društvo matematikov, fizikov in astronomov slovenije - DMFA založništvo. 3. BOTTOMLEY, JAMES in EMELYANOV, PAVEL (2014) Linux Containers Usenix Login, 39 (5), str. 6—10. 4. COSTA, GLAUBER (2012) LinuxCon Europe: Resource Isolation: The Failure of Operating Systems & We Can Fix It. Dostopno prek: http://linuxconeurope2012.sched.org/event/bf1a2818e908e3a534164b52d5b85bf1 (12. 10. 2014). 5. DEMEYER, SERGE (2011) Research Methods in Computer Science. Dostopno prek: http://win.ua.ac.be/ sdemey/Tutorial_ResearchMethods/ResearchMethds00 _Contents.pdf (12. 10. 2014). 6. DICTIONARY.COM LLC (2014) Find the meanings and definitions of words. Dostopno prek: http://dictionary.reference.com/browse/para-?s=t (12. 10. 2014). 7. DOCKER INC. (2014) Docker Docs. Dostopno prek: https://docs.docker.com (12. 10. 2014). 8. FELTER, WESLEY, FERREIRA, ALEXANDRE, RAJAMONY, RAM in RUBIO, JUAN (2014) An Updated Performance Comparison of Virtual Machines and Linux Containers. Austin, ZDA: IBM Research Division. 9. FOLEY, MARY JO (2014) Docker container support coming to Microsoft’s next Windows Server release. Dostopno prek: http://www.zdnet.com/docker-container-supportcoming-to-microsofts-next-windows-server-release-7000034708/ (12. 10. 2014). 10. GARTNER INC. (2014) Gartner IT Glossary. Dostopno prek: http://www.gartner.com/it-glossary/ (12. 10. 2014). 93 94 11. GOLDBERG, ROBERT (1973) Architecture of virtual machines. Dostopno prek: http://dl.acm.org/citation.cfm?id=803950 (12. 10. 2014). 12. GOOGLE INC. (2014) Google Trends. Dostopno prek: http://www.google.com/trends/ (12. 10. 2014). 13. HALLYN, SERGE in GRABER, STÉPHANE (2013) LXC - Linux Containers. Dostopno prek: https://linuxcontainers.org (12. 10. 2014). 14. IBM INC. (2014) Running Parallel Jobs. Dostopno prek: http://www-01.ibm.com/ support/knowledgecenter/#!/SSETD4_9.1.2/lsf _admin/chap_parallel_lsf_admin.dita (12. 10. 2014). R R 15. INTEL CORPORATION (2006) Intel○Virtualization Technology and Intel○Active Management Technology in Retail Infrastructure. Dostopno prek: http://www.intel.com/design/intarch/papers/316087.pdf (12. 10. 2014). 16. JANAKIRAM MSV (2014) Demystifying Kubernetes: the tool to manage Google-scale workloads in the cloud. Dostopno prek: http://www.computerweekly.com/feature/ Demystifying-Kubernetes-the-tool-to- manage-Google-scale-workloads-in-the-cloud (12. 10. 2014). 17. JEREB, EVA, BOHANEC, MARKO in RAJKOVIČ, VLADISLAV (2003) Računalniški program za večparametrsko odločanje. Kranj: Moderna organizacija v sestavi fakultete za organizacijske vede Univerze v Mariboru. 18. KASAMPALIS, SAKIS (2010) Copy On Write Based File Systems Performance Analysis And Implementation. Dostopno prek: http://faif.objectis.net/download-copy-onwrite-based-file-systems (12. 10. 2014). 19. KNUTH, GABE (2007) A brief history of Xen and XenSource. Dostopno prek: http://www.brianmadden.com/blogs/gabeknuth/archive/2007/08/16/a-brief-historyof-xen-and-xensource.aspx (12. 10. 2014). 20. LI, JACK, WANG, QINGYANG, JAYASINGHE, DEEPAL, PARK, JUNHEE, ZHU, TAO in PU, CALTON (2013) Performance Overhead Among Three Hypervisors: An Experimental Study using Hadoop Benchmarks. Dostopno prek: http://www.cc.gatech.edu/ qywang/papers/JackLiBigdata13.pdf (12. 10. 2014). 95 96 21. LIBVIRT.ORG (2014) Control Groups Resource Management & LXC container driver. Dostopno prek: http://libvirt.org/drvlxc.html (12. 10. 2014). 22. MANN, ANDI (2006) Virtualization 101: Technologies, Benefits, and Challenges. Dostopno prek: http://etomicmail.com/files/dedicated_server/ Virtualization%20101.pdf (12. 10. 2014). 23. MCALLISTER, NEIL (2014) Microsoft, Docker bid to bring Linux-y containers to Windows: What YOU need to know. Dostopno prek: http://www.theregister.co.uk/2014/10/16/windows_containers_deep_dive/ (12. 10. 2014). 24. MINTON, GABE (2010) Using a SWOT Analysis, 71 (3), str. 80––81. Dostopno prek: http://search.proquest.com/docview/820531614 (12. 10. 2014). 25. NAIR, P. K. RAMACHANDRAN in NAIR, VIMALA D (2014) Organization of a Research Paper: The IMRAD Format. Springer International Publishing. Dostopno prek: http://link.springer.com/chapter/10.1007/978-3-319-03101-9_2 (12. 10. 2014). 26. O’BRIEN, DAVID (2006) AMDTM64 Virtualization. Dostopno prek: http://developer.amd.com/wordpress/media/2012/10/9-David_ObrienAMD_India_SVM_DO_v1.pdf (12. 10. 2014). 27. ORACLE CORPORATION (2011) Introduction to Virtualization. Dostopno prek: http://docs.oracle.com/cd/E20065_01/doc.30/e18549/intro.htm (12. 10. 2014). 28. ORACLE CORPORATION (2012) Linux Containers (LXC). Dostopno prek: http://www.oracle.com/us/technologies/linux/lxc-features-1405324.pdf (12. 10. 2014). 29. PEIKARI, CYRUS in CHUVAKIN, ANTON (2004) Security Warrior. O’Reilly Media, Inc. 30. PENDRY, JAN-SIMON in MCKUSICK, MARSHALL KIRK (1995) Union Mounts in 4.4BSD-lite, Proceedings of the USENIX 1995 Technical Conference Proceedings. TCON’95. Berkeley, CA, USA: USENIX Association, str. 3—9. 31. RAYA, FIDEL (1984) The Case Study Method: Case study. Dostopno prek: http://faculty.washington.edu/fidelr/RayaPubs/TheCaseStudyMethod.pdf (12. 10. 2014). 97 98 32. RED HAT INC (2013) Red Hat and dotCloud Collaborate on Docker to Bring Next Generation Linux Container Enhancements to OpenShift Platform-as-a-Service. Dostopno prek: http://www.redhat.com/en/about/press-releases/red-hat-and-dotcloudcollaborate-on-docker-to-bring-next-generation-linux-container-enhancements-to -openshift (12. 10. 2014). 33. SANFILIPPO, SALVATORE (2014) Redis documentation. Dostopno prek: http://redis.io/documentation (12. 10. 2014). 34. SHANLEY, TOM (2010) x86 Instruction Set Architecture - Comprehensive 32/64-bit Coverage MindShare Press, str: 1391-1478. 35. SHENK, JERRY (2013) Layered Security: Why It Works. Dostopno prek: http://www.sans.org/reading-room/whitepapers/analyst/layered-security -works-34805 (12. 10. 2014). 36. SHIELDS, GREG (2008) Selecting the Right Virtualization Solution. Realtimepublishers.com Inc, str: 39-50. 37. SURKSUM, KENNETH VAN (2014) Gartner releases its 2014 Magic Quadrant for x86 Server Virtualization Infrastructure. Dostopno prek: http://virtualization.info/ en/news/2014/07/gartner-releases-its-2014-magic-quadrant-for-x86-servervirtualization-infrastructure.html (12. 10. 2014). 38. TANG, XUEHAI, ZHANG, ZHANG, WANG, MIN, WANG, YIFANG, FENG, QINGQING in HAN, JIZHONG (2014) Performance Evaluation of Light-Weighted Virtualization for PaaS Clouds. Lecture Notes in Computer Science, no. 8630. Springer International Publishing. Dostopno prek: http://link.springer.com/chapter/10.1007/ 978-3-319-11197-1_32 (12. 10. 2014). 39. TANGE, OLE (2011) GNU Parallel - The Command-Line Power Tool. Dostopno prek: http://www.gnu.org/s/parallel (12. 10. 2014). 40. THE FREEBSD DOCUMENTATION PROJECT (2000) FreeBSD Architecture Handbook. Dostopno prek: https://www.freebsd.org/doc/en_US.ISO8859-1/books/archhandbook/index.html (12. 10. 2014). 99 100 41. THE POSTGRESQL GLOBAL DEVELOPMENT GROUP (2014) PostgreSQL 9 Documentation. Dostopno prek: http://www.postgresql.org/docs/9.0/static/kernelresources.html (12. 10. 2014). 42. THE VAR GUY (2014) What Comes After Traditional Server Virtualization? Dostopno prek: http://thevarguy.com/virtualization-applications-and-technologies /030414/what-comes-after-traditional-server-virtualization (12. 10. 2014). 43. TURNBULL, JAMES (2014) The Docker Book: Containerization is the new virtualization. Dostopno prek: http://www.dockerbook.com 44. VAN DER PAS, RUUD (2010) Basic Concepts in Parallelization. Dostopno prek: http://www.compunity.org/training/tutorials/2 Basic_Concepts_Parallelization.pdf (12. 10. 2014). 45. VARIAN, MELINDA (1997) VM and the VM Community: Past, Present, and Future. Dostopno prek: http://www.leeandmelindavarian.com/Melinda/25paper.ps (12. 10. 2014). 46. VMWARE INC. (2007) Understanding Full Virtualization, Paravirtualization, and Hardware Assist. Dostopno prek: http://www.vmware.com/files/pdf/ VMware_paravirtualization.pdf (12. 10. 2004). 47. VMWARE INC. (2014) VMware Teams With Docker, Google and Pivotal to Simplify Enterprise Adoption of Containers. Dostopno prek: http://ir.vmware.com/releasedetail.cfm?releaseid=867568 (12. 10. 2014). 48. WALKER, RAY (2006) Examining Load Average. Dostopno prek: http://www.linuxjournal.com/article/9001 (12. 10. 2014). 49. WALSH, DAN (2013) Linux Containers Overview & Roadmap. Dostopno prek: http://rhsummit.files.wordpress.com/2013/06/sarathy_w_0340_secure _linux_containers_roadmap.pdf (12. 10. 2014). 50. WALTERS, BRIAN (1999) VMware Virtual Platform. LINUX Journal, 63 (5). Dostopno prek: http://www.linuxjournal.com/article/3458 (12. 10. 2014). 101 102 51. WELSH, MATT (2007) Operating Systems. Dostopno prek: http://www.eecs.harvard.edu/ mdw/course/cs161/notes/osstructure.pdf (12. 10. 2014). 52. WOLF, CHRIS (2014) VMware and Docker – Better Together. Dostopno prek: http://blogs.vmware.com/cto/vmware-docker-better-together/ (12. 10. 2014). 53. XEN PROJECT (2013) The Xen Project, the powerful open source industry standard for virtualization. Dostopno prek: http://www.xenproject.org (12. 10. 2014). 54. YANG, YU (2007) OS-level Virtualization and Its Applications. Dostopno prek: http://www.ecsl.cs.sunysb.edu/tr/TR223.pdf (12. 10. 2014). 103 104 PRILOGI Priloga 1: Kratice in akronimi Priloga 2: LXC-predloga za storitev sshd Priloga 1: Kratice in akronimi API . . . . programski vmesnik (angl. application program interface) CLI . . . . vmesnik z ukazno vrstico (angl. command-line interface) CPU . . . . centralna procesna enota - procesor (angl. central processing unit) DDoS . . . porazdeljena ohromitev storitve (angl. distributed denial of service) DEX . . . . strokovnjak za odločitve (angl. decision expert) DNS . . . . sistem domenskih imen (angl. domain name system) EOF . . . . znak za konec datoteke (angl. end-of-file) FLOPS . . enota za število izvršenih operacij s plavajočo vejico v sekundi (angl. floating-point operations per second) GPL . . . . splošno dovoljenje GNU (angl. GNU public licence) HCL . . . . seznam združljive strojne opreme (angl. hardware compatibility list) HTTP . . . protokol za izmenjavo hiperteksta ter grafičnih, zvočnih in drugih večpredstavnostnih vsebin na spletu (angl. hypertext transfer protocol) HTTPS . . protokol, ki omogoča varno spletno povezavo (angl. protokol, ki omogoča varno spletno povezavo) I/O . . . . vhodno/izhodni (angl. input/output) IaaS . . . . infrastruktura kot storitev (angl. infrastructure as a service) ID . . . . . oznaka (angl. identifier) IKT . . . . informacijska in komunikacijska tehnologija (angl. ICT - information and communication technology) IOPS . . . enota za število vhodno/izhodnih operacij na sekundo (angl. I/O operations per second) KVM . . . navidezna naprava na podlagi jedra (angl. Kernel-based virtual machine) LTS . . . . dolgoročna podpora (angl. long term support) LXC . . . . Linux vsebnik (angl. Linux container) MB . . . . megabajt (angl. megabyte) PaaS . . . . računalniško okolje kot storitev (angl. platform as a service) PHP . . . . splošno uporaben skriptni programski jezik (angl. hypertext preprocessor) PID . . . . identifikator procesa (angl. process ID) PSPN . . . matrika prednosti, slabosti, priložnosti in nevarnosti (angl. SWOT) QEMU . . različica hipervizorja (angl. Quick Emulator hypervizor) RHEL . . . različica Linux distribucije (angl. Red Hat Enterprise Linux) RPM . . . sistem za upravljanje sistemskih paketov (angl. Red Hat package manager; recursive initialism) RTE . . . . izvajalno okolje (angl. run-time environment) SDN . . . . programsko definirano omrežje (angl. software defined netowrking) SSH . . . . varna lupina (angl. secure shell) SSL . . . . sloj varnih vtičnic (angl. secure socket layer) STDIN . . standardni vhod (angl. standard input) SWOT . . PSPN-analiza (angl. strengths, weaknesses, opportunities and threats matrix) TCP . . . . povezavni protokol transportnega sloja v protokolnem skladu TCP/IP (angl. transmission control protocol) TTL . . . . življenjska doba (angl. time-to-live) UID . . . . identifikator uporabnika (angl. user identifier) VM . . . . navidezna naprava (angl. virtual machine) VMM . . . hipervizor (angl. virtual machine monitor) VPN . . . . navidezno zasebno omrežje (angl. navidezno zasebno omrežje) Priloga 2: LXC-predloga za storitev sshd #!/bin/bash # # lxc: linux Container library # Authors: # Daniel Lezcano <daniel.lezcano@free.fr> # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA install_sshd() { rootfs=$1 tree="\ $rootfs/var/run/sshd \ $rootfs/var/empty/sshd \ $rootfs/var/lib/empty/sshd \ $rootfs/etc/ssh \ $rootfs/dev/shm \ $rootfs/run/shm \ $rootfs/proc \ $rootfs/bin \ $rootfs/sbin \ $rootfs/usr \ $rootfs/tmp \ $rootfs/home \ $rootfs/root \ $rootfs/lib \ $rootfs/lib64" mkdir -p $tree if [ $? -ne 0 ]; then return 1 fi return 0 } configure_sshd() { rootfs=$1 cat <<EOF > $rootfs/etc/passwd root:x:0:0:root:/root:/bin/bash sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin EOF cat <<EOF > $rootfs/etc/group root:x:0:root sshd:x:74: EOF ssh-keygen -t rsa -f $rootfs/etc/ssh/ssh_host_rsa_key ssh-keygen -t dsa -f $rootfs/etc/ssh/ssh_host_dsa_key # by default setup root password with no password cat <<EOF > $rootfs/etc/ssh/sshd_config Port 22 Protocol 2 HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_dsa_key UsePrivilegeSeparation yes KeyRegenerationInterval 3600 ServerKeyBits 768 SyslogFacility AUTH LogLevel INFO LoginGraceTime 120 PermitRootLogin yes StrictModes yes RSAAuthentication yes PubkeyAuthentication yes IgnoreRhosts yes RhostsRSAAuthentication no HostbasedAuthentication no PermitEmptyPasswords yes ChallengeResponseAuthentication no EOF return 0 } copy_configuration() { path=$1 rootfs=$2 name=$3 cat <<EOF >> $path/config lxc.utsname = $name lxc.pts = 1024 lxc.rootfs = $rootfs lxc.mount.entry=/dev $rootfs/dev none ro,bind 0 0 lxc.mount.entry=/lib $rootfs/lib none ro,bind 0 0 lxc.mount.entry=/bin $rootfs/bin none ro,bind 0 0 lxc.mount.entry=/usr /$rootfs/usr none ro,bind 0 0 lxc.mount.entry=/sbin $rootfs/sbin none ro,bind 0 0 lxc.mount.entry=tmpfs $rootfs/var/run/sshd tmpfs mode=0644 0 0 lxc.mount.entry=@LXCTEMPLATEDIR@/lxc-sshd $rootfs/sbin/init none bind 0 0 EOF if [ "$(uname -m)" = "x86_64" ]; then cat <<EOF >> $path/config lxc.mount.entry=/lib64 $rootfs/lib64 none ro,bind 0 0 EOF fi } usage() { cat <<EOF $1 -h|--help -p|--path=<path> EOF return 0 } options=$(getopt -o hp:n: -l help,path:,name: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" while true do case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; -n|--name) name=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done if [ "$(id -u)" != "0" ]; then echo "This script should be run as ’root’" exit 1 fi if [ $0 == "/sbin/init" ]; then type @LXCINITDIR@/lxc-init if [ $? -ne 0 ]; then echo "’lxc-init is not accessible on the system" exit 1 fi type sshd if [ $? -ne 0 ]; then echo "’sshd’ is not accessible on the system " exit 1 fi exec @LXCINITDIR@/lxc-init -- /usr/sbin/sshd exit 1 fi if [ -z "$path" ]; then echo "’path’ parameter is required" exit 1 fi rootfs=$path/rootfs install_sshd $rootfs if [ $? -ne 0 ]; then echo "failed to install sshd’s rootfs" exit 1 fi configure_sshd $rootfs if [ $? -ne 0 ]; then echo "failed to configure sshd template" exit 1 fi copy_configuration $path $rootfs $name if [ $? -ne 0 ]; then echo "failed to write configuration file" exit 1 fi
© Copyright 2024