Konténer (Container) technológia magyarázata és működése

Képzeld el, hogy a szoftvereid kis dobozokba zárva utaznak, mindenük megvan, ami a működéshez kell. Ez a konténertechnológia lényege! De miért jó ez? Könnyű költözés szerverről szerverre, gyorsabb fejlesztés, és kevesebb fejfájás. Merüljünk el a konténerek világában, és nézzük meg, hogyan forradalmasítják a szoftverfejlesztést!
ITSZÓTÁR.hu
40 Min Read

A konténer technológia az alkalmazások futtatásának egy modern és hatékony módja. Lényegében egy szoftvercsomagolási és futtatási módszer, mely lehetővé teszi, hogy egy alkalmazás minden függőségével, könyvtárával és konfigurációs fájljával együtt egy elszigetelt környezetben fusson. Ezt az elszigetelt környezetet nevezzük konténernek.

A konténerek legnagyobb előnye, hogy platformfüggetlenek. Ez azt jelenti, hogy egy konténer egyszeri létrehozása után szinte bárhol futtatható, legyen az egy fejlesztői laptop, egy teszt szerver, vagy egy éles környezetben lévő felhő infrastruktúra. Ez jelentősen leegyszerűsíti az alkalmazások telepítését és karbantartását.

A konténerek működésének alapja az operációs rendszer kernelének virtualizációja. Ezzel a módszerrel a konténerek megosztják az operációs rendszer kernelét, de elkülönülnek egymástól a felhasználói térben. Ez azt eredményezi, hogy a konténerek sokkal könnyebbek és gyorsabbak, mint a hagyományos virtuális gépek (VM-ek), hiszen nem kell egy teljes operációs rendszert futtatniuk.

A konténerizáció lehetővé teszi a fejlesztők számára, hogy az alkalmazásaikat a lehető legegyszerűbben szállítsák és futtassák, miközben a rendszergazdák számára biztosítja a konzisztens és megbízható működést.

A legelterjedtebb konténer platform a Docker. A Docker egy nyílt forráskódú platform, amely lehetővé teszi a konténerek létrehozását, futtatását és kezelését. A Docker segítségével a fejlesztők könnyen létrehozhatnak Docker image-eket, amelyek az alkalmazás teljes környezetét tartalmazzák. Ezek az image-ek aztán megoszthatók és futtathatók bárhol, ahol Docker telepítve van.

A konténerek használata különösen előnyös a mikroszolgáltatás architektúrában, ahol az alkalmazások kisebb, önálló szolgáltatásokra vannak bontva. Minden egyes mikroszolgáltatás futhat egy külön konténerben, ami lehetővé teszi a független fejlesztést, telepítést és skálázást.

Mi az a konténer? Definíció és alapelvek

A konténertechnológia egy operációs rendszer szintű virtualizációs módszer, amely lehetővé teszi alkalmazások és azok függőségeinek izolált futtatását. Képzeljünk el egy dobozt, amibe bepakolunk mindent, amire egy programnak szüksége van: a kódot, a futtatókörnyezetet, a rendszerszintű eszközöket, a könyvtárakat és a konfigurációs fájlokat. Ez a doboz a konténer.

A konténerek nem emulálnak hardvert, mint a virtuális gépek (VM-ek). Ehelyett közvetlenül az operációs rendszer kerneljét használják, megosztva azt más konténerekkel. Ezáltal a konténerek sokkal könnyebbek és gyorsabban indulnak, mint a VM-ek, hiszen nincs szükségük egy teljes operációs rendszer betöltésére. A konténerek indítási ideje jellemzően néhány másodperc, míg a VM-eké percekbe telhet.

A konténerek működésének alapja az operációs rendszer által biztosított izolációs mechanizmusok, mint például a névtér (namespace) és a vezérlőcsoport (cgroup). A névterek lehetővé teszik, hogy a konténerben futó processzek saját nézetet kapjanak a rendszerről, beleértve a fájlrendszert, a hálózatot és a felhasználói azonosítókat. A vezérlőcsoportok pedig a konténerek által felhasználható erőforrások (CPU, memória, I/O) korlátozására szolgálnak.

A konténer egy standardizált egység, amely tartalmazza az alkalmazás futtatásához szükséges összes elemet, és lehetővé teszi, hogy az alkalmazás megbízhatóan fusson különböző számítástechnikai környezetekben.

A konténerizáció legfontosabb előnyei közé tartozik a hordozhatóság, a skálázhatóság és a hatékonyság. A hordozhatóság azt jelenti, hogy a konténer ugyanúgy fog futni a fejlesztői gépen, mint a tesztkörnyezetben vagy a produkciós szerveren. A skálázhatóság azt jelenti, hogy könnyen lehet több példányt indítani ugyanabból a konténerből, hogy megbirkózzunk a megnövekedett terheléssel. A hatékonyság pedig a kevesebb erőforrás-felhasználást és a gyorsabb indítási időt jelenti a virtuális gépekhez képest.

A konténerek létrehozása és kezelése általában konténerkezelő eszközökkel történik, mint például a Docker vagy a Podman. Ezek az eszközök lehetővé teszik a konténerek létrehozását, futtatását, megállítását, törlését, valamint a konténerképek létrehozását és megosztását.

A konténerképek read-only sablonok, amelyek tartalmazzák az alkalmazás és annak függőségeinek leírását. Ezek a képek a konténerek alapját képezik. A Dockerfile egy szöveges fájl, amely tartalmazza a konténerkép felépítéséhez szükséges utasításokat.

Virtuális gépek (VM) vs. Konténerek: A különbségek és előnyök

A virtuális gépek (VM-ek) és a konténerek két különböző megközelítést képviselnek az alkalmazások elkülönítésére és futtatására. Míg mindkettő célja az erőforrások hatékonyabb kihasználása, a működési elvük és a felmerülő overhead jelentősen eltér.

