fbpx

Hagyma, Zsír, Krumpli, Docker – konyhanyelven a konténerizációról

Mire jó a konténerizáció, és hogyan húzhatsz fel fejlesztői környezetet egyetlen POCO parancs segítségével? Morvai Gábor röviden végigvezet a Docker konténereket életre hívó kihívások, a DevOps és a hagyományos fejlesztői munkát elválasztó falak lebontásán.

Mi az a Docker, régen csak rocker volt?!

Nagyon röviden a Docker egy program neve, ami virtualizációt csinál. A virtualizáció meg azt jelenti, hogy a programok számára olyan lesz mintha valami lenne, de ez a valami nem a megszokott “feltelepítettem az adatbázist” jellegű. Itt az adatbázis, az csak példaként szerepel. Gondolj bátran bármilyen szoftverre. Képzeld csak el, milyen lenne, ha soha többé nem kellene Office programot telepítened. Vagy képzeld csak el, hogy nem kell telepítened a böngészőt, és mégis használhatsz Firefoxot, Chrome-ot telepítés nélkül. Szóval – az előző példával élve – lesz egy adatbázisod, de nem kellett telepíteni, így igazából a “Program Files” mappában sem fogod megtalálni.

Hogy mi van? Most akkor van adatbázis, vagy nincs?

Van is, meg nincs is. A legtöbben Windows rendszerrel kezdtük a magyar oktatás sajátosságai miatt. Ennél is régebben még DOS-al is kezdhetett az ember, de a lényeg az, hogy szinte az anyatejjel együtt szívtuk magunkba a Microsoft termékei mellett a cég filozófiáját is. Ezen azt értem, hogy ha használni szeretnél egy programot, akkor feltelepíted, és kész. Ezt a telepítési folyamatot a különböző varázslók nagyon könnyűvé és egyszerűvé tették. Ismeritek a mondást: next-next-next-finish, ahogy a képen is látható.

konténerizáció blogcikk1

Ezen a helyzeten módosítottak a portable programok. Ez szó szerinti fordításban hordozható programot jelent, azaz olyat, ami telepítés nélkül is működőképes. Tehát mondjuk USB sticken hurcolhatod magaddal, és bárhol, bármilyen számítógépen használhatod. Persze megkötés, hogy csak ugyanolyan operációs rendszerrel működik, tehát egy windows portable program csak windowson fog működni.  Ez nagy könnyítés abból a szempontból, hogy nem szemetelik össze a rendszerleíró adatbázist (registry), aminek a telefirkálása gyakran párosul a rendszer lassulásával.

Egy kis kitérő a registryvel kapcsolatban. Ez ismét csak egy példa, ami azt szemlélteti, hogy a telepítős alkalmazások telepítés közben módosítanak dolgokat a számítógépen. Tehát nem csak egy xy.exe fájlt fog kicsomagolni, hanem mappákat hoz létre, különböző helyekre fájlokat rak le, és a már említett windowsos rendszerleíró adatbázist is módosítja. A lényeg az, hogy olyan sok változást hajthat végre egy-egy telepítő, ami után már lehet, hogy nem fog jól működni a számítógép.

A klasszikusan nagyobb alkalmazások – mint az említett adatbázis – azonban nem minden esetben érhetőek el portable formában. A helyzetet még cifrázza, hogy most Windowsról van szó, de ne felejtsük el, hogy asztali gépek és laptopok esetén is nagyon megerősödtek az egyéb oprendszerek: mac/linux -, és ez szerverkörnyezetben különösen igaz. Erre a problémára (azaz különböző platformokon is működjön ugyanaz a szoftver) kellett megoldást találni és el is érkeztünk a virtualizációhoz. Ennek a klasszikus példája a Virtualbox, amikor is egy teljes értékű oprendszert teszel fel egy dobozba. Egy virtuális dobozba. Ezt a dobozt kinyithatod, becsukhatod, kidobhatod, újrahúzhatod, bármit csinálhatsz vele. A dobozból nem jönnek ki a bajok (vírusok, elromlott registry, akármi) normál esetben. Ide azt telepíthetsz, amit csak akarsz. Csakhogy – mivel teljes értékű oprendszerről van szó, ezért egy-egy ilyen doboz meglehetősen nagy méretű. Nem is kicsit, több gigás  méretre kell gondolni. Ezért tovább kellett menni a fejlődésben. De mielőtt továbbmennénk: itt már látható, hogy megoldható, hogy az említett adatbázis (ne feledjétek, ezen bármilyen szoftvert lehet érteni) egy ilyen virtualizált környezetbe legyen telepítve, miközben a host gépre nincsen, de mégis használható onnan. Így kell érteni, hogy van is, meg nincs is.

