A Docker alapjai

A Docker az egyik legismertebb és talán a legnépszerűbb konténerizációs rendszer, amelynek alapját a Linux kernelben már régóta jelen levő képesség adja. A Docker a legelterjedtebb konténerkezelő szoftverek közé tartozik, amely a Linux kernelszolgáltatásán alapulva egy modern, kényelmes környezetet nyújt a fejlesztők és az üzemeltetők számára Windowson, MacOS-en és Linuxon is. Ebben a fejezetben áttekintjük:

  • A konténerizációs rendszerek működésének lényeges pontjait.

  • A konténerizációhoz kapcsolódó architektúrát és a Docker által kidolgozott megvalósítás főbb elemeit.

  • Az operációs rendszer azon szolgáltatásait, amelyek nélkülözhetetlenek a konténer technológia támogatásához.

  • A Union fájlrendszert és működési elveit.

  • A Docker motor összetevőit és azok feladatát.

  • A Docker telepítésének folyamatát.

  • A DockerHub főbb funkcióit.

Szükséges eszközök:

Windows, MacOS vagy Linux operációs rendszerű számítógép.

Feldolgozási idő:

kb. 60 perc.

Ebben a fejezetben a konténerizációs feladatokat a Dockeren keresztül ismerjük meg. Maga a szoftver ingyenes, de a grafikus felület kezelőszoftveréért, a Docker Desktopért fejlesztő cégeknek (egy kellően nagy éves árbevétel felett – amely e sorok írásakor 10M dollár volt) fizetni kell.

A konténerizációs rendszerekről dióhéjban

A nyílt forráskódú Docker megszületését 2013-ra datálják, amivel alig egy évvel előzte meg a hasonló célra kifejlesztett, a Linux egy erre kifejlesztett kernelszolgáltatásra alapozó Lxd-t. A konténertechnológia versenyzői közül nem lehet kihagyni a RedHat fejlesztését, a Redhat Linuxokhoz tervezett Podman nagy vonalakban hasonlít ugyan a Dockerhez, de attól több ponton is eltér. A legnagyobb különbséget az jelenti, hogy míg a Docker esetében a működéshez egy háttérben futó szerverszolgáltatás szükséges, a RedHat-féle Podman nem igényel ilyet, az egyes konténerek önállóan működnek. Éppen ezért kell telepíteni a Docker esetében a Docker alkalmazást, enélkül egy konténer sem indítható el. A Docker esetében a konténerek ún. dedikált módban futnak, amelyhez végső soron rendszergazdai hozzáférésre van szükség, a Podman esetében ilyenre nincs szükség. Ez az oka annak, hogy a Podman biztonságosabbnak mondható olyan rendszerek esetében, ahol a felhasználók saját konténereiket indíthatják el.

A Docker architektúrája

A konténerek működése egy háromrétegű architektúra mentén valósul meg, amelynek alapját az operációs rendszer egyes szolgáltatásai jelentik. Erre épül az a futásidőben használt réteg, amely a containerd-ből és a runc-ből áll. A konténerek működtetését és az azokkal történő kommunikációt a harmadik rétegben működő Docker motor biztosítja.

A docker konténerek futtatásához szükséges architektúra

A docker konténerek futtatásához szükséges architektúra

A Docker konténerek futása nem lenne lehetséges a modern Linux kernelek egyes szolgáltatásai nélkül, amelyek három lényeges ponton nyújtanak támogatást a konténerizáció számára: ezek a névterek, az ún. kontroll csoportok és a Union fájlrendszer.

A névterek

A Linux kernel névterei (namespaces) már a konténerizáció előtt, 2002-ben is léteztek és lehetővé teszik, hogy a konténerek úgy fussanak saját, elkülönített környezetükben, mint ha mindegyikük egy önálló gépen működne. A névterek lehetővé teszik, hogy a konténerek folyamatai, fájlrendszerei elzárhatók legyenek egymástól és az operációs rendszertől. A névtereknek több típusa is létezik. A PID namespace az egyes processzek szétválasztását szolgálja. Az egyes konténerekben futó processzek ezzel csak a saját folyamataikhoz férnek hozzá, és nem látják a konténert futtató host gép processzeit éppúgy, mint más konténerekét sem. A Network namespace a hálózati interfészeket és paramétereit választja szét, így az egyes konténerek eltérő hálózati beállításokkal (IP cím, alhálózati maszk, átjáró stb.) tudnak működni. A USER namespace a konténereken belül önálló felhasználó és csoport azonosítók beállíthatóságát szolgálja – ezzel a konténerben lévő processzek a host géptől eltérő jogosultsági szinteken futnak még akkor is, ha abban azonos nevű vagy felhasználói azonosítójú felhasználók vannak felvéve. Ennek köszönhető, hogy egy konténerben létrehozott root felhasználó nem azonos a host gép azonos nevű felhasználójával. A Mount namespace pedig az egyes konténerek által használt fájlrendszereket szeparálja el egymástól úgy, hogy a konténerek számára egy virtuális fájlrendszert definiál és rendel hozzá. Ez a namespace biztosítja azt is, hogy a konténerek saját belső fájlrendszerrel rendelkezhessenek, melynek módosításai nincsenek hatással a host saját fájlrendszerére.