A virtuális gépek egy teljes operációs rendszert (vendég OS) emulálnak a fizikai hardveren. Ez azt jelenti, hogy minden VM-nek saját operációs rendszere, kernelje és alkalmazásai vannak. A virtualizációs réteg (hypervisor) felelős a hardver erőforrásainak elosztásáért a VM-ek között. Ez a megközelítés erős elkülönítést biztosít, mivel a VM-ek egymástól teljesen függetlenül működnek. Ugyanakkor jelentős overheadet is eredményez, mivel minden VM-nek futtatnia kell egy teljes operációs rendszert, ami sok erőforrást igényel, például CPU-t, memóriát és tárolóhelyet.

Ezzel szemben a konténerek az operációs rendszer kerneljét osztják meg a host operációs rendszerrel. Nem emulálnak teljes operációs rendszert, hanem az alkalmazások és azok függőségeinek elkülönítésére szolgálnak a host OS-en belül. A konténerek virtualizálják az operációs rendszert, nem a hardvert. Ez azt jelenti, hogy sokkal könnyebbek és gyorsabban indíthatók, mint a VM-ek. A konténerek kevesebb erőforrást igényelnek, mivel nem kell külön operációs rendszert futtatniuk.

A legfontosabb különbség a VM-ek és a konténerek között a virtualizáció szintje. A VM-ek a hardvert virtualizálják, míg a konténerek az operációs rendszert. Ez a különbség jelentős hatással van a teljesítményre, az erőforrás-felhasználásra és a telepítés egyszerűségére.

A konténerek lényegesen hatékonyabban használják ki az erőforrásokat, mivel nem szükséges minden alkalmazáshoz külön operációs rendszert futtatni.

Az alábbi táblázat összefoglalja a főbb különbségeket:

Jellemző Virtuális Gép (VM) Konténer
Virtualizációs szint Hardver Operációs rendszer
Operációs rendszer Saját, vendég OS Megosztott a host OS-sel
Erőforrás-felhasználás Magas Alacsony
Indítási idő Hosszú Rövid
Elkülönítés Erős Kevésbé erős (a kernel megosztása miatt)

A konténerek előnyei a következők:

  • Gyorsabb telepítés és indítás: A konténerek másodpercek alatt elindíthatók, míg a VM-ek indítása perceket vehet igénybe.
  • Hatékonyabb erőforrás-felhasználás: A konténerek kevesebb erőforrást igényelnek, ami lehetővé teszi több alkalmazás futtatását ugyanazon a hardveren.
  • Egyszerűbb fejlesztés és tesztelés: A konténerek konzisztens környezetet biztosítanak a fejlesztők és a tesztelők számára.
  • Hordozhatóság: A konténerek könnyen átvihetők különböző környezetekbe, például fejlesztői gépről éles szerverre.

Ugyanakkor a konténereknek is vannak hátrányai. A VM-ekhez képest kevésbé erős az elkülönítés, mivel a konténerek a host OS kerneljét osztják meg. Ez biztonsági kockázatot jelenthet, ha egy konténerben biztonsági rés található. Ezenkívül a konténerek kevésbé alkalmasak olyan alkalmazások futtatására, amelyek speciális kernelmodulokat vagy hardverhozzáférést igényelnek.

Végső soron a VM-ek és a konténerek közötti választás az alkalmazás követelményeitől függ. Ha erős elkülönítésre van szükség, vagy az alkalmazás speciális hardverhozzáférést igényel, akkor a VM-ek a jobb választás. Ha a gyors telepítés, a hatékony erőforrás-felhasználás és a hordozhatóság a fontosabb, akkor a konténerek a megfelelőbbek.

Konténerizációs technológiák: Docker, Podman, containerd

A Docker alapozta meg a konténerizáció modern ökoszisztémáját.
A Docker forradalmasította az alkalmazásfejlesztést, gyors és könnyű konténerizációt biztosítva fejlesztők számára.

A konténerizációs technológiák, mint a Docker, Podman és containerd, lehetővé teszik az alkalmazások és azok függőségeinek egy standardizált egységbe, úgynevezett konténerbe csomagolását. Ez a megközelítés biztosítja, hogy az alkalmazás ugyanúgy fusson különböző környezetekben, legyen szó fejlesztői gépről, tesztkörnyezetről vagy éppen éles szerverről.

A Docker talán a legismertebb konténerizációs platform. A Docker egy teljes ökoszisztémát kínál a konténerek létrehozására, futtatására és menedzselésére. A Docker Dockerfiles segítségével definiáljuk a konténer tartalmát, ami egy egyszerű szöveges fájl, amely tartalmazza az alkalmazás futtatásához szükséges összes lépést és függőséget. A Docker ezekből a Dockerfiles-okból építi fel a konténer image-eket, amik a futtatható konténerek alapját képezik.

A Podman egy alternatív konténerizációs megoldás, amely a rootless konténer futtatására helyezi a hangsúlyt. Ez azt jelenti, hogy a konténerek nem root jogosultságokkal futnak, ami jelentősen növeli a biztonságot. A Podman kompatibilis a Docker parancssorával, így a Dockerhez szokott felhasználók könnyen átválthatnak a Podman használatára. A Podman különösen népszerű a fejlesztői környezetekben, ahol a biztonság és a könnyű használat fontos szempont.

A konténerizáció lényege, hogy elszigeteljük az alkalmazásokat a futtató környezettől, így biztosítva a konzisztens működést és a könnyű áttelepíthetőséget.

A containerd egy alacsonyabb szintű konténer futtató, amelyet a Docker is használ a háttérben. A containerd a konténerek életciklusának menedzselésére összpontosít, beleértve a konténerek letöltését, tárolását, futtatását és a hálózatkezelést. A containerd egy CNCF (Cloud Native Computing Foundation) projekt, ami garantálja a hosszú távú támogatást és a nyílt forráskódú fejlesztést. A containerd gyakran használják Kubernetes környezetekben a konténerek futtatására.

