Bevezetés a konténertechnológiába

A konténer technológia az elmúlt években a számítástechnika egyik legjelentősebb fejezetévé vált, sajátos megoldást nyújtva az elosztott rendszerek hibatűrő működésére, valamint az informatikai és az üzemeltetési biztonság javítására. A konténertechnológia egyik legnagyobb előnye, hogy lehetővé teszi az alkalmazások és függőségeik egy elkülönített, hordozható környezetben történő futtatását. Erre alapozva biztosítható, hogy a fejlesztési, a tesztelési és az éles (ún. production) környezetek között ne legyen eltérés, így elkerülhetővé válnak a „de nálam ez működik” típusú problémák. A konténerek gyorsan indíthatók és alapjában véve kis erőforrásigényűek, ami megkönnyíti az alkalmazások telepítését és skálázását úgy, hogy a rendszergazdáknak mit sem kell tudniuk azok belső működéséről. Bár a kiszolgálókon működő alkalmazások működtethetők a hagyományos módon is, és ez minden bizonnyal még évekig így lesz, egy fiatal programozó, programtervező előbb-utóbb minden bizonnyal találkozik azokkal az igényekkel, amelyeket igazán hatékonyan csak konténerek segítségével lehet megoldani. A fejlesztőkkel szemben egyre gyakoribb elvárás a technológia ismerete, és előnyt élveznek azok, akik képesek egy konténerben futó alkalmazás megtervezésére és elkészítésére. Ez a jegyzet ehhez nyújt segítséget.

Ebben a fejezeteben megismerjük:

  • A konténerizáció fogalmát, alapelveit és technikáit.

  • A mikroszervizek fogalmát és implementációját.

  • Egy konténerekre alapozott hibatűrő rendszerek felépítését.

  • Néhány biztonsági megfontolást és sebezhetőség-kezelést a konténerekben.

  • A konténerekre alapozott fejlesztési és telepítési folyamatok automatizálásának folyamatát.

  • A technológia előnyeit és hátrányait.

Szükséges eszközök:

Nincsenek.

Feldolgozási idő:

kb. 30 perc.

A számítógépek programozásának korai szakaszában a szoftverfejlesztők az alkalmazásaikat kifejezetten egy adott operációs rendszert futtató fizikai gépre tervezték. Az egyes szoftverek közös felhasználói térben futottak, a multitasking rendszerekben megosztották egymással az operációs rendszer könyvtárait és a fizikai gép erőforrásait. Szó sem lehetett arról, hogy egy szoftver ne azon az operációs rendszeren vagy hardver architektúrán működjön, amelyre azt eredetileg tervezték. Ezt a működési modellt az alábbi ábra szemlélteti:

Tradicionális programfuttatási környezet

Tradicionális programfuttatási környezet

Idővel a fizikai gépeket virtuális gépek váltották fel, melyek nagyszerű lehetőséget biztosítottak arra, hogy egy fizikai hardveren különböző virtuális gépeket alakítsunk ki, és azon futtassuk az egyes szoftvereket vagy komplex rendszereket. Egy virtuális számítógép virtuális operációs rendszert működtet – ez ideális olyan nagy és összetett rendszerek esetében, mint az egyetemek Neptun programja, vagy egy komplex termelésirányítási rendszer és még sorolhatnánk. A magas komplexitású, rendkívül összetett szoftverek így önálló operációs rendszeren futhatnak, és mivel más szoftvert ezekre már nemigen szokás telepíteni, annak teljes működését a szoftver igényei szerint lehet beállítani.

Virtuális gépek működési környezete

A virtuális gépek működési modellje

A virtuális gépeket működtetésére kifejlesztett megoldást szerver szintű virtualizációként szokás említeni, mivel a virtualizáció tárgya ebben az esetben a teljes gép és annak operációs rendszere, amelyeken tipikusan kiszolgálókat működtetnek. Ugyanakkor a kis kapacitás- és erőforrásigényű alkalmazások számára nem célszerű ezt a megoldást választani, hiszen a virtuális gép operációs rendszere egy teljes alap infrastruktúrát igényel, szükségszerűen futtatja a rendszermagot, emellett számos, az operációs rendszerhez tartozó egyéb szoftvert tartalmaz a rendszerkönyvtáraktól a beépített alkalmazásokig. A szerver virtualizáció ezért pl. egy egyszerű API-t implementáló megoldás működtetésére egy rendkívül pazarló megoldás lenne, ezért esetükben egy más természetű megoldást célszerű használni. Ez az alkalmazás virtualizáció vagy más néven konténerizáció, amely csak egy alkalmazás számára szükséges szoftver környezetet virtualizálja, azok számára az alap operációs rendszeren működő, de attól elszeparált és testre szabott környezetet biztosít. Számos ilyen megoldás létezik, az egyik legismertebb változata a Docker, amely a konténerizációhoz kapcsolódó környezet kezelését rendkívül átgondoltan valósítja meg.