A microservice dolog, az vajon mi? Kell ezzel foglalkoznom? Hogy kapcsolódik ide?

Régen kisebb hardverek voltak, ennek megfelelően kisebb programok. Ezeket könnyű volt átlátni, üzemeltetni. Ahogy nagyobbak lettek gépek, az igények és a kódok, úgy nőtt a rendszerek komplexitása. Logikus irány volt, hogy egy-egy szolgáltatást szétbontsunk, és akár külön gépre is tesszük. Végül eljutottunk oda a fejlődésben, hogy egy-egy szolgáltatás már annyira kicsi lett, hogy be is vezettük a microservice fogalmát. Na és itt kapcsolódik, hogy kinek van annyi különálló számítógépe, ami egy nagyobb rendszer összes szolgáltatását elérhetővé teszi? Ez még egy szerverparkban elmegy, no de mi a helyzet a lokális fejlesztői környezettel? Amint ez a probléma szembejött (na meg a fent emlitett “több platformon, Linuxon, Macen, Windowson is legyen elérhető ugyanaz a szoftver”), akkor fordult mindenki a virtualizáció irányába. Szóval a kérdésre a válasz az, hogy közvetlenül nem kell vele foglalkoznunk, de a konténerizáció kialakulásában ez is okként szerepel.

És akkor miben több a Docker mint a Virtualbox?

Valójában nem több, hanem kevesebb, másabb. Ez azt jelenti, hogy ő úgy teremt virtualizált környezetet, hogy eközben nem szeretné a teljes értékű operációs rendszer látszatát kelteni. Nagyon lényeges funkciók hiányoznak belőle, ami egy oprendszertől azért elvárható lenne. Hogy szélsőséges példát mondjak: nincs nvidia grafikus kártya driver benne – amit amúgy egy oprendszertől elvárnánk, mert hát minek? Csak egy programot akarok benne futtatni, nem akarom hogy külön monitorbeállitásai legyenek :) És nem utolsó sorban, mivel kevesebb szolgáltatása van ennek a rendszernek, mint egy teljes értékű operációs rendszernek, ezért kisebb a sebezhetőségi felülete is. Biztos ismeritek a mondást: kevesebb kódban kevesebb hiba.

Mi az a konténer?

konténerizáció blogcikk2

Majdnem olyan, mint a való életből vett konténer. Olyasmi, amiből irodát is lehet kialakítani, de őrölt kávét is lehet benne szállítani. Éppen ebben van a hasonlat alapja, miszerint a konténer kívülről egyforma (talán a színe más, de tök standard a méretezése) miközben belülről lehet teljesen custom. Nem olyan új a gondolat, elég csak a Windows 3.x-es koncepcióra gondolni: ha megtanulsz egy szoftvert, például a Word használatát, akkor könnyedén megtanulhatod az Excel használatát is. Ezt úgy érték el, hogy nagyon hasonló mindkét esetben a felület, a menüstruktúra, és az alapműveletek. Ugyanúgy kell új dokumentumot megnyitni, bezárni, vágólapot kezelni, stb. A konténerek ennél is kicsit tovább mennek: nem elég, hogy teljesen standard a felülete (egyformán indítható el, állítható le, ugyanúgy lehet belépni, stb.), de bezártságot is ad. Alapesetben nem jön ki a konténerből semmi. Alapértelmezésben internet irányba lát a konténer, befelé, a konténer által indított szolgáltatásokból nem látszik semmi. Ezeket szándékosan ki kell ajánlani a hostgépre, azaz a Docker konténert futtató gépre. Ehhez hasonlóan a merevlemez tartalmához sem fér hozzá a konténer. Ezt is külön jeleznünk kell a konténer indításakor, hogy melyik mappákat szeretnénk hogy a konténer elérje, vagy melyiket tudja módosítani (volume mapping). Szóval alaphelyzetben egy lezárt dobozt, egy zárt konténert kapunk. Amikor szeretnénk interakcióba lépni egy konténerrel, akkor ezt kifejezetten jeleznünk kell az indításakor.

Már nagyon sok a történelem, ma mi a helyzet?