A három technológia közötti különbségek a következők:

  • Docker: Teljes körű konténerizációs platform, beépített eszközökkel a konténerek létrehozásához, futtatásához és menedzseléséhez.
  • Podman: Rootless konténer futtatásra optimalizált, a Docker parancssorával kompatibilis.
  • containerd: Alacsonyabb szintű konténer futtató, a konténerek életciklusának menedzselésére összpontosít.

A megfelelő technológia kiválasztása az adott projekt igényeitől függ. A Docker ideális választás lehet, ha egy teljes körű megoldásra van szükség. A Podman a rootless konténer futtatás előnyeit kínálja. A containerd pedig a Kubernetes alapú környezetekben nyújt kiváló teljesítményt.

A Docker architektúrája és működése: Docker Engine, Docker Daemon, Docker CLI

A Docker a konténerizációs technológia egyik legelterjedtebb implementációja. Lényegében egy platform, amely lehetővé teszi alkalmazások és azok függőségeinek konténerekbe csomagolását, amik aztán bárhol futtathatók, ahol Docker futtatási környezet rendelkezésre áll. A Docker architektúrájának megértése kulcsfontosságú a technológia hatékony használatához.

A Docker architektúra három fő komponensre osztható: a Docker Engine, a Docker Daemon és a Docker CLI (parancssori interfész).

A Docker Engine a Docker alkalmazás futtatásához szükséges alapvető szoftver. Ez a komponens foglalja magában a Docker Daemont és a Docker CLI-t, valamint a konténerek létrehozásához és kezeléséhez szükséges egyéb eszközöket.

A Docker Daemon (dockerd) egy háttérfolyamat, amely a Docker Engine szíve. Ez a folyamat felelős a Docker objektumok (képek, konténerek, hálózatok, kötetek) kezeléséért. A Docker Daemon fogadja a Docker CLI-től érkező kéréseket és végrehajtja azokat, például képek letöltését, konténerek létrehozását, indítását, leállítását és törlését. A Daemon folyamatosan fut a háttérben, és figyeli a Docker API-n keresztül érkező kéréseket.

A Docker Daemon a központi irányító, amely a Docker konténerek életciklusát kezeli.

A Docker CLI (parancssori interfész) a felhasználóval való kommunikáció eszköze. Lehetővé teszi a felhasználók számára, hogy parancsokat adjanak ki a Docker Daemon felé. A CLI parancsokkal lehet például:

  • Képeket letölteni (docker pull)
  • Konténereket létrehozni (docker create vagy docker run)
  • Konténereket indítani (docker start)
  • Konténereket leállítani (docker stop)
  • Konténereket törölni (docker rm)
  • Képeket építeni (docker build)
  • Képeket feltölteni egy távoli tárolóba (docker push)

A Docker CLI parancsokat küld a Docker Daemonnak, amely azokat értelmezi és végrehajtja. A Daemon ezután visszajelzést küld a CLI-nek, amely megjeleníti azt a felhasználó számára.

Például, amikor a felhasználó kiadja a docker run ubuntu parancsot, a Docker CLI elküldi ezt a parancsot a Docker Daemonnak. A Daemon először ellenőrzi, hogy a ubuntu kép helyileg elérhető-e. Ha nem, akkor letölti azt egy konfigurált tárolóból (alapértelmezés szerint a Docker Hub-ról). Ezután a Daemon létrehoz egy új konténert a ubuntu kép alapján, és elindítja azt. A konténerben fut a ubuntu operációs rendszer, és a felhasználó interakcióba léphet vele a CLI-n keresztül.

A Docker képek rétegekből épülnek fel. Minden réteg egy-egy fájlrendszerbeli változást reprezentál, például egy szoftver telepítését vagy egy fájl módosítását. Ezek a rétegek csak olvashatóak, és egymásra épülnek. Amikor egy konténer fut, egy írható réteg kerül hozzá a rétegek tetejére. Ez a réteg lehetővé teszi a konténer számára, hogy fájlokat hozzon létre és módosítson anélkül, hogy a kép eredeti rétegeit érintené.

A Docker képek a konténerek sablonjai. Tartalmazzák az összes szükséges fájlt, konfigurációt és függőséget ahhoz, hogy egy alkalmazás fusson. A képeket a Docker Hub-on vagy más tárolókban lehet tárolni és megosztani.

A Docker konténerek a képek futó példányai. Elszigeteltek a gazdagéptől és egymástól, ami biztosítja, hogy az egyik konténerben futó alkalmazás ne zavarja a többi konténerben futó alkalmazásokat. A konténerek könnyűsúlyúak és gyorsan indíthatók, ami ideálissá teszi őket a mikroszolgáltatások és a felhő alapú alkalmazások futtatásához.

A Docker hálózatok lehetővé teszik a konténerek közötti kommunikációt. A Docker kötetek lehetővé teszik a konténerek számára, hogy adatokat tároljanak a gazdagépen, ami biztosítja, hogy az adatok megmaradjanak a konténerek leállítása után is.

A Docker architektúrája lehetővé teszi a fejlesztők és az üzemeltetők számára, hogy gyorsabban és hatékonyabban dolgozzanak. A konténerek segítségével a fejlesztők könnyen csomagolhatják alkalmazásaikat és azok függőségeit, míg az üzemeltetők könnyen telepíthetik és kezelhetik azokat.

Docker image-ek: Létrehozás, rétegek, Dockerfile

A Docker image-ek a konténer technológia alapkövei. Ezek a sablonok tartalmazzák mindazt, ami egy alkalmazás futtatásához szükséges: a kódot, a futtatókörnyezetet, a rendszer könyvtárakat, a beállításokat és a függőségeket. Képzeljük el őket egy pillanatképként, amely egy adott pillanatban rögzíti az alkalmazás állapotát.

