Modul 9 · 9.1
A konténerek megértése
Modul 9: Docker és docker compose · Olvasási idő: 10 perc
Tanulási cél: A lecke után el tudja magyarázni, mi a konténer, miben különbözik egy virtuális géptől, hol maradnak meg egy konténer adatai, és mikor van értelme Dockert használni a szerverén.
Kulcsfogalmak: image, konténer, réteg, registry (Docker Hub), tag, digest, namespace-ek, cgroupok, közös kernel, illékony fájlrendszer, volume, bind mount, port közzététele, hivatalos image
Miért konténerek?
Tegyük fel, hogy a VPS-én egy állapotoldalt szeretne futtatni, amely megmutatja, működik-e a webhelye. A program Node.js-ben készült, annak egy bizonyos verziójára van szüksége, és még nagyjából kétszáz könyvtárra. Konténerek nélkül mindezt a szerverére telepíti, a webszervere és az adatbázisa mellé. Egy évvel később egy második programot szeretne, amelynek egy másik Node.js-verzió kell. Ekkor kezdődik a fejtörés.
A konténer ezt oldja meg. A program készítője a programot mindazzal együtt szállítja, amire szüksége van, egyetlen csomagban: ez az image. A szerverén ezt az image-et konténerként indítja el. A program a saját fájljait, a saját Node.js-ét, a saját könyvtárait látja, és nem ütközik a szerver többi részével. Nincs rá többé szükség? Törli a konténert és az image-et, és semmi sem marad utána a /usr vagy a /etc könyvtárban.
A Docker a legismertebb eszköz az image-ek letöltésére és a konténerek futtatására. Vannak alternatívák (Podman, maga a containerd), de a fogalmak mindenhol ugyanazok.
Image, konténer és registry
Három szó, amellyel folyamatosan találkozni fog:
- Image: csak olvasható sablon, amely egy fájlrendszert (program, könyvtárak, beállítások) és az indítandó parancsot tartalmazza. Egy image rétegekből épül fel: egy alapréteg (például egy csupasz Debian), erre egy réteg a Node.js-szel, erre pedig a program. Két azonos alaprétegű image ezt a réteget közösen használja a lemezén.
- Konténer: egy image futó (vagy leállított) példánya. A csak olvasható rétegek fölött a konténer saját, vékony írható réteget kap. Egyetlen image-ből tíz konténert is indíthat.
- Registry: az a hely, ahol az image-ek tárolódnak, például a Docker Hub (
docker.io) vagy a GitHub registryje (ghcr.io). A Docker adocker pullparanccsal tölt le egy image-et.
Egy image neve így néz ki:
louislam/uptime-kuma:2
caddy:2
vaultwarden/server:latestA kettőspont utáni rész a tag: egy verziót jelölő címke. Egy tag megváltozhat: a caddy:2 ma egy másik buildre mutat, mint három hónap múlva, amint megjelenik egy új 2.x. Ha pontosan rögzíteni szeretné, melyik image-et futtatja, használja a digestet: ez a tartalom ujjlenyomata, például caddy@sha256:.... Ez soha nem változik. A latest tag egyszerűen egy név, amelyet a készítő választ; nem jelenti automatikusan azt, hogy "a legújabb stabil verzió", ezért rossz választás, ha tudni szeretné, mi fut.
Nem virtuális gép
Egy konténer hasonlít egy kis virtuális gépre, de nem az. Ez a különbség a biztonság szempontjából fontos.
| Virtuális gép (mint az Ön VPS-e) | Konténer | |
|---|---|---|
| Kernel | Saját kernel | A gazdagép kernelét használja közösen |
| Indulás | Másodpercektől percekig, egy teljes operációs rendszer | Általában egy másodpercen belül, csak a program |
| Elkülönítés | A hypervisor végzi, hardverszinten | A kernel végzi: namespace-ek és cgroupok |
| Méret | Gigabájtok | Gyakran néhány tíz vagy néhány száz megabájt |
Egy konténer valójában egy közönséges folyamat a szerverén, amelyet a kernel elszigetelt környezetbe helyez:
- a namespace-ek gondoskodnak arról, hogy a folyamatnak saját nézete legyen a fájlokról, folyamatokról, a hálózatról és a felhasználókról. A konténerben a program úgy látja, mintha ő lenne az 1-es számú folyamat, és nem látja a szerver többi részét;
- a cgroupok korlátozzák, mennyi processzort és memóriát használhat.
Mivel minden konténer ugyanazt a kernelt használja, az elkülönítés kevésbé szigorú, mint két VPS között. Egy kernelhiba vagy egy túl sok jogosultságot kapó konténer a gazdagépet is érintheti. Ezért érvényesek ennek a modulnak a szabályai: csak megbízható image-eket futtasson, ne adjon a konténereknek több jogosultságot a szükségesnél, és soha ne csatolja a /var/run/docker.sock vagy a / útvonalat egy konténerbe (9.3. és 10.2. lecke).
Hol maradnak az adatai?
Ez a kezdők klasszikus csapdája. A konténer írható rétege illékony: ha törli a konténert (például frissítéskor, 9.4. lecke), akkor minden, amit a program oda írt, elvész. A megőrizendő adatok ezért a konténeren kívülre valók:
- Volume: olyan tárhely, amelyet maga a Docker kezel (a
/var/lib/docker/volumes/alatt). Nevet ad neki, példáuluptime-kuma, és a konténer egy könyvtárához csatolja:-v uptime-kuma:/app/data. - Bind mount: a szerverén lévő közönséges könyvtár, amelyet a konténerbe csatol:
-v /srv/vaultwarden:/data. Praktikus, mert a fájlokat közvetlenül látja, és könnyen a biztonsági mentésébe (8. modul) veheti.
Egy jól beállított volume-okkal rendelkező konténert eldobhat és újra létrehozhat anélkül, hogy bármit elveszítene. Pontosan így működik a frissítés: új image letöltése, a régi konténer törlése, új konténer ugyanazokkal a volume-okkal. Ezért vegye fel a volume-okat a biztonsági mentési tervébe (8.1. lecke).
Portok közzététele
Egy konténernek saját hálózata van. Egy webes program, amely a konténerben a 3001-es porton figyel, a szerveren kívülről nem érhető el, amíg ezt a portot közzé nem teszi: -p 3001:3001 (gazdagépport:konténerport). Figyelem: cím megadása nélkül a Docker a szerver összes címén közzéteszi a portot, tehát a 0.0.0.0 és a [::] címen is. Ez azt jelenti: az egész internetről elérhető, és a Docker ezt az ufw megkerülésével intézi (9.3. lecke). A biztonságos szokás a loopback címen történő közzététel, -p 127.0.0.1:3001:3001, elé pedig egy https-t használó reverse proxy (9.4. lecke).
Ki készíti az image-et?
Egy image valaki más szoftvere, amely rootként futhat a szerverén. Ezért nézze meg, ki a készítője:
- a Docker Official Images (például
caddy,nginx,postgres) karbantartását a Docker a készítőkkel közösen végzi; - maguknak a készítőknek az image-ei (például
louislam/uptime-kumaésvaultwarden/server), amelyeket arról ismer fel, hogy a projekt webhelye ezt a nevet adja meg; - ismeretlenek image-ei, hasonló hangzású nevekkel: ezeket ne használja.
Mindig azt a nevet használja, amely a projekt hivatalos webhelyén szerepel, ne azt, amelyet egy keresés elsőként kidob.
Mikor igen, mikor nem?
A Docker praktikus olyan programokhoz, amelyeket a készítő image-ként szállít, olyan szolgáltatásokhoz, amelyeket gyorsan el szeretne dobni vagy át szeretne költöztetni, és ahhoz, hogy több, eltérő igényű programot futtasson egymás mellett. A szervere alapjaihoz (SSH, tűzfal, frissítések) nem használ konténereket. Egyetlen webhely pedig nginx-szel és a csomagforrásból telepített PHP-vel (7.2. lecke) Docker nélkül is kiválóan működik. Egy konténer újabb réteget jelent, amelyet értenie és frissítenie kell; akkor használja, ha haszna van.
Összefoglalás
- Az image rétegekből álló, csak olvasható sablon; a konténer ennek futó példánya saját írható réteggel.
- A konténerek a gazdagép kernelét használják közösen, és namespace-ekkel, valamint cgroupokkal vannak elszigetelve: könnyebbek egy VM-nél, de kevésbé szigorúan elkülönítettek.
- Az írható réteg illékony: a tartós adatok helye egy volume vagy bind mount, és ezeknek a biztonsági mentésben a helyük.
- Egy tag megváltozhat, egy digest nem; a
latestkeveset mond. - A portokat a 127.0.0.1 címen tegye közzé, és csak a készítő saját vagy hivatalos image-eit használja.
Kvíz
Feladat
O9.1. feladat: Konténer vagy sem? Válasszon ki két programot, amelyet a szerverén szeretne futtatni (vagy példaként használja az Uptime Kumát és egy WordPress-webhelyet). Programonként nézzen utána, hogy a készítő szállít-e hivatalos image-et, és milyen néven, melyik taget választaná, melyik könyvtár tartalmazza a tartós adatokat, és melyik porton figyel a program. Ezután magyarázza el, hogy konténerben vagy a csomagforrásból futtatná-e, és miért.
O9.1. feladat: Konténer vagy sem?
Ezt a feladatot saját maga végzi el, senki nem ellenőrzi. Pipálja ki, amit elvégzett, és jelölje meg a feladatot elvégzettként.
Uptime Kuma: louislam/uptime-kuma verziócímkével, adatok az /app/data mappában, 3001-es port, közzététel a(z) 127.0.0.1 címen egy reverse proxy mögött. Válasszon a készítőtől származó image-et vagy Official Image-et, verziócímkével és elnevezett adatmappával.
A pipái és jegyzetei csak ebben a böngészőben maradnak meg, sehova nem küldjük el őket. Ha bejelentkezett, a Fiókomban csak azt tároljuk, hogy elvégezte a feladatot.
További olvasnivaló
- Docker-dokumentáció, What is a container?: https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-a-container/
- Docker-dokumentáció, Volumes: https://docs.docker.com/engine/storage/volumes/
- Docker-dokumentáció, Port publishing and mapping: https://docs.docker.com/engine/network/port-publishing/
- Docker Official Images: https://docs.docker.com/docker-hub/repos/manage/trusted-content/official-images/