A konténerek kisebb alkalmazások esetén mára majdnem teljes egészében átvették a virtuális gépek szerepét. Használatukkal a fejlesztők az alkalmazásaikat az elvárt és egyedi önálló környezetével együtt csomagolhatják egységbe. Bár a virtuális gépekkel szemben konténerek kevésbé rugalmasak, mivel a az őket futtató operációs rendszerre alapozva működnek, egyes területeken sokkal jobb alternatívát jelentenek. A konténerizáció során alkalmazott operációs rendszer közös az alkalmazás virtualizációt futtató operációs rendszerrel, amelyben az alkalmazások a virtuális környezetben ún. mikroszervizekként futnak. Ezek a legtöbb esetben tartalmazzák az alkalmazást, annak adatait és a működéshez szükséges futtató környezetet is annak minden beállításával együtt. Egy webalkalmazás esetén ilyen a webszerver, az alkalmazáshoz tartozó adatbázis-szerver vagy pl. a PHP értelmező.

Ebben a kontextusban a virtualizált környezet neve konténer, amelyek tehát egymástól és az operációs rendszertől is elszeparálva működnek. Összetettebb feladat megoldására egymással együttműködő konténercsoportok is létrehozhatók, amelyek saját belső hálózati kapcsolatokkal, elkülönített névtérrel is rendelkeznek. Ennek tipikus példája lehet egy olyan környezet, amelyben a webszervert, a PHP motort és az adatbáziskezelő-rendszert három önálló, de egy nagyobb egységként kezelt konténer alkotja.

A konténerek jelentősége többek között abban is rejlik, hogy függetlenek az őket futtató operációs rendszertől, az arra telepített programoktól és a komponensek verziószámától. A konténerek felépítését különféle szabályok határozzák meg, amelyek biztosítják az operációs rendszertől való függetlenségüket.

A konténerizáció alkalmazása számos más előnyt is biztosít. Amellett, hogy a kis alkalmazások felhőszolgáltatók infrastruktúráján történő futtatásának (Aws, Google Cloud, MS Azure stb.) tipikus technológiája, erre alapozva aránylag egyszerűen lehet hibatűrő, ún. HA (High Availability) rendszereket felépíteni. Egy ilyen komplex rendszer esetén a konténerek több példányban, több szerverre elosztva redundáns módon működnek, így egyes elemeik kiesése esetén a teljes rendszer még képes lehet ellátni a feladatát. Újabb előnyt jelent, hogy a konténerekben alkalmazott szoftverek verziója állandó, beállításaik csak a konténer belsejében érvényesek, így elkerülhetők a fejlesztés és a publikált végterméket futtató szerverek környezetének különbségei – a fejlesztés során alkalmazott környezet a konténerbe lesz „becsomagolva”, így az pontosan meg fog egyezni a végleges változatban működővel akkor is, ha annak idővel újabb változata jelent már meg.

Konténerek előnyei és hátrányai

A konténertechnológia tehát lehetővé teszi, hogy az azokban futó alkalmazások a környezetüktől elszeparálva, attól jórészt függetlenül működhessenek.

A konténertechnológiának azonban más előnyei is vannak, egy ilyen a hordozhatóság. Mivel minden konténerbe zárt alkalmazás magával hordozza a működéséhez szükséges függőségeket, működésük nem függ más rendszerszoftverekétől, amelyek egy adott környezeteben nem, esetleg azok eltérő, inkompatibilis verziója áll rendelkezésre. Ezt a helyzetet a webprogramozók számára a talán egyik leginkább problémás területtel, a LAMP webfejlesztési környezettel lehet szemléltetni.