Az image-ek létrehozásának leggyakoribb módja a Dockerfile használata. Ez egy szöveges fájl, amely utasításokat tartalmaz a Docker számára, hogyan építse fel az image-et. A Dockerfile soronként hajtja végre az utasításokat, és minden utasítás egy új réteget hoz létre az image-ben.

Az image rétegek a Docker egyik legfontosabb tulajdonsága. Minden réteg csak olvasható, és a korábbi rétegekre épül. Ez azt jelenti, hogy ha egy image-et módosítani kell, nem kell az egészet újraépíteni. A Docker csak a megváltozott réteget építi újra, ami jelentősen felgyorsítja a folyamatot és csökkenti a tárhelyigényt. A rétegek megosztása is lehetséges különböző image-ek között, ami tovább optimalizálja a tárhelyhasználatot.

A Dockerfile utasításai határozzák meg, hogy mi kerüljön az egyes rétegekbe. Néhány gyakori utasítás:

  • FROM: Megadja az alap image-et, amelyre az új image épül. Például: `FROM ubuntu:latest`
  • RUN: Parancsokat futtat a konténerben az image építése során. Például: `RUN apt-get update && apt-get install -y nginx`
  • COPY: Fájlokat másol a host gépről a konténerbe. Például: `COPY ./myapp /app`
  • ADD: Hasonló a COPY-hoz, de képes URL-ekről is fájlokat letölteni és kicsomagolni.
  • WORKDIR: Beállítja a munkakönyvtárat a konténerben. Például: `WORKDIR /app`
  • EXPOSE: Megadja, hogy mely portokat fogja a konténer publikálni. Például: `EXPOSE 80`
  • CMD: A konténer indításakor futtatandó parancsot adja meg. Például: `CMD [„nginx”, „-g”, „daemon off;”]`
  • ENTRYPOINT: Hasonló a CMD-hez, de nehezebb felülírni a konténer indításakor.
  • ENV: Környezeti változókat állít be. Például: `ENV MY_VAR=my_value`

A Dockerfile-ban megadott utasítások sorrendje számít. A gyakran változó utasításokat a Dockerfile aljára érdemes helyezni, mert így a Docker a gyorsítótárából tudja felhasználni a korábbi rétegeket, és csak a változó rétegeket kell újraépítenie. Ha például a függőségek telepítése (RUN apt-get install…) gyakran változik, akkor ezt érdemes a Dockerfile aljára tenni.

A Docker image-ek létrehozása és használata során kulcsfontosságú a rétegek optimalizálása. Minél kevesebb réteg van, és minél kisebbek a rétegek, annál gyorsabban épül fel az image, és annál kevesebb tárhelyet foglal el. A felesleges fájlok törlése, a több parancs egyetlen RUN utasításba történő egyesítése, és a multi-stage build használata mind segíthetnek a rétegek optimalizálásában.

A Docker image-ek nem módosíthatóak. Ha módosítani kell egy image-et, akkor egy új image-et kell létrehozni a módosított Dockerfile alapján. A rétegek miatt azonban ez a folyamat általában gyors, mivel csak a megváltozott rétegeket kell újraépíteni.

A Docker image-ek a konténerizált alkalmazások terjesztésének és futtatásának szabványos módját biztosítják, garantálva a konzisztens működést a különböző környezetekben.

A Docker image-eket a Docker Hub-on vagy más image regisztrákon tárolhatjuk és oszthatjuk meg. Ez lehetővé teszi, hogy mások is felhasználhassák a létrehozott image-eket, és hogy mi is felhasználhassuk mások által létrehozott image-eket.

A Docker image-ek immutable, vagyis megváltoztathatatlanok. Ha egy image-et módosítani kell, akkor egy új image-et kell létrehozni a módosított Dockerfile alapján. Ez a megközelítés biztosítja, hogy a konténerek mindig ugyanúgy fognak viselkedni, függetlenül attól, hogy hol futtatjuk őket.

Dockerfile utasítások részletesen: FROM, RUN, COPY, ADD, CMD, ENTRYPOINT, ENV, VOLUME, EXPOSE, USER, WORKDIR

A Dockerfile a konténerek létrehozásának alapköve. Ez egy szöveges fájl, amely tartalmazza azokat az utasításokat, amelyekre a Dockernek szüksége van egy adott alkalmazás futtatásához szükséges környezet összeállításához. Nézzük meg a leggyakoribb és legfontosabb Dockerfile utasításokat részletesen:

FROM: Ez az utasítás határozza meg a bázisképet, amelyre a konténerünk épül. Minden Dockerfile-nak kötelezően tartalmaznia kell egy FROM utasítást, és ez kell, hogy legyen az első. A báziskép lehet egy hivatalos kép a Docker Hub-ról (pl. ubuntu:latest, python:3.9) vagy egy korábban létrehozott, saját kép. Például:

FROM ubuntu:latest

Ez a sor azt mondja, hogy a konténerünk az Ubuntu legfrissebb verziójára épül.

RUN: A RUN utasítás parancsokat futtat a konténer belsejében a kép építése során. Ezek a parancsok lehetnek csomagok telepítése, fájlok létrehozása, konfigurációs beállítások végrehajtása, stb. Minden RUN utasítás egy új réteget hoz létre a Docker képben. Például:

RUN apt-get update && apt-get install -y python3 python3-pip

Ez a parancs frissíti az Ubuntu csomagkezelőjét, majd telepíti a Python 3-at és a pip csomagkezelőt.

COPY: A COPY utasítás fájlokat vagy könyvtárakat másol a host gépről a konténerbe. A forrás és a cél elérési utakat kell megadni. A cél elérési út mindig a konténeren belüli helyre vonatkozik. Például:

COPY ./app /app

Ez a parancs az ./app könyvtárat a host gépről az /app könyvtárba másolja a konténerben.

