Modul 9 · 9.1
Porozumenie kontajnerom
Modul 9: Docker a docker compose · Čas čítania: 10 minút
Cieľ lekcie: Po tejto lekcii dokážete vysvetliť, čo je kontajner, ako sa líši od virtuálneho stroja, kde zostávajú údaje kontajnera a kedy má Docker na vašom serveri zmysel.
Kľúčové pojmy: image (obraz), kontajner, vrstva, registry (Docker Hub), tag, digest, namespaces, cgroups, zdieľané jadro, nestály súborový systém, volume, bind mount, publikovanie portu, oficiálny obraz
Prečo kontajnery?
Predstavte si, že na svojom VPS chcete prevádzkovať stavovú stránku, ktorá ukazuje, či váš web funguje. Program je napísaný v Node.js, potrebuje jeho konkrétnu verziu a k tomu zhruba dvesto knižníc. Bez kontajnerov to všetko nainštalujete priamo na server, vedľa webového servera a databázy. O rok neskôr chcete druhý program, ktorý potrebuje inú verziu Node.js. A začína sa skladačka.
Kontajner tento problém rieši. Autor programu dodá program spolu so všetkým, čo potrebuje, v jednom balíku: v obraze (image). Na serveri tento obraz spustíte ako kontajner. Program vidí svoje vlastné súbory, svoj vlastný Node.js, svoje vlastné knižnice a nekoliduje so zvyškom vášho servera. Už ho nepotrebujete? Odstránite kontajner aj obraz a v /usr ani v /etc nič nezostane.
Docker je najznámejší nástroj na sťahovanie obrazov a spúšťanie kontajnerov. Existujú aj alternatívy (Podman, samotný containerd), pojmy sú však všade rovnaké.
Obraz, kontajner a registry
Tri slová, s ktorými sa budete stretávať stále:
- Obraz (image): šablóna len na čítanie so súborovým systémom (program, knižnice, nastavenia) a príkazom, ktorý sa má spustiť. Obraz sa skladá z vrstiev: základná vrstva (napríklad holý Debian), nad ňou vrstva s Node.js a nad ňou samotný program. Dva obrazy s rovnakou základnou vrstvou túto vrstvu na disku zdieľajú.
- Kontajner: bežiaca (alebo zastavená) inštancia obrazu. Nad vrstvami len na čítanie dostane kontajner vlastnú tenkú zapisovaciu vrstvu. Z jedného obrazu môžete spustiť desať kontajnerov.
- Registry: miesto, kde sú obrazy uložené, napríklad Docker Hub (
docker.io) alebo registry GitHubu (ghcr.io). Docker stiahne obraz príkazomdocker pull.
Názov obrazu vyzerá takto:
louislam/uptime-kuma:2
caddy:2
vaultwarden/server:latestČasť za dvojbodkou je tag: označenie verzie. Tag sa môže meniť: caddy:2 dnes ukazuje na iný build ako o tri mesiace, keď vyjde nová verzia 2.x. Ak chcete presne zaznamenať, ktorý obraz prevádzkujete, použite digest: odtlačok obsahu, napríklad caddy@sha256:.... Ten sa nikdy nezmení. Tag latest je len názov, ktorý si zvolí autor; automaticky neznamená „najnovšia stabilná verzia“, a preto je to zlá voľba, ak chcete vedieť, čo vlastne beží.
Nie je to virtuálny stroj
Kontajner sa podobá na malý virtuálny stroj, ale nie je ním. Tento rozdiel je dôležitý pre bezpečnosť.
| Virtuálny stroj (ako váš VPS) | Kontajner | |
|---|---|---|
| Jadro | Vlastné jadro | Zdieľa jadro hostiteľa |
| Spustenie | Sekundy až minúty, celý operačný systém | Väčšinou do sekundy, iba program |
| Oddelenie | Hypervízorom, na úrovni hardvéru | Jadrom: namespaces a cgroups |
| Veľkosť | Gigabajty | Často desiatky až stovky megabajtov |
Kontajner je v skutočnosti obyčajný proces na vašom serveri, ktorý jadro umiestni do izolovaného prostredia:
- namespaces zabezpečia, že proces má vlastný pohľad na súbory, procesy, sieť a používateľov. V kontajneri sa programu zdá, že je procesom číslo 1, a zvyšok vášho servera nevidí;
- cgroups obmedzujú, koľko procesora a pamäte môže používať.
Keďže všetky kontajnery zdieľajú to isté jadro, oddelenie je menej prísne ako medzi dvoma VPS. Chyba v jadre alebo kontajner s príliš veľkými právami môže zasiahnuť hostiteľa. Preto platia pravidlá z tohto modulu: spúšťajte iba obrazy, ktorým dôverujete, nedávajte kontajnerom viac práv, než potrebujú, a nikdy do kontajnera nepripájajte /var/run/docker.sock ani / (lekcia 9.3 a 10.2).
Kde zostávajú vaše údaje?
Toto je klasická pasca pre začiatočníkov. Zapisovacia vrstva kontajnera je nestála: ak kontajner odstránite (napríklad pri aktualizácii, lekcia 9.4), všetko, čo do nej program zapísal, zmizne. Údaje, ktoré musia zostať, preto patria mimo kontajnera:
- Volume: úložisko, ktoré spravuje samotný Docker (v
/var/lib/docker/volumes/). Dáte mu názov, napríkladuptime-kuma, a pripojíte ho k priečinku v kontajneri:-v uptime-kuma:/app/data. - Bind mount: obyčajný priečinok na vašom serveri, ktorý pripojíte do kontajnera:
-v /srv/vaultwarden:/data. Je to praktické, pretože súbory vidíte priamo a ľahko ich zahrniete do zálohy (modul 8).
Kontajner s dobre nastavenými volumes môžete zahodiť a vytvoriť znova bez akejkoľvek straty. Presne tak funguje aktualizácia: stiahnuť nový obraz, odstrániť starý kontajner, spustiť nový kontajner na tých istých volumes. Zaraďte preto volumes do svojho plánu záloh (lekcia 8.1).
Publikovanie portov
Kontajner má vlastnú sieť. Webový program, ktorý v kontajneri počúva na porte 3001, nie je zvonku servera dostupný, kým tento port nepublikujete: -p 3001:3001 (port hostiteľa:port kontajnera). Pozor: bez adresy Docker publikuje port na všetkých adresách vášho servera, teda 0.0.0.0 aj [::]. To znamená dostupnosť z celého internetu, a Docker to zariadi mimo ufw (lekcia 9.3). Bezpečný zvyk je publikovať na loopback, -p 127.0.0.1:3001:3001, a pred to postaviť reverse proxy s https (lekcia 9.4).
Kto vytvoril obraz?
Obraz je softvér niekoho iného, ktorý môže na vašom serveri bežať ako root. Preto si overte, kto je jeho autorom:
- Docker Official Images (napríklad
caddy,nginx,postgres) udržiava Docker spolu s autormi; - obrazy od samotného autora (napríklad
louislam/uptime-kumaavaultwarden/server) rozpoznáte podľa názvu, ktorý uvádza webová stránka projektu; - obrazy od neznámych autorov s podobne znejúcimi názvami: nepoužívať.
Vždy použite názov uvedený na oficiálnej webovej stránke projektu, nie prvý, ktorý vám ponúkne vyhľadávanie.
Kedy áno, kedy nie?
Docker sa hodí pre programy, ktoré autor dodáva ako obraz, pre služby, ktoré chcete vedieť rýchlo zahodiť alebo presunúť, a na prevádzku viacerých programov s rôznymi požiadavkami vedľa seba. Na základ vášho servera (SSH, firewall, aktualizácie) kontajnery nepoužívajte. A jednoduchý web s nginx a PHP z repozitára balíkov (lekcia 7.2) funguje bez Dockeru výborne. Kontajner pridáva vrstvu, ktorej musíte rozumieť a ktorú musíte aktualizovať; používajte ho vtedy, keď vám niečo prináša.
Zhrnutie
- Obraz je šablóna len na čítanie zložená z vrstiev; kontajner je bežiaca inštancia s vlastnou zapisovacou vrstvou.
- Kontajnery zdieľajú jadro hostiteľa a sú izolované pomocou namespaces a cgroups: sú ľahšie ako VM, ale menej prísne oddelené.
- Zapisovacia vrstva je nestála: trvalé údaje patria do volume alebo bind mount a tie patria do vašej zálohy.
- Tag sa môže zmeniť, digest nie;
latesttoho veľa nehovorí. - Porty publikujte na 127.0.0.1 a používajte iba obrazy od autora alebo oficiálne obrazy.
Kvíz
Úloha
Úloha O9.1: Kontajner, alebo nie? Vyberte si dva programy, ktoré chcete na svojom serveri prevádzkovať (alebo ako príklad použite Uptime Kuma a web na WordPress). Pre každý program zistite, či autor dodáva oficiálny obraz a pod akým názvom, aký tag by ste zvolili, ktorý priečinok obsahuje trvalé údaje a na akom porte program počúva. Potom vysvetlite, či by ste ho prevádzkovali v kontajneri, alebo z repozitára balíkov, a prečo.
Úloha O9.1: Kontajner, alebo nie?
Túto úlohu vykonávate sami, nikto ju nekontroluje. Odškrtnite, čo ste urobili, a označte úlohu ako splnenú.
Uptime Kuma: louislam/uptime-kuma s tagom verzie, údaje v /app/data, port 3001, publikovať na 127.0.0.1 za reverse proxy. Vyberte image od autora alebo Official Image, s tagom verzie a pomenovaným priečinkom na údaje.
Vaše zaškrtnutia a poznámky zostávajú iba v tomto prehliadači, nikam ich neposielame. Po prihlásení si v sekcii Moje kurzy uchovávame iba to, že ste úlohu splnili.
Ďalšie čítanie
- Dokumentácia Dockeru, What is a container?: https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-a-container/
- Dokumentácia Dockeru, Volumes: https://docs.docker.com/engine/storage/volumes/
- Dokumentácia Dockeru, 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/