A kontroll csoportok

A control groups (cgroups) a Linux kernel másik szolgáltatása, amely lehetővé teszi az egyes folyamatok által igénybe vehető erőforrások mértékének korlátozását. Tipikus a CPU, memória, a diszk I/O vagy a hálózati sávszélesség korlátozása. A cgroups teszi lehetővé, hogy egyes processzek vagy konténerek elhasználják a rendszer erőforrásait, lehetetlenné téve más szoftverek működését. Ugyancsak a cgroups-on alapul a felhőszolgáltatásokban kínált erőforrások korlátozása, pl. az igénybe vehető CPU magok száma. Ennek beállításairól az utolsó, Biztonsági kérdések c. fejezetben olvashatsz bővebben.

A union fájlrendszer

A konténerek fájlrendszere rétegekből épül fel. Az első a konténer saját, alaprétege, ennek minden egyéb módosítása a konténerben egy-egy újabb réteg létrehozását hozza magával. Ennek optimális kialakításához egy új fájlrendszert terveztek, melynek alapja szintén egy kernel szolgáltatás, a Union Filesystem (UnionFS). A UnionFS tehát több fájlrendszer réteg egyesítésére képes, melyek kialakítása során különböző rétegeket olvaszt össze egy, a konténer számára nyújtott virtuális fájlrendszerré. Az egyes rétegek egymás felett helyezkednek el, és csak olvashatók vagy írhatók is lehetnek. A UnionFS a benne tárolt fájlok és könyvtárak rendszerét egy egységként teszi elérhetővé a konténer számára úgy, ahogy az az alábbi ábrán látható. Ebben a konténer saját rétege tartalmaz egy eleve több rétegből felépített Ubuntu 22.04-es operációs rendszert, melynek tartalma nem módosítható. A konténer erre további rétegeket építhet, melynek tartalma eltakarja az alsóbb rétegek azonos tartalmait.

A Union fájlrendszer rétegekből épül fel

A Union fájlrendszer rétegekből épül fel

A csak olvasható rétegben szereplő fájlok módosítását az ún. copy-on-write technológia teszi lehetővé. Amennyiben egy ilyen fájlt olvasni szeretnénk, egyszerűen az ebben a rétegben szereplő fájl tartalmát olvassuk ki. Ha viszont ezt módosítani kell, a UnionFS először egy másolatot készít az aktuális írható rétegbe, majd ennek tartalmát módosítja. A konténer szemszögéből, felülről nézve, ez a másolat „eltakarja” az eredeti fájlt, az új, módosított változattal helyettesítve azt.

Az alábbi példában egy konténerizált Ubuntu 22.04 operációs rendszer rendszergazdájának nevét változtatjuk meg úgy, hogy az /etc/passwd fájlban a root-ot rendszergazdára cseréljük. Ezt a fájlt a konténer alsó rétege már eleve tartalmazta, a módosítása viszont nem abban, hanem a következő, a konténer saját rétegében működő másolatban történik meg. Felülről nézve, a konténerben ezért „ez a fájl látszik”, így az eredeti többé nem érhető el számára.

A copy-on-write az eredeti fájlok másolatát módosítja

A copy-on-write az eredeti fájlok másolatát módosítja

A Docker motor

Ahogyan azt már láttuk, a Docker Engine két fő összetevőből áll, ezek a runC és a containerd. A runC alacsony szinten felel a konténerek létrehozásáért és futtatásáért, ez végzi a konténerek indítását, leállítását és további, kezelésükkel kapcsolatos műveleteket. A containerd a runC-re épül, és a Docker daemon egyik alapvető eleme. Magasabb szinten kezeli a konténerek létrehozását, indítását, leállítását és egyéb műveleteit, pl. gondoskodik a konténerek előállítását lehetővé tevő image-ek és fájlrendszerek kezeléséről, a hálózati beállításokról, a konténer üzeneteinek naplózásáról, de ez teszi lehetővé az állapotuk lekérdezését is.

Docker telepítése és konfigurálása

A Docker telepítése az egyes operációs rendszerekre nem túl bonyolult feladat, de a folyamat során esetenként felmerül egy-két nem triviális lépés. A telepítés Linuxon a legegyszerűbb, az alábbi módon hajtható végre. (Emlékeztető: a sudo parancs az azt követő parancsokat rendszergazda jogosultsággal hajtja végre.)

koczka@columbo:~# sudo apt install docker.io

A telepítés sikeressége a docker verziószámának megjelenítésével ellenőrizhető legegyszerűbben:

koczka@columbo:~$ docker -v
Docker version 24.0.5, build 24.0.5-0ubuntu1~20.04.1

Linuxon a konténerek futtatására és kezelésére biztonsági okokból csak azok a felhasználók jogosultak, akik tagjai a docker csoportnak. Egy felhasználó jogosítása is ezzel történik: a kiszemelt felhasználót a docker csoporthoz kell adni pl. a usermod -aG docker user paranccsal.

Windowson a telepítés valamivel bonyolultabb, részletes útmutató a Docker weboldalán található. Fontos, hogy bár Windows gépeken Windows és Linux konténerek is futtathatók, mi az utóbbival dolgozunk, ezért egy Linux kernelre is szükség lesz, amelyet a Docker indítása után egy (hiba)üzenetablakban a program jelezni is fog. A működéshez szükséges fájlt a Microsoft weboldaláról lehet letölteni. Itt a WSL2 Linux kernel update package for x64 machines link tartalmazza az aktuális verziót. A telepítés után újra kell indítani a gépet, majd újra elindítani a Docker Desktop alkalmazást. A program működőképességét az ablakának bal alsó sarkában látható docker ikon zöld háttere jelzi (a megfelelő állapot elérése esetenként 20-30 másodpercet is igénybe vesz).

alternateText

A Docker Desktop működés közben

A DockerHub

A konténerek népszerűségéhez nagyban hozzájárult egy olyan központi felhőalapú tárhely létrehozása, amelyben alkalmazások tárolhatók. A 2015-ben indult DockerHub nem csak számos kész konténert tartalmaz, hanem különböző könyvtárakban a regisztrált felhasználók saját konténereiket is elhelyezhetik és a felhasználási helyeiken letölthetik. A DockerHubról rengeteg alkalmazás konténerizált változata tölthető le, pl. különféle Linuxok, webszerverek, adatbáziskezelő rendszerek, vagy akár komplex futtató környezetek is. A hubról az egyes szoftverek különböző verziói is elérhetők lehetnek. A DockerHub webes felületének címe https://hub.docker.com.

alternateText

A DockerHub

Az oldalon tallózhatunk az egyes konténerek között (bár így megtalálni egy alkalmazást eléggé kilátástalan vállalkozás) de a beépített keresőt is alkalmazhatjuk. A fenti képen egy „hello world” nevű konténerre kerestem rá (ez lesz az első konténerünk, amit majd a következő fejezetben el is indítunk majd). Az alkalmazás neve mellett látható „jelvény” szerint ez egy „hivatalos docker konténer”, amit utoljára 13 nappal ezelőtt frissítettek. Az egyes rendszerek felsorolásában látható, hogy az nem csak az elterjedt operációs rendszerekre készült el, hanem ritkább architektúrákon, pl. a ma már nem annyira ismert PowerPC-n is elérhető. A DockerHubot érdemes megismerni, mert amellett, hogy számos alkalmazás innen tölthető le, használatával sok munkát megspórolhatunk, hiszen az itt megtalálható konténereket már csak használnunk kell, nem szükséges azok felépítésével saját magunknak bajlódni.

Figyelem

A DockerHub és a konténerek használatával kapcsolatban azért felmerül a kérdés, hogy egy esetleges „docker apokalipszis” esetén hogyan lehet majd a rendszerek működését fenntartani. A konténertechnológia alkalmazása esetén ki vagyunk téve DockerHub szolgáltatásainak, amelyet – ha a tulajdonosa valamilyen okból bezár – többé nem tudunk majd elérni. Részleges megoldást az jelenthet, ha saját konténerbázist alakítunk ki, de ez már nem annyira egyszerű feladat.

Összefoglalás

A Docker az egyik legnépszerűbb konténerizációs rendszer, amely a Linux kernel képességeire építve kényelmesen kezelhető és meglehetősen biztonságos fejlesztői és üzemeltetői környezetet biztosít nem csak Linuxot, hanem mellett Windows-t vagy MacOS operációs rendszert futtató számítógépeken is. Ebben a fejezetben megismertük a konténerizáció alapelveit, a Docker architektúráját és összetevőit, valamint az operációs rendszer azon szolgáltatásait, amelyek nélkülözhetetlenek a technológia működéséhez. Láttuk a névterek, a kontroll csoportok, valamint a union fájlrendszer szerepét a konténerek szeparációjában és az erőforrások igénybevételének szabályozásában. Áttekintettük a Docker telepítésének folyamatát, a WSL2 kernel telepítését, valamint a DockerHub főbb funkcióit is.

Kérdések, feladatok

  1. Milyen operációs rendszereken használható a Docker?

  2. Milyen hardveren futtathatók Docker konténerek? Keress különböző architektúrákat a DockerHubon!

  3. Mi a különbség a konténerek és a virtuális gépek között?

  4. Mik a Docker architektúrájának főbb elemei?

  5. Mi a szerepe a Linux kernel névtereinek (namespaces) a Docker működésében?

  6. Hogyan segítik a kontroll csoportok (cgroups) a Docker működését?

  7. Mi a Union fájlrendszer (UnionFS), és hogyan működik?

  8. Milyen fő összetevőkből áll a Docker motor (Docker Engine)?

  9. Hogyan lehet telepíteni a Dockert Linux rendszeren?

  10. Hogyan lehet ezt megtenni Windows és MacOS rendszereken?

  11. Mi a WSL2 és miért van rá szükség?

  12. Hogyan lehet a Dockert elindítani és leállítani az egyes operációs rendszereken?

  13. Mi a DockerHub, és milyen szolgáltatásai vannak?