ADD: Az ADD utasítás hasonló a COPY-hoz, de további funkcionalitással rendelkezik. Képes automatikusan kicsomagolni a tömörített fájlokat (pl. .tar, .gz) és képes távoli URL-ekről fájlokat letölteni. Általában a COPY-t részesítik előnyben, mert egyértelműbb és kevésbé meglepő a viselkedése. Például:

ADD ./app.tar.gz /app/

Ez a parancs az app.tar.gz fájlt a host gépről az /app/ könyvtárba másolja a konténerben, és ott kicsomagolja.

CMD: A CMD utasítás egy parancsot ad meg, amelyet a konténer indításakor futtat. Csak egy CMD utasítás lehet egy Dockerfile-ban. Ha több van, az utolsó lesz érvényes. A CMD felülírható a docker run parancsban megadott argumentumokkal. Például:

CMD ["python3", "/app/main.py"]

Ez a parancs a main.py Python szkriptet futtatja a konténer indításakor.

ENTRYPOINT: Az ENTRYPOINT utasítás hasonló a CMD-hez, de nem írható felül a docker run parancsban, hacsak nem használjuk a –entrypoint flag-et. Az ENTRYPOINT-ot gyakran használják a konténer fő folyamatának meghatározására. A CMD-vel kombinálva paramétereket adhatunk át az ENTRYPOINT által meghatározott alkalmazásnak. Például:

ENTRYPOINT ["/usr/bin/java", "-jar", "/app/my-app.jar"]

Ez a parancs a Java alkalmazást futtatja a konténer indításakor.

Az ENTRYPOINT és CMD együttműködése lehetővé teszi a konténer testreszabását indításkor, miközben biztosítja, hogy a fő alkalmazás mindig fusson.

ENV: Az ENV utasítás környezeti változókat állít be a konténerben. Ezek a változók elérhetőek lesznek az alkalmazás számára futásidőben. Például:

ENV APP_HOME /app

Ez a parancs az APP_HOME környezeti változót az /app értékre állítja.

VOLUME: A VOLUME utasítás egy vagy több mount pontot hoz létre, amelyeket külső tároló kötetekhez lehet csatolni. Ez lehetővé teszi a konténerben lévő adatok megőrzését a konténer törlése után is, illetve a host gépről is elérhetővé teszi azokat. Például:

VOLUME /data

Ez a parancs egy /data nevű mount pontot hoz létre a konténerben.

EXPOSE: Az EXPOSE utasítás megadja, hogy a konténer mely portokat fogja használni. Ez nem teszi automatikusan elérhetővé a portokat kívülről, de dokumentációs célt szolgál, és a Docker használhatja a portok közötti összekapcsolások optimalizálására. A portokat a docker run parancs -p vagy -P flag-jeivel tehetjük elérhetővé. Például:

EXPOSE 8080

Ez a parancs jelzi, hogy a konténer a 8080-as portot fogja használni.

USER: A USER utasítás megadja, hogy melyik felhasználóként fusson a konténerben a következő utasítások. Alapértelmezés szerint a konténerek root felhasználóként futnak. A nem root felhasználóként való futtatás növeli a biztonságot. Például:

USER myuser

Ez a parancs a myuser felhasználóra vált a következő utasítások végrehajtásához.

WORKDIR: A WORKDIR utasítás beállítja a munkakönyvtárat a konténerben. A következő RUN, CMD, ENTRYPOINT, COPY és ADD utasítások relatív elérési útjai ehhez a könyvtárhoz viszonyulnak. Például:

WORKDIR /app

Ez a parancs a munkakönyvtárat az /app könyvtárra állítja.

Konténer futtatása és menedzselése: Docker run, Docker ps, Docker stop, Docker rm

A Docker run indít konténert, a ps listáz, stop leállít.
A Docker run parancs konténereket indít, míg a Docker ps listázza a futó konténereket gyorsan.

A konténerek futtatása és menedzselése a Docker CLI segítségével történik. Nézzük meg a leggyakrabban használt parancsokat:

  • docker run: Ez a parancs hozza létre és indítja el a konténert egy adott image alapján. Például: docker run -d -p 80:80 nginx. A -d opció a háttérben futtatja a konténert (detached mode), a -p 80:80 pedig a host gép 80-as portját a konténer 80-as portjára irányítja. Az nginx az image neve, amiből a konténer létrehozódik.
  • docker ps: Ezzel a paranccsal listázhatjuk az éppen futó konténereket. A kimenet tartalmazza a konténer azonosítóját (CONTAINER ID), a használt image-et, a parancsot, a létrehozás időpontját, az állapotát (STATUS) és a portokat (PORTS). A docker ps -a parancs az összes konténert listázza, beleértve a leállítottakat is.
  • docker stop: A docker stop paranccsal állíthatunk le egy futó konténert. A parancs argumentuma a konténer azonosítója (CONTAINER ID) vagy a neve. Például: docker stop . A docker stop parancs megpróbálja elegánsan leállítani a konténert, azaz jelez a konténerben futó alkalmazásnak, hogy be kell fejeznie a munkát és le kell állnia.
  • docker rm: Ezzel a paranccsal távolíthatunk el egy leállított konténert. A parancs argumentuma a konténer azonosítója (CONTAINER ID) vagy a neve. Például: docker rm . Fontos, hogy egy futó konténert nem lehet eltávolítani. Először le kell állítani a docker stop paranccsal.

A konténer azonosítók használata helyett a konténerek elnevezése is egy bevett gyakorlat. A docker run parancsban a --name opcióval adhatunk nevet a konténernek. Például: docker run --name my-nginx -d -p 80:80 nginx. Ezután a docker stop és docker rm parancsokban a konténer nevét használhatjuk az azonosító helyett.

A konténerek állapotának figyelése is fontos. A docker ps parancs mellett a docker stats parancs is hasznos lehet. Ez a parancs valós időben mutatja a konténer erőforrás-használatát, például a CPU-használatot, a memória-használatot és a hálózati forgalmat.

A konténerek menedzselése során elengedhetetlen a megfelelő tervezés és a konténerek állapotának folyamatos figyelemmel kísérése.