Ma úgy gondoljuk, hogy többé nincs szükség hagyományos programok telepítésére úgy, ahogy azt korábban megtanultuk windows-os rendszereken. Ehelyett becsomagoljuk a feltelepítendő programot egy konténerbe, és ezt a konténert indítjuk el, állítjuk le, kezeljük – és nem utolsó sorban használjuk. Ez azért lesz jó, mert nagyon egyszerű lesz a helyzet olyankor, amikor egyik alkalmazásunk 5.0-s, másik 5.5-ös, harmadik meg 5.7-es mysql-el kompatibilis. Csak annyi a dolgunk, hogy 3 különböző Docker parancsot adjunk ki ahelyett, hogy sorra telepítenénk Windows szervizeket. Sőt, akik szemfülesek, azok saját konténert sem gyakran gyártanak, hanem mások által készítetteket használnak. Ilyen kész konténereket lehet találni szép számmal a Dockerhub-on is, ami a Docker konténerek hivatalos tárháza.

Ó, hát ez nagyszerű, akkor mindent így csináljunk!

Lassan a testtel! A Microsoft és a Docker nincsenek annyira jó viszonyban. Ez gyakorlatban azt jelenti, hogy vannak ugyan MS szolgáltatások, amik tudnak Dockerben futni, de ezek nagyok, akár több gigabyte-osak is lehetnek. Másik oldalról ma a Windows oprendszer a host gépen okoz néha izgalmas perceket. Windowsból Dockert futtatni nem lehetetlen, de vannak benne problémás dolgok. Nem egyszerű, tényleg. A legkönnyebb Linuxon, mert ott kernel szinten támogatott a történet. Aztán Mac-en sem olyan rossz, néha van, amit meg kell oldani, de nem rossz. Windowson sokkal gyakrabban fordul elő anomália, és egy jól belőtt rendszer frissítés után elhalálozhat. De ha a holdállás is úgy akarja, képes működni, és az kárpótol minden szenvedésért.

Hallottam, hogy POCO, ez mi?

A Docker konténerek önmagukban nagyon jó izoláltságot biztosítanak, és az előbb példaként emlitett 3 adatbázis akár egy időben is tud futni (persze nem ajánljuk ki a portokat ugyanarra a címre, hogy ne legyen ütközés). De ha azt szeretnénk, hogy ezek a konténerek beszélgessenek egymással, akkor már macerás a helyzet. Nagyon sok és hosszú command line-os parancsot kell begépelnünk – tehát könnyű hibázni. Erre találták ki a Docker Compose-t. Ez nagyon könnyűvé teszi a konténerek közti hálózatok kialakítását. Elég megadni hogy links, és már össze is van kötve a két konténer, úgy hogy tudnak egymással beszélgetni, de mégsem kell a host gép portjaira kiajánlani dolgokat. Ezzel azt lehet elérni, hogy mindhárom adatbázis 3306-os porton fut, ami nincs kiajánlva a host gépre. És ha van mondjuk a példa kedvéért egy PHP-s konténer, akkor az a 3 adatbázishoz könnyedén tud majd szolgáltatásnév alapon csatlakozni. A portok olyan kapuk a számítógépen (vagy jelen esetben a konténeren), ahol egy szolgáltatás adatot cserélhet egy másik számítógéppel. Egy-egy ilyen szolgáltatást dockeres környezetben el is nevezhetünk, és azután már ezzel a könnyen megjegyezhető névvel, szolgáltatásnévvel elég rá hivatkozni, nem szükséges IP cimekkel zsonglőrködni.

A POCO a projektek komponálásában nyújt segítséget. Olyan, mint a hagyma: réteges. Legbelül található a Docker, ami a virtualizációt és az izolációt adja nekünk. Erre épül a Docker Compose, ami a konténerek közötti kapcsolódást teszi nagyon könnyűvé nekünk. És ezen kívül, erre épülve van a POCO, ami egy konténer halmazt projektként lát, és projekt szintű műveletekkel támogat minket. Egy projektet egyetlen (rövid és egyszerű, projektről projektre hasonló felépítésű!) paranccsal el tudd indítani különböző módokon például lokális frontend fejlesztéshez, vagy buildeléshez, vagy lokális backend fejlesztéshez, vagy bármi máshoz. A módok (plan-ek) azért vannak, mert azt vettük észre, hogy egy Java fejlesztő tök máshogy használja ugyanazt a kódbázist, mint egy frontend fejlesztő. De még ezen belül is megoszlik, hogy ki melyik szervizeket használja fejlesztés közben. Alapesetben, ha a default plan megfelel számodra, és épp a project mappájában állsz, akkor elég egy nagyon standardizált poco up parancs, ami után elérhetővé válnak azok a szolgáltatások, amiket külön-külön telepíteni, vagy beállítgatni napokba telt volna.