A LAMP egy meglehetősen népszerű fejlesztési környezet, amely a nevét dinamikus website-ok felépítése során megkövetelt szoftverek (Linux, Apache, MySQL/MariaDB, PHP) kezdőbetűiről kapta. A szükséges komponensek nem csak Linux, hanem Windows és MacOS környezetben is külön-külön is telepíthetők, ugyanakkor Windowsra elérhető egy XAMPP nevű komplex csomag, amely ezeket együttesen tartalmazza. A webalkalmazások kifejlesztése során problémát okozhat, hogy az egyes komponensek eltérő verziói jelentős különbségeket tartalmaznak, ami különösen a PHP esetében szembetűnő: az eltérő verziók nem garantálják a visszamenőleges kompatibilitást. Így (a rendszergazdák legnagyobb örömére) egy esetleges rendszerfrissítés során a korábban működő webalkalmazások már hibásan vagy egyáltalán nem működnek.

Ezért az alkalmazásokat üzemeltető rendszergazdák a rendelkezésre állás fenntartása érdekében abban érdekeltek, hogy ne végeznek nagyobb verziófrissítést, így rendszereik előbb-utóbb elavulttá válnak. A verziók „befagyasztásának” kényszere okozza az üzemeltetők egyik legnagyobb problémáját, mivel így kénytelenek olyan elavult szoftvereket is működtetni, amelyek jelenléte nem csak a webalkalmazás, hanem a teljes kiszolgáló biztonságát is veszélyeztetik. Gyakori, hogy az elavult webalkalmazások fejlesztői már nem állnak rendelkezésre, vagy a megoldást a rendszer teljes újraírásában látják, a tulajdonosok pedig nem vállalják ennek költségeit. E lánc végén a szerver üzemeltetők állnak, akik az alkalmazások működőképességét a frissítést követően nem tudják garantálni, emiatt a rendszereiket nem frissítik, így elavult állapotban tartják.

A verziók változásai miatt bekövetkező inkompatibilitás a webfejlesztők számára is előnytelen. A megrendelők elvárják a szoftverek működőképességének megtartását, ezért a szerverszoftverek frissítésével előálló inkompatibilitás konfliktushelyzetet szül: az üzemeltetők a biztonság fenntartása mellett érvelve nem akarják az elavult környezetet hosszú távon fenntartani, a fejlesztők pedig nem szeretnének további fejlesztéseket örök életükre további díjazás nélkül végezni, a webalkalmazás tulajdonosai pedig elvárják, hogy „ami tegnap működött, az ma is működjön”. A webfejlesztőket további kompatibilitási problémák is terhelik: esetenként a webszerver és az adatbáziskezelő rendszerek speciális beállításai szükségesek ahhoz, hogy az alkalmazásaik helyesen működhessenek. Ilyenek pl. a webszerver működését befolyásoló, rendszerszintű .htaccess fájlok, vagy pl. a kis- és nagybetűk megkülönböztetésére szolgáló beállítások az adatbáziskezelőben.

A konténertechnológia alkalmazása kiváló lehetőséget nyújt a felsorolt problémák megoldására. A szeparációs képesség lehetővé teszi, hogy az elkészült webalkalmazások pontosan azt a konténerbe zárt PHP verziót használják, amire az adott szoftvert kifejlesztették és tesztelték úgy, hogy közben az üzemeltetők a kiszolgáló szerver egyéb komponenseit rendszeresen frissíthetik. Az alkalmazás környezete egy „konténerképes” fejlesztő esetén azonosak lesznek a fejlesztés során alkalmazottal, így a hibáinak javítása is független a kiszolgálótól, azok orvoslása a fejlesztő feladatkörébe tartozik. Amennyiben már a fejlesztés is konténerizált környezetben történt, a szoftver működéséhez szükséges minden beállítást is a fejlesztő végez el – ebben az esetben az elkészült konténer garantáltan úgy fut majd az éles környezetben, ahogyan az a fejlesztő gépén működött.

A konténerek használatával a fejlesztő megszabadulhat a bonyolult és szintén egyedi konfigurációval rendelkező XAMPP rendszertől. Nem csak egy mySql konténer indítható szinte másodpercek alatt, hanem szinte bármely más adatbáziskezelő rendszer is. Egy Python Flask alkalmazás futtatási környezetének kialakítása, amely alapjában véve még önálló webszervert sem igényel, szintén másodpercek alatt alakítható ki, vagy upgrade-elhető az elvárt változatra.