A konténerekkel való munka során gyakran előfordul, hogy több konténert kell együtt kezelni. Erre a célra a Docker Compose kínál megoldást, amely lehetővé teszi több konténer definícióját egyetlen YAML fájlban, és azok együttes elindítását és leállítását.

A docker run parancs sok opcióval rendelkezik, amelyek lehetővé teszik a konténer konfigurálását. Néhány gyakran használt opció:

  • -e: Környezeti változók beállítása.
  • -v: Volume-ok csatolása a host gépről a konténerbe.
  • --network: Konténer hozzáadása egy hálózathoz.

Konténer hálózatkezelés: Bridge, Host, None hálózatok

A konténer hálózatkezelés a konténerizációs technológiák, mint például a Docker, egyik kulcsfontosságú eleme. Meghatározza, hogyan kommunikálnak a konténerek egymással és a külvilággal. A Docker három alapvető hálózati módot kínál:

  • Bridge: Ez az alapértelmezett hálózati mód. A Docker egy privát, belső hálózatot hoz létre (pl. docker0), és minden konténerhez ezen a hálózaton belül rendel egy IP címet. A konténerek egymással ezen a hálózaton keresztül tudnak kommunikálni. A külvilággal való kommunikációhoz a Docker porttovábbítást (port forwarding) használ, melynek segítségével a hoszt gép egy adott portja átirányításra kerül a konténer egy portjára.
  • Host: Ebben a módban a konténer közvetlenül a hoszt gép hálózatát használja. Ez azt jelenti, hogy a konténer nem kap külön IP címet, hanem a hoszt gép IP címét használja, és a hoszt gép portjait használja. Ez a mód nagyobb teljesítményt eredményezhet, mivel nincs szükség NAT-ra (Network Address Translation), de portütközésekhez vezethet, ha több konténer próbálja ugyanazt a portot használni.
  • None: Ebben a módban a konténer nincs hálózathoz csatlakoztatva. Ez azt jelenti, hogy a konténer nem tud kommunikálni sem a külvilággal, sem más konténerekkel. Ezt a módot jellemzően olyan konténerekhez használják, amelyeknek nincs szükségük hálózati kapcsolatra, például számítási feladatokhoz.

A kiválasztott hálózati mód jelentős hatással van a konténer alkalmazások teljesítményére, biztonságára és konfigurációjára.

A Bridge hálózat a leggyakrabban használt, mivel biztosítja az elkülönítést és a rugalmasságot, míg a Host hálózat a teljesítménykritikus alkalmazásokhoz ideális, de nagyobb figyelmet igényel a portütközések elkerülése érdekében. A None hálózat pedig az izolált, hálózatot nem igénylő feladatokhoz való.

A Docker lehetővé teszi egyedi hálózatok létrehozását is, melyek segítségével komplex alkalmazások konténerei könnyen összekapcsolhatók.

Konténer tárolás: Volume-ok, Bind mounts, tmpfs

A konténerizáció során az adatok perzisztenciája kritikus kérdés. Alapértelmezetten a konténerben tárolt adatok a konténer megszűnésével elvesznek. Ezért különböző tárolási megoldások állnak rendelkezésre, amelyek lehetővé teszik az adatok megőrzését és megosztását a konténerek között.

Volume-ok (kötet): A volume-ok a Docker által menedzselt tárolási egységek. A Docker hozza létre és kezeli őket, függetlenül a konténer fájlrendszerétől. Előnyük, hogy könnyen átvihetők konténerek között, és a Docker automatikusan gondoskodik az adatok mentéséről és visszaállításáról. Hasznosak, ha azt szeretnénk, hogy az adataink a konténer életciklusán túl is megmaradjanak, és ne legyenek közvetlenül a host fájlrendszeréhez kötve.

Bind mounts: A bind mountok a host fájlrendszerének egy könyvtárát vagy fájlját csatolják a konténerhez. Ez azt jelenti, hogy a konténerben végzett változtatások közvetlenül a host fájlrendszerén is megjelennek, és fordítva. Nagyon hasznosak fejlesztés során, amikor a kódot a host gépen szerkesztjük, és azonnal látni szeretnénk a változásokat a konténerben futó alkalmazásban.

A bind mountok közvetlen hozzáférést biztosítanak a host fájlrendszeréhez, így nagyobb rugalmasságot, de egyben nagyobb felelősséget is jelentenek.

tmpfs: A tmpfs egy ideiglenes fájlrendszer, amely a host gép memóriájában vagy swap területén tárolja az adatokat. Gyors hozzáférést biztosít az adatokhoz, de a konténer leállásakor vagy a host gép újraindításakor az adatok elvesznek. Ideális ideiglenes adatok tárolására, például munkamenet-adatok vagy cache fájlok számára. Előnye, hogy nem foglal helyet a host gépen, ha nincs rá szükség.

A tárolási megoldások közötti választás az adott alkalmazás igényeitől függ. Ha perzisztens adatokra van szükségünk, a volume-ok a legjobb választás. Fejlesztés során a bind mountok nyújtanak nagy segítséget. Az ideiglenes adatok kezelésére pedig a tmpfs a legalkalmasabb.

Docker Compose: Többkonténeres alkalmazások definiálása és kezelése

A Docker Compose egy eszköz a többkonténeres Docker alkalmazások definiálására és futtatására. Egyetlen YAML fájl segítségével leírhatjuk az alkalmazásunk teljes architektúráját, beleértve az egyes konténereket, azok függőségeit, hálózati beállításait és a tárolt adatokat.

A konténer technológia, mint a Docker, lehetővé teszi az alkalmazások és azok függőségeinek elkülönített környezetben való futtatását. Azonban egy összetett alkalmazás gyakran több konténerből áll, amelyek együttműködnek. A Docker Compose ebben segít, hogy ne kelljen külön-külön kezelnünk ezeket a konténereket.

A Docker Compose YAML fájlban definiáljuk a szolgáltatásokat. Egy szolgáltatás (service) egy konténer futtatásának konfigurációját jelenti. A YAML fájlban megadhatjuk a Docker image-t, a portokat, a környezeti változókat, a köteteket és a függőségeket.

Például:


version: "3.9"
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
  db:
    image: postgres:13
    environment:
      POSTGRES_USER: example
      POSTGRES_PASSWORD: example

Ebben a példában két szolgáltatás van definiálva: web és db. A web szolgáltatás az Nginx webkiszolgálót futtatja, és a 80-as portot a host gép 80-as portjára irányítja. A db szolgáltatás a PostgreSQL adatbázist futtatja, és beállítja a felhasználónevet és a jelszót.

A Docker Compose leegyszerűsíti a többkonténeres alkalmazások kezelését azáltal, hogy egyetlen paranccsal elindíthatjuk, leállíthatjuk és újraépíthetjük az egész alkalmazást.

A Docker Compose használatának előnyei:

  • Egyszerű konfiguráció: Egyetlen YAML fájlban definiálhatjuk az egész alkalmazás architektúráját.
  • Könnyű kezelhetőség: Egyetlen paranccsal kezelhetjük az összes konténert.
  • Reprodukálhatóság: Az alkalmazás konfigurációja verziókövethető, így biztosítható a reprodukálhatóság különböző környezetekben.
  • Skálázhatóság: Könnyen skálázhatjuk az alkalmazás egyes részeit a docker-compose scale paranccsal.

A Docker Compose parancsok:

  1. docker-compose up: Elindítja az alkalmazást.
  2. docker-compose down: Leállítja az alkalmazást.
  3. docker-compose build: Létrehozza a Docker image-eket a Dockerfile-ok alapján.
  4. docker-compose ps: Megmutatja a futó konténereket.
  5. docker-compose logs: Megmutatja a konténerek naplóit.

A Docker Compose használata elengedhetetlen a modern szoftverfejlesztésben, különösen a mikroszolgáltatás alapú architektúrák esetében, ahol az alkalmazás több kisebb, egymástól független szolgáltatásból áll.

Konténer orchestráció: Kubernetes, Docker Swarm

A Kubernetes dinamikusan skálázza a konténereket, növelve hatékonyságot.
A Kubernetes automatikusan kezeli a konténerek skálázását és hibajavítását, növelve az alkalmazások megbízhatóságát.

A konténertechnológia elterjedésével felmerült az igény a konténerek hatékony kezelésére és üzemeltetésére. Ezt a problémát oldják meg a konténer orchestrációs platformok, amelyek közül a legismertebbek a Kubernetes és a Docker Swarm.

A Kubernetes (K8s) egy nyílt forráskódú konténer orchestrációs rendszer, amely automatizálja a konténerek telepítését, skálázását és kezelését. A Kubernetes központi eleme a cluster, amely egy vagy több node-ból áll. A node-okon futnak a konténerek, amelyeket pod-okba szerveznek. A pod-ok a Kubernetes legkisebb telepíthető egységei, és egy vagy több, szorosan összekapcsolódó konténert tartalmazhatnak.

A Kubernetes architektúrája összetett, de rendkívül rugalmas. Főbb komponensei:

  • kube-apiserver: A Kubernetes API szervere, amely a clusterrel való kommunikáció központi pontja.
  • kube-scheduler: A pod-ok node-okra való ütemezéséért felelős.
  • kube-controller-manager: A cluster állapotának figyeléséért és a kívánt állapot fenntartásáért felelős.
  • etcd: A cluster konfigurációs adatainak tárolására szolgál.

A Docker Swarm szintén egy konténer orchestrációs eszköz, amelyet a Docker fejlesztett ki. A Swarm beépített a Docker motorba, így egyszerűen használható a Dockerrel ismerkedők számára. A Swarm egy clusterben több Docker host-ot (node-ot) egyesít, amelyek együttesen futtatják a konténereket.

A Docker Swarm architektúrája egyszerűbb, mint a Kubernetesé. A Swarm cluster egy vagy több manager node-ból és több worker node-ból áll. A manager node-ok feladata a cluster irányítása és a feladatok ütemezése, míg a worker node-ok a konténereket futtatják.

A Kubernetes és a Docker Swarm közötti legfontosabb különbség a komplexitásukban és a funkcionalitásukban rejlik. A Kubernetes sokkal összetettebb és erőteljesebb, míg a Docker Swarm egyszerűbb és könnyebben használható.

A választás a Kubernetes és a Docker Swarm között a projekt igényeitől függ. A Kubernetes ideális nagyméretű, komplex alkalmazásokhoz, amelyek magas szintű rugalmasságot és skálázhatóságot igényelnek. A Docker Swarm pedig kisebb, egyszerűbb alkalmazásokhoz, vagy olyan projektekhez, ahol a gyors beüzemelés és az egyszerű használat a prioritás.

Mindkét platform támogatja a konténerek automatikus skálázását, a terheléselosztást és a hibatűrést. A skálázás lehetővé teszi az alkalmazások erőforrásainak dinamikus növelését vagy csökkentését a terhelés függvényében. A terheléselosztás a bejövő forgalmat egyenletesen osztja el a konténerek között, biztosítva a magas rendelkezésre állást. A hibatűrés pedig garantálja az alkalmazások folyamatos működését abban az esetben is, ha egy vagy több konténer meghibásodik.

A következő táblázat összefoglalja a Kubernetes és a Docker Swarm legfontosabb jellemzőit:

Jellemző Kubernetes Docker Swarm
Komplexitás Magas Alacsony
Skálázhatóság Magas Közepes
Rugalmasság Magas Közepes
Tanulási görbe Merdek Enyhe
Közösség Nagy és aktív Kisebb

Kubernetes alapok: Podok, Service-ek, Deployment-ek, Namespace-ek