Csak ennyi?

Ha van két különböző projekt, akkor POCO-val nagyon hasonló lesz az indítása akkor is, ha gyökeresen más szervizeket használunk. Például az egyik projektnél adatbázist, elosztott cache-t, message queue-t és PHP-t használunk, az is ugyanúgy “poco up projectnév/plan” módon indul, mint az amelyik 3 Java-s alkalmazást használ, amik soap-on kommunikálnak egymással. Íme egy példa: https://github.com/shiwaforce/poco-example-nnmp Ebben az mutatom be, hogy úgy tudsz phpmyadmin felületet használni úgy, hogy sosem volt php a gépeden. De így van ez a többi komponenssel is: nem kell a projektben szereplő szolgáltatásokat telepíteni. Más gépen, más operációs rendszerrel ugyanezt a full stack fejlesztői környezetet beállítani pontosan ugyanennyi: poco up

Ahhoz, hogy könnyen ki tudd próbálni a saját fejlesztésed integráltan, egy olyan környezetben, ami kísértetiesen hasonlít az éles környezethez, ehhez ideális választás a POCO. Maga a kipróbálás fontosságát nem kell ecsetelnem: elég rossz vakon fejleszteni, nem is beszélve arról, hogy ha ehhez még jön olyan várakozás, hogy a javítást ki is kell telepíteni egy adott környezetre, hogy ki tudjuk próbálni… nos ezek a várakozási idők igazán rombolják a kreativitást. Az integrált fejlesztés azt teszi lehetővé, hogy amikor kattintasz a felületen, akkor valójában ténylegesen az összes érintett rendszer dolgozni fog a gépeden, nem pedig mock adatokkal operálunk. Ezzel gyakorlatilag minden fejlesztő egyben teszteli is az alkalmazást. Nem kell megvárni az élesbe állást, hogy kiderüljön: baj van. Sőt, ez már a fejlesztés készítése közben kiderül, amikor a lehető legkönnyebb, legidőtakarékosabb javítani. Az pedig, hogy olyan környezeten fejlesszünk lokálisan, mint amilyen majd az éles is lesz, eleve kizárja az olyan hibákat, melyekben elhangzik az ismert ultimate érv: “de hiszen nálam működött”.

Ez most akkor üzemeltetés, DevOps, vagy fejlesztés?

A válasz nem egyszerű. Úgy teszi egyszerűvé az fejlesztést, hogy kicsit üzemeltetni kell. És úgy teszi egyszerűvé az üzemeltetést, hogy kicsit fejleszteni kell. Röviden kicsit megbontja a “csak DevOps” és a “csak fejlesztő” beállítottságú kollégák közötti falat. Ahhoz, hogy jól működjön a projekt, érdemes tisztában lenni a szolgáltatás, port, konténer, http, ip és kapcsolódó fogalmakkal – de nem kell ezekkel érdemben beállítást csinálni. Ugyanígy DevOps – vagy inkább SecDevOps oldalról már az az igény, hogy minél kisebb legyen a támadható felület – ezt is alapból nyújtja a technológia, anélkül, hogy tűzfal-szabályokkal, vagy kódban lévő biztonsági megoldásokkal kellene vacakolni.

Ezek az újítások nem invalidálják a régi bevált megoldásokat, csak egyszerűsítik. Egy olyan gépen, ahol a projekt még nem futott, ott egy többkomponenses projekt beüzemelése minden érintett komponenssel együtt pár percre redukálódik, amit egyetlen paranccsal indítunk, és a futás közben pedig kávézhatunk is. Szemben a korábbi “mindent feltelepíteni, beállítani, importálni, stb” dologgal, ami órákat és nagy odafigyelést igényel. Mindenképp érdemes tehát haladni a korral, és elindulni ebbe az irányba. Tapasztalatainkról többször is hallhattatok már a DevTales nevű podcast műsoraiban is, ahol kollégák élő projektjeire épülő benyomásaikat osztották meg.