A konténerek alkalmazásának további nagy előnye a biztonság javítása. A konténerek elzárt környezetben futnak, esetleges sérülékenységük főként saját magukra van kihatással, az őket futtató környezetre csak adott esetben lehetnek következményei. Egy sérülékeny konténer a teljes kiszolgálóra nézve csak abban az esetben jelent kockázatot, ha egy támadó ki tud abból törni pl. úgy, ahogyan a Biztonsági kérdések c. fejezet példájában láthatjuk majd. Amennyiben kifejlesztett szoftverrel vagy az abban felhasznált komponensekkel kapcsolatban valamilyen sebezhetőség kerül nyilvánosságra, a konténerek a javított szoftver komponensekkel egyszerűen újraépíthetők, és a változások hatása csak az általuk használt elszeparált környezetben érvényesül. A konténerek létrehozásához szükséges image-ek pedig szükség esetén digitálisan aláírhatók, így eredetiségük még a felhasználásuk előtt ellenőrizhető, ami nagyban csökkenti a hamisított vagy malware-rel preparált konténerek bekerülését egy rendszerbe.

A konténerek a fejlesztési folyamatok felgyorsításában is segítséget jelentenek. Alkalmazásukkal a tesztelést végző munkatársak számítógépein sem kell kialakítani a fejlesztési környezetet, egy komplex alkalmazás pusztán egyetlen parancs végrehajtásával, annak minden összetevőjével együtt telepíthető. Gondoljunk csak megint egy LAMP környezet telepítésére, és egy webalkalmazás beállítására, ami a fejlesztők számára sem feltétlenül triviális feladat. A konténerek alkalmazásával a környezet kialakítása és beállítása a fejlesztő feladata, ezeket a konténer magával hordozza, feleslegessé téve az utólagos hangolási feladatokat.

Összefoglalás

A konténertechnológia tehát számos előnyt kínál mind a programozók, mind a rendszergazdák számára. A fejlesztők számára a legnagyobb előny a hordozhatóság, mivel a konténerek biztosítják, hogy az alkalmazás ugyanabban a környezetben azonos módon fut, megszüntetve az inkompatibilitásból és eltérő rendszer beállításból származó problémákat. A technológia alkalmazása jelentősen megkönnyíti a fejlesztési és a tesztelési folyamatokat, mivel a konténerizált alkalmazások könnyen működtethetők eltérő rendszerkörnyezetekben is. A rendszergazdák számára a konténerek az alkalmazások egyszerű telepítését, skálázását és az igénybe vehető erőforrások könnyű korlátozását kínálja. A konténerek elzárt működése emeli a biztonság szintjét is, mivel az esetleges sérülékenységek az esetek túlnyomó többségében csak az adott konténerre vannak hatással. Végül, a konténertechnológia lehetővé teszi a redundáns, hibatűrő rendszerek tervezését és építését, növelve a megbízhatóságot és rendelkezésre állást.

Kérdések, feladatok

  1. Magyarázd el, hogy mi a konténer és mi a Docker!

  2. Mi a mikroservice?

  3. Mit jelent a HA rövidítés?

  4. Hogyan épül fel egy konténerizált szoftver környezet?

  5. Milyen előnyei vannak és milyen feladatok megoldásakor előnyös a konténerek használata?

  6. Hogyan segíti a konténerek használata a hordozhatóságot és környezetfüggetlenséget?

  7. Mikor nem javasolt a konténerek használata?

  8. Mi a különbség az alkalmazás virtualizáció és a szerver virtualizáció közt? Milyen esetben előnyös az egyik vagy másik alkalmazása?

  9. Szükség esetén hogyan lehet ellenőrizni egy Docker konténer eredetiségét?

  10. Milyen hatással van a konténerizáció egy rendszer teljes egészének biztonságára?

  11. Konténerizálhatók az elterjedt ingyenes adatbáziskezelő-rendszerek, pl. a mySQL vagy a PostgreSQL?

  12. Hogy hívják és miben különbözik a Dockertől a Redhat konténerizációs rendszere? Biztonsági szempontból mi a legfőbb különbség a Redhat megoldása és a Docker között?