A Kubernetes, egy nyílt forráskódú konténerorchesztrációs platform, elengedhetetlen a modern alkalmazásfejlesztésben. Nézzük meg az alapvető építőköveit:

Podok: A Kubernetes legkisebb, telepíthető egysége a Pod. Egy vagy több konténert foglal magába, amelyek osztoznak a hálózati és tárolási erőforrásokon. A Podok rövid életűek lehetnek, ami azt jelenti, hogy létrehozásuk és törlésük dinamikusan történhet.

Egy Pod egyetlen alkalmazás egy példányát képviseli.

Service-ek: Mivel a Podok dinamikusan változhatnak, szükség van egy stabil belépési pontra az alkalmazásokhoz. Ezt a célt szolgálják a Service-ek. A Service egy absztrakciós réteg, amely egy vagy több Podot foglal magába, és egyetlen, állandó IP-címen és porton keresztül teszi elérhetővé őket. A Service-ek lehetővé teszik a terheléselosztást a Podok között, és elrejtik a Podok változó IP-címét a külső felhasználók elől. Többféle Service típus létezik, például ClusterIP (csak a klaszteren belülről érhető el), NodePort (a klaszter minden csomópontján elérhető egy porton keresztül) és LoadBalancer (külső terheléselosztóval érhető el).

Deployment-ek: A Deployment egy magasabb szintű absztrakció, amely a Podok és Service-ek kezelését könnyíti meg. Meghatározza a kívánt állapotot, például a futó Podok számát és a használt konténer image verzióját. A Kubernetes automatikusan gondoskodik arról, hogy a rendszer az előírt állapotnak megfelelően működjön. Ha egy Pod meghibásodik, a Deployment automatikusan újraindítja vagy lecseréli azt. A Deployment-ek emellett lehetővé teszik a gördülő frissítéseket és a visszagörgetéseket, így minimalizálva az állásidőt az alkalmazások frissítése során.

Namespace-ek: A Namespace egy logikai elkülönítési egység a Kubernetes klaszteren belül. Lehetővé teszi a klaszter erőforrásainak felosztását különböző csapatok, projektek vagy környezetek között (pl. fejlesztői, tesztelői, éles). A Namespace-ek használatával elkerülhetőek a névütközések, és javítható a biztonság, mivel az erőforrások elkülönítve kezelhetőek. Például, egy fejlesztői csapat a saját Namespace-ében dolgozhat anélkül, hogy befolyásolná egy másik csapat munkáját egy másik Namespace-ben.

A Namespace-ek segítségével:

  • Különböző csapatok osztozhatnak egy klaszteren.
  • Elkülöníthetőek a fejlesztői, tesztelői és éles környezetek.
  • Korlátozható az erőforrások használata Namespace-enként.

Ezek az alapvető építőkövek teszik a Kubernetes-t egy hatékony és rugalmas platformmá a konténerizált alkalmazások kezelésére.

A konténer biztonság kérdései: Image scanning, runtime security

A konténer biztonságának kulcsfontosságú területei az image scanning és a runtime security. Mivel a konténerek képekből épülnek fel, amelyek potenciálisan sérülékeny szoftvereket tartalmazhatnak, az image scanning elengedhetetlen a kockázatok minimalizálásához.

Az image scanning során a konténer képeket automatikusan átvizsgálják ismert biztonsági rések (CVE-k), rossz konfigurációk és más potenciális problémák után. Ez lehetővé teszi a fejlesztők és a biztonsági szakemberek számára, hogy a sérülékenységeket még a konténerek üzembe helyezése előtt azonosítsák és kijavítsák. A szkennelési folyamat gyakran tartalmazza a kép rétegeinek elemzését, a telepített csomagok verzióinak ellenőrzését és a biztonsági irányelveknek való megfelelés értékelését.

Többféle image scanning megoldás létezik, beleértve a nyílt forráskódú eszközöket és a kereskedelmi termékeket. Ezek az eszközök integrálhatók a CI/CD (folyamatos integráció/folyamatos kézbesítés) folyamatokba, így biztosítva, hogy minden új konténer kép átessen a biztonsági ellenőrzésen.

A runtime security a konténerek futás közbeni védelmét jelenti. Még akkor is, ha egy konténer kép a szkennelés során biztonságosnak bizonyult, a futás közbeni környezetben új sérülékenységek merülhetnek fel, vagy a támadók kihasználhatják a meglévőeket. A runtime security megoldások folyamatosan figyelik a konténerek viselkedését, észlelik a gyanús tevékenységeket, és reagálnak a biztonsági incidensekre.

A runtime security megvalósítható különböző technikákkal, például:

  • Rendszerhívás figyelés: Figyeli a konténer által kezdeményezett rendszerhívásokat, és észleli az anomáliákat.
  • Fájlrendszer integritás ellenőrzés: Ellenőrzi a konténer fájlrendszerét a jogosulatlan módosítások ellen.
  • Hálózati forgalom elemzés: Figyeli a konténer hálózati forgalmát a rosszindulatú tevékenységek, például a parancssori injekciók vagy az adatszivárgás jelei után.

A runtime security kritikus fontosságú a konténerek teljes körű védelméhez, mivel kiegészíti az image scanninget, és védelmet nyújt a futás közbeni támadások ellen.

A hatékony runtime security megvalósítása érdekében fontos, hogy a biztonsági megoldások integrálva legyenek a konténer platformmal, például a Kubernetes-szel. Ez lehetővé teszi a biztonsági szabályzatok központi kezelését és a biztonsági incidensekre való automatikus reagálást.

A megfelelő image scanning és runtime security megoldások kiválasztása a szervezet egyedi igényeitől és kockázati profiljától függ. Fontos, hogy a megoldások skálázhatóak, automatizálhatóak és integrálhatóak legyenek a meglévő fejlesztési és üzemeltetési folyamatokba.

Share This Article
Leave a comment

Vélemény, hozzászólás?

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük