Mi az a Docker: egy rövid kirándulás a történelembe és az alapvető absztrakciókba

Augusztus 10-én kezdődött Slurmban Docker videó tanfolyam, amelyben teljes egészében elemezzük – az alapvető absztrakcióktól a hálózati paraméterekig.

Ebben a cikkben a Docker történetéről és főbb absztrakcióiról fogunk beszélni: Image, Cli, Dockerfile. Az előadás kezdőknek szól, így nem valószínű, hogy a tapasztalt felhasználók számára érdekes lesz. Nem lesz vér, vakbél vagy mély merítés. A nagyon alapokat.

Mi az a Docker: egy rövid kirándulás a történelembe és az alapvető absztrakciókba

Mi az a Docker

Nézzük meg a Docker definícióját a Wikipédiából.

A Docker olyan szoftver, amely automatizálja az alkalmazások telepítését és kezelését konténeres környezetekben.

Ebből a meghatározásból semmi sem derül ki. Különösen homályos, hogy mit jelent a „konténerezést támogató környezetben”. Hogy megtudjuk, menjünk vissza az időben. Kezdjük azzal a korszakkal, amelyet hagyományosan „monolit korszaknak” nevezek.

Monolitikus korszak

A monolitikus korszak a 2000-es évek eleje, amikor minden alkalmazás monolitikus volt, egy csomó függőséggel. A fejlesztés sokáig tartott. Ugyanakkor nem volt sok szerver, mind név szerint ismertük és figyeltük őket. Van egy vicces összehasonlítás:

A házi kedvencek háziállatok. A monolitikus korszakban úgy kezeltük szervereinket, mint háziállatokat, ápolva és dédelgetettük, és elfújtuk a porszemeket. A jobb erőforrás-kezelés érdekében pedig virtualizációt alkalmaztunk: vettünk egy szervert, és több virtuális gépre vágtuk, ezzel biztosítva a környezet elszigetelését.

Hypervisor alapú virtualizációs rendszerek

Valószínűleg mindenki hallott már a virtualizációs rendszerekről: VMware, VirtualBox, Hyper-V, Qemu KVM stb. Alkalmazásizolációt és erőforrás-kezelést biztosítanak, de vannak hátrányai is. A virtualizáció elvégzéséhez hipervizorra van szükség. A hypervisor pedig egy többletköltség. Maga a virtuális gép pedig általában egy egész kolosszus – egy nehéz kép, amely operációs rendszert, Nginxet, Apache-t és esetleg MySQL-t tartalmaz. A kép nagy, és a virtuális gép kezelése kényelmetlen. Ennek eredményeként a virtuális gépekkel való munka lassú lehet. A probléma megoldására a virtualizációs rendszereket kernel szinten hoztak létre.

Kernel szintű virtualizációs rendszerek

A kernelszintű virtualizációt az OpenVZ, Systemd-nspawn és LXC rendszerek támogatják. Az ilyen virtualizáció szembetűnő példája az LXC (Linux Containers).

Az LXC egy operációs rendszer szintű virtualizációs rendszer a Linux operációs rendszer több izolált példányának egyetlen csomóponton történő futtatására. Az LXC nem használ virtuális gépeket, hanem virtuális környezetet hoz létre saját folyamatterével és hálózati veremével.

Az LXC lényegében konténereket hoz létre. Mi a különbség a virtuális gépek és a konténerek között?

Mi az a Docker: egy rövid kirándulás a történelembe és az alapvető absztrakciókba

A tároló nem alkalmas folyamatok elkülönítésére: a virtualizációs rendszerekben kernel szinten találtak sebezhetőségeket, amelyek lehetővé teszik, hogy a tárolóból a gazdagépre meneküljenek. Ezért, ha el kell különíteni valamit, jobb, ha virtuális gépet használ.

A virtualizáció és a konténerezés közötti különbségek az ábrán láthatók.
Vannak hardveres hipervizorok, hipervizorok az operációs rendszer tetején és tárolók.

Mi az a Docker: egy rövid kirándulás a történelembe és az alapvető absztrakciókba

A hardveres hipervizorok nagyszerűek, ha valóban el akarunk különíteni valamit. Mert lehetséges a memórialapok és processzorok szintjén elkülöníteni.

Léteznek hipervizorok, mint program, és vannak konténerek, és róluk fogunk még beszélni. A tárolórendszerek nem rendelkeznek hipervizorral, de létezik egy Container Engine, amely konténereket hoz létre és kezel. Ez a dolog könnyebb, így a maggal való munka miatt kevesebb a többletköltség, vagy egyáltalán nincs.

Mit használnak a konténerezéshez a kernel szintjén

A főbb technológiák, amelyek lehetővé teszik más folyamatoktól elkülönített tároló létrehozását, a névterek és a vezérlőcsoportok.

Névterek: PID, Networking, Mount és User. Több is van, de a könnyebb érthetőség kedvéért ezekre fogunk összpontosítani.

A PID névtér korlátozza a folyamatokat. Ha például létrehozunk egy PID névteret, és elhelyezünk egy folyamatot, akkor az PID 1 lesz. Általában a rendszerekben a PID 1 systemd vagy init. Ennek megfelelően, amikor egy folyamatot egy új névtérbe helyezünk, az is megkapja a PID 1-et.

A hálózati névtér lehetővé teszi a hálózat korlátozását/elszigetelését, és saját interfészek elhelyezését. A csatlakoztatás a fájlrendszer korlátozása. Felhasználó – a felhasználók korlátozása.

Vezérlőcsoportok: memória, CPU, IOPS, hálózat - összesen körülbelül 12 beállítás. Egyébként C-csoportoknak (C-csoportoknak) is nevezik őket.

A vezérlőcsoportok kezelik a tároló erőforrásait. A vezérlőcsoportokon keresztül azt mondhatjuk, hogy a konténer nem fogyaszthat többet egy bizonyos mennyiségű erőforrásnál.

A konténerezés teljes körű működéséhez további technológiákat használnak: Képességek, Másolás írásban és mások.

A képességek az, amikor megmondjuk egy folyamatnak, hogy mit tehet és mit nem. Kernel szinten ezek egyszerűen bittérképek sok paraméterrel. Például a root felhasználó teljes jogosultsággal rendelkezik, és mindent megtehet. Az időszerver megváltoztathatja a rendszeridőt: a Time Capsule-ban vannak képességei, és ennyi. A jogosultságok használatával rugalmasan konfigurálhatja a folyamatok korlátozásait, és ezáltal megvédheti magát.

A Copy-on-Write rendszer lehetővé teszi, hogy Docker-képekkel dolgozzunk, és hatékonyabban használjuk azokat.

A Docker jelenleg kompatibilitási problémákkal küzd a Cgroups v2-vel, ezért ez a cikk kifejezetten a Cgroups v1-re összpontosít.

De térjünk vissza a történelemhez.

Amikor a virtualizációs rendszerek megjelentek a kernel szintjén, elkezdték aktívan használni őket. A hypervisor rezsije eltűnt, de néhány probléma megmaradt:

  • nagy képek: ugyanabba az OpenVZ-be betolnak egy operációs rendszert, könyvtárakat, egy rakás különböző szoftvert, és a végén még mindig elég nagynak bizonyul a kép;
  • Nincs normális szabvány a csomagolásra és a szállításra, így a függőségek problémája továbbra is fennáll. Vannak olyan helyzetek, amikor két kódrészlet ugyanazt a könyvtárat használja, de különböző verziókkal. Konfliktus lehet köztük.

Mindezen problémák megoldására eljött a következő korszak.

Konténer korszak

Amikor elérkezett a konténerek korszaka, a velük való munka filozófiája megváltozott:

  • Egy folyamat - egy tartály.
  • A folyamathoz szükséges összes függőséget a tárolójába szállítjuk. Ehhez a monolitokat mikroszolgáltatásokba kell vágni.
  • Minél kisebb a kép, annál jobb – kevesebb a lehetséges sebezhetőség, gyorsabban gördül ki stb.
  • Az esetek mulandóvá válnak.

Emlékszel, mit mondtam a háziállatokról a szarvasmarhákról? Korábban az esetek olyanok voltak, mint a háziállatok, de most olyanokká váltak, mint a szarvasmarha. Korábban volt egy monolit - egy alkalmazás. Most 100 mikroszolgáltatás, 100 konténer. Egyes tárolóknak 2-3 másolata lehet. Kevésbé válik számunkra minden tartály ellenőrzése. Számunkra sokkal fontosabb magának a szolgáltatásnak az elérhetősége: mit csinál ez a konténerkészlet. Ez megváltoztatja a monitoring megközelítését.

2014-2015-ben a Docker virágzott – ez a technológia, amelyről most beszélni fogunk.

A Docker megváltoztatta a filozófiát és szabványosította az alkalmazáscsomagolást. A Docker segítségével becsomagolhatunk egy alkalmazást, elküldhetjük egy tárolóba, onnan letölthetjük és telepíthetjük.

Mindent a Docker konténerbe teszünk, amire szükségünk van, így a függőségi probléma megoldódik. A Docker garantálja a reprodukálhatóságot. Szerintem sokan találkoztak már a reprodukálhatatlansággal: neked minden működik, rátolod a gyártásra, és ott leáll. A Dockerrel ez a probléma megszűnik. Ha a Docker-tároló elindul, és megteszi, amit tennie kell, akkor nagy valószínűséggel beindul a termelés, és ott is ugyanezt teszi.

Kitérő a rezsiről

A rezsiről mindig vannak viták. Vannak, akik úgy vélik, hogy a Docker nem hordoz további terhelést, mivel a Linux kernelt és a konténerezéshez szükséges összes folyamatát használja. Például: „ha azt mondod, hogy a Docker többletköltség, akkor a Linux kernel is többletköltség.”

Másrészt, ha mélyebbre megyünk, akkor valóban több olyan dolog van a Dockerben, ami egy húzással rezsinek mondható.

Az első a PID névtér. Amikor egy folyamatot elhelyezünk egy névtérben, az 1-es PID-t kapja. Ugyanakkor ennek a folyamatnak van egy másik PID-je is, amely a gazdagép névterében, a tárolón kívül található. Például elindítottuk az Nginxet egy konténerben, PID 1 lett (master process). A gazdagépen pedig PID 12623. És nehéz megmondani, hogy mekkora rezsi.

A második dolog a Cgroups. Vegyük a Ccsoportokat memória szerint, vagyis azt a képességet, hogy korlátozzuk egy konténer memóriáját. Ha engedélyezve van, aktiválódnak a számlálók és a memória elszámolása: a kernelnek tudnia kell, hogy hány oldal van lefoglalva, és hány szabad még ehhez a tárolóhoz. Ez valószínűleg többletköltség, de nem láttam pontos tanulmányt arról, hogy ez hogyan befolyásolja a teljesítményt. És én magam sem vettem észre, hogy a Dockerben futó alkalmazás hirtelen erős teljesítménycsökkenést tapasztalt.

És még egy megjegyzés a teljesítményről. Néhány kernelparaméter a gazdagéptől a tárolóba kerül. Különösen néhány hálózati paraméter. Ezért ha valami nagy teljesítményt szeretne futtatni a Dockerben, például valamit, ami aktívan használja a hálózatot, akkor legalább módosítania kell ezeket a paramétereket. Például néhány nf_conntrack.

A Docker koncepcióról

A Docker több összetevőből áll:

  1. A Docker Daemon ugyanaz a Container Engine; konténereket indít.
  2. A Docker CII egy Docker felügyeleti segédprogram.
  3. Dockerfile – utasítások a kép készítéséhez.
  4. Kép – az a kép, amelyből a tartályt kigördítik.
  5. Tartály.
  6. A Docker registry egy képtár.

Sematikusan valahogy így néz ki:

Mi az a Docker: egy rövid kirándulás a történelembe és az alapvető absztrakciókba

A Docker démon a Docker_host rendszeren fut, és elindítja a konténereket. Van egy kliens, amely parancsokat küld: készítse el a képet, töltse le a képet, indítsa el a tárolót. A Docker démon belép a rendszerleíró adatbázisba, és végrehajtja azokat. A Docker kliens helyileg (Unix sockethez) és TCP-n keresztül egy távoli gazdagépről is elérheti.

Nézzük végig az egyes összetevőket.

Docker démon - ez a szerver rész, a gazdagépen működik: képeket tölt le és konténereket indít azokról, hálózatot hoz létre a konténerek között, naplókat gyűjt. Amikor azt mondjuk, hogy „alkoss képet”, a démon is ezt teszi.

Docker CLI — Docker kliens rész, konzol segédprogram a démonnal való munkához. Ismétlem, nem csak helyben, hanem hálózaton keresztül is tud működni.

Alapvető parancsok:

docker ps – a Docker gazdagépen jelenleg futó konténerek megjelenítése.
docker images – helyileg letöltött képek megjelenítése.
docker keresés <> - kép keresése a rendszerleíró adatbázisban.
docker pull <> - egy kép letöltése a rendszerleíró adatbázisból a gépre.
dokkoló épít < > - gyűjtsük össze a képet.
docker run <> - indítsa el a tárolót.
docker rm <> - távolítsa el a tárolót.
dokkolónaplók <> - konténernaplók
docker start/stop/restart <> - a tárolóval való munka

Ha elsajátítja ezeket a parancsokat, és magabiztosan használja őket, tekintse magát 70%-ban jártasnak a Dockerben felhasználói szinten.

dockerfile - utasítások a kép létrehozásához. Szinte minden utasítás parancs egy új réteg. Nézzünk egy példát.

Mi az a Docker: egy rövid kirándulás a történelembe és az alapvető absztrakciókba

Így néz ki a Dockerfile: parancsok a bal oldalon, argumentumok a jobb oldalon. Minden itt található (és általában a Dockerfile-ban írt) parancs új réteget hoz létre az Image-ben.

Még a bal oldalra nézve is nagyjából megértheti, mi történik. Azt mondjuk: „hozzon létre egy mappát nekünk” - ez egy réteg. „Tegye működőképessé a mappát” egy másik réteg, és így tovább. A réteges torta megkönnyíti az életet. Ha létrehozok egy másik Docker-fájlt, és módosítok valamit az utolsó sorban – a „python” „main.py” helyett mást futtatok, vagy egy másik fájlból telepítek függőséget –, akkor az előző rétegek gyorsítótárként lesznek felhasználva.

Kép - ez konténeres csomagolás, a konténerek a képről indulnak. Ha a Dockert egy csomagkezelő szemszögéből nézzük (mintha deb vagy rpm csomagokkal dolgoznánk), akkor az image lényegében egy rpm csomag. A yum install segítségével telepíthetjük az alkalmazást, törölhetjük, megkereshetjük a tárolóban és letölthetjük. Körülbelül ugyanez itt is: a konténerek a képről indulnak el, a Docker registry-ben tárolódnak (a yumhoz hasonlóan, egy repositoryban), és minden képhez tartozik egy SHA-256 hash, egy név és egy címke.

A kép a Dockerfile utasításai szerint épül fel. A Dockerfile minden egyes utasítása új réteget hoz létre. A rétegek újra felhasználhatók.

Docker nyilvántartás egy Docker képtár. Az operációs rendszerhez hasonlóan a Dockernek is van egy nyilvános szabványos nyilvántartása - dockerhub. De létrehozhatja saját tárolóját, saját Docker-nyilvántartását.

Konténer - mi indul el a képről. A Dockerfile utasításai szerint készítettünk egy képet, majd ebből a képből indítjuk el. Ez a tároló el van szigetelve más tárolóktól, és mindent tartalmaznia kell, ami az alkalmazás működéséhez szükséges. Ebben az esetben egy tartály - egy folyamat. Előfordul, hogy két folyamatot kell végrehajtania, de ez némileg ellentétes a Docker-ideológiával.

Az „egy tároló, egy folyamat” követelmény a PID névtérhez kapcsolódik. Amikor egy PID 1-es folyamat elindul a névtérben, ha hirtelen elhal, akkor az egész tároló is elhal. Ha két folyamat fut ott: az egyik él, a másik halott, akkor a konténer továbbra is élni fog. De ez a legjobb gyakorlatok kérdése, ezekről más anyagokban fogunk beszélni.

A kurzus jellemzőinek és teljes programjának részletesebb megismeréséhez kövesse az alábbi linket: "Docker videó tanfolyam".

Szerző: Marcel Ibraev, okleveles Kubernetes-adminisztrátor, gyakorló mérnök a Southbridge-nél, előadó és a Slurm tanfolyamok fejlesztője.

Forrás: will.com

Hozzászólás