Kontejner je jen izolovaný proces běžící na jádře tvého hostitele — ne malý virtuální počítač. Nemá vlastní jádro, nebootuje, nemá „svůj hardware": sdílí jádro s tebou a od zbytku systému ho oddělují dvě funkce Linuxu — namespaces (co proces vidí) a cgroups (kolik smí spotřebovat). Až tohle pochopíš, přestaneš od kontejnerů čekat věci, které umí jen VM, a naopak oceníš, proč jsou tak rychlé a lehké.
Pár pojmů na úvod
- Kontejner = izolovaný proces (nebo skupina procesů) na sdíleném jádře hostitele. Tváří se, že má systém sám pro sebe, ale pod ním je pořád tvoje jedno jádro Linux.
- Image (obraz) = neměnná šablona, ze které kontejner vzniká — zabalený souborový systém + metadata (co spustit). Image se nemění; kontejner je jeho běžící instance.
- Namespaces = funkce jádra, která procesu izoluje pohled — vidí jen svoje procesy, svou síť, své mounty. Nic „mimo" pro něj neexistuje.
- cgroups (control groups) = funkce jádra, která omezuje zdroje — kolik CPU a RAM proces dostane. Namespaces řeší co vidí, cgroups řeší kolik sní.
- Registry = sklad hotových image ke stažení (Docker Hub,
quay.io). Odtudpullnešnginx,postgres,python… místo abys je stavěl od nuly. - Podman / Docker = nástroje, kterými kontejnery ovládáš. Docker je nejrozšířenější; Podman (rootless, bez démona) je běžný v ekosystému RHEL/Fedora. CLI mají skoro totožné.
Kontejner vs virtuální stroj — hlavní rozdíl
Nejčastější omyl začátečníka je, že kontejner = odlehčená VM. Není. Virtuální stroj emuluje celý počítač: má vlastní jádro, bootuje, běží v něm kompletní operační systém nad hypervizorem. Kontejner nic z toho nemá — je to obyčejný proces, který jádro hostitele jen „schová" do svých namespaces a omezí cgroupami.
Důsledky, které z toho plynou:
- Rychlost a velikost — kontejner nabootuje za zlomek vteřiny a váží megabajty, ne gigabajty, protože nenese celý OS ani jádro.
- Hustota — na jednom stroji rozjedeš stovky kontejnerů; VM jsou o řád těžší.
- Slabší izolace — protože sdílejí jádro, díra v jádře může teoreticky prasknout hranici mezi kontejnery. VM je oddělená silněji (ale za cenu režie). K bezpečnosti se vrátíme níž.
Image vs kontejner
Tenhle rozdíl si zapamatuj natvrdo, protože se v něm pletou i pokročilí:
- Image je neměnná šablona — jako instalační ISO nebo „recept". Leží v úložišti a nikdy se nemění.
- Kontejner je běžící (nebo zastavená) instance vytvořená z image — jako uvařené jídlo z receptu. Z jednoho image spustíš klidně deset kontejnerů najednou, každý žije vlastní život.
podman pull nginx # stáhne image nginx z registry
podman images # vypíše lokálně dostupné image
podman run -d nginx # vytvoří a spustí kontejner z image
podman ps # vypíše běžící kontejnery
podman ps -a # i zastavené
💡 Když smažeš kontejner, image zůstane. Když smažeš image, musíš ho příště znovu
pullnout nebo postavit. Jsou to dvě různé věci na dvou různých místech.
Podman vs Docker
Docker kontejnery zpopularizoval a jeho CLI se stalo standardem. Má ale dvě vlastnosti, které Podman řeší lépe:
- Démon — Docker běží jako pořád zapnutá služba (
dockerd) pod rootem; všechno jde přes ni. Podman žádného démona nemá — spustí kontejner jako obyčejný podproces a skončí. - Rootless — Podman umí běžet bez roota, pod tvým uživatelem. Kontejner tak nemá práva do celého systému, i kdyby se z něj něco „utrhlo".
Nejlepší zpráva: CLI je kompatibilní. Skoro všude, kde návod píše docker, můžeš dát podman:
podman run -d -p 8080:80 nginx # to samé jako `docker run ...`
alias docker=podman # a spousta návodů „prostě jede"
V příkladech používáme podman, ale s Dockerem je postup skoro identický (docker run … funguje stejně).
Prakticky: porty a data
Kontejner je izolovaný, takže ven není vidět nic, dokud to sám nepropojíš. Dvě věci potřebuješ skoro pořád — pustit dovnitř síť (port) a přežít data (volume).
Porty (-p) — namapuješ port hostitele na port uvnitř kontejneru, jinak se k službě nedostaneš:
podman run -d -p 8080:80 nginx
# host:8080 → kontejner:80 → v prohlížeči otevřeš http://localhost:8080
Volumes (-v) — připojí složku hostitele (nebo pojmenovaný svazek) dovnitř kontejneru. Bez toho
je souborový systém kontejneru dočasný:
podman run -d -v ./data:/var/lib/postgresql/data:Z postgres
# cokoli DB zapíše do /var/lib/... skončí ve složce ./data na hostiteli
⚠️ Když na systému běží SELinux (enforcing — typicky Fedora/RHEL), přidej k bind-mountu příznak
:Z(privátní label jen pro tenhle kontejner) nebo:z(sdílený mezi kontejnery). Bez něj kontejner do složky nesmí a spadne na „permission denied", i když práva (rwx) vypadají správně.
🚩 Souborový systém kontejneru žije jen po dobu jeho existence. Když kontejner smažeš, jeho data zmizí s ním. Cokoli má přežít (databáze, uploady, logy), MUSÍ jít do volume. Tohle je asi nejčastější bolestivá lekce začátečníků — viz Failure modes.
Containerfile — vlastní image z receptu
Když ti hotový image nestačí, napíšeš si vlastní. Recept se jmenuje Containerfile (u Dockeru Dockerfile, obsah je stejný) — je to textový seznam kroků, jak image postavit:
FROM node:22 # z čeho vyjít (základní image)
WORKDIR /app # pracovní složka uvnitř
COPY . . # zkopíruj kód z hostitele do image
RUN npm ci # spusť příkaz při stavbě
CMD ["node", "server.js"] # co spustit, když kontejner poběží
podman build -t moje-app . # postaví image podle Containerfile v aktuální složce
podman run -p 3000:3000 moje-app
Kouzlo je v tom, že celé prostředí je popsané v jednom souboru — kdokoli s tímhle receptem postaví bit po bitu stejný image. Tím se dostáváme k tomu, proč vůbec kontejnery používat.
Proč vůbec kontejnery
- Konzistence dev ↔ prod — image nese aplikaci i její prostředí (verze runtime, knihovny, systémové balíčky). Konec „u mě to jede, na serveru ne" — na serveru běží stejný image.
- Izolace — dvě aplikace, které chtějí různé verze Pythonu nebo knihoven, si nelezou do zelí; každá má svůj kontejner.
- Rychlé nasazení — nasazení = stáhnout image a spustit. Žádné ruční „doinstaluj tohle, nastav tamto". Rollback = spustit předchozí verzi image.
- Čistý hostitel — nemusíš na systém instalovat deset různých databází a runtime; všechno žije zabalené v kontejnerech a po smazání nezůstane bordel.
Failure modes — časté omyly začátečníků
- „Kontejner je bezpečný jako VM." Není — sdílí jádro s hostitelem, takže izolace je slabší. Nespouštěj v něm slepě nedůvěryhodný kód s očekáváním pancéřové hranice. Pomáhá rootless Podman.
- Root uvnitř kontejneru. U rootful Dockeru proces běží jako root a při špatné konfiguraci
(nebo díře v jádře) to může být root i na hostiteli. Rootless Podman naopak root uvnitř mapuje
přes user namespace na tvého neprivilegovaného uživatele, takže host-root to není — proto ho preferuj
(plus
USERbez práv v image). - „Smazal jsem kontejner a přišel o databázi.“ Data bez volume jsou dočasná. Vždy si ujasni, co má
přežít, a dej to do
-v— jinakpodman rm= konec dat. - „Build funguje u mě.“ Když ostatním pošleš jen zdrojáky bez image nebo Containerfile, postaví si něco jiného. Sdílej image (registry) nebo aspoň Containerfile, ne zabalený stav ze svého disku.
- Obří image.
FROM ubuntu+ hromada balíčků = gigabajtové image, které se pomalu stahují. Vyjdi z menšího základu (alpine,-slim), uklízej po sobě, nezanášej do image build nástroje. - Tag
latest.nginx:latestdnes a za měsíc může být jiná verze — build přestane být reprodukovatelný. Přišpendli konkrétní verzi (nginx:1.27), ať víš, co ti kde běží.
🛠️ Cvičení
- Kontejner vs VM vlastními slovy. Vysvětli na dvě věty, proč kontejner nabootuje za zlomek vteřiny a VM ne. Kde je v tom „vlastní jádro"?
- Spusť si web. Stáhni image
nginx, spusť z něj kontejner a namapuj ho na port hostitele tak, abys ho otevřel v prohlížeči nahttp://localhost:8080. Jaký-pzápis použiješ? - Image vs kontejner. Spusť ze stejného image
nginxdva kontejnery zároveň a vypiš si běžící kontejnery. Kolik je image a kolik kontejnerů? Vysvětli ten poměr. - Ztráta dat. Rozjeď kontejner, vytvoř v něm soubor (bez volume), kontejner smaž a spusť znovu. Je soubor tam? Proč? Jak bys to zařídil, aby přežil?
- Přečti si Containerfile. Najdi u libovolného projektu
Containerfile/Dockerfilea popiš, co dělá řádekFROM,COPY,RUNaCMD. Který se spouští při stavbě a který až při běhu?
Náčrt řešení — rozbal, až si cvičení zkusíš sám
- Kontejner vs VM — kontejner je jen proces na už běžícím jádře hostitele, takže se „spustí" jako každý jiný program, okamžitě. VM musí nastartovat vlastní jádro a celý operační systém nad hypervizorem, což je plnohodnotný boot. Pozor: proto je kontejner malý a rychlý, ale izolovaný slaběji — sdílí jádro.
- Spuštění nginx —
podman pull nginx, pakpodman run -d -p 8080:80 nginx. Zápis-p 8080:80znamená „port 8080 na hostiteli → port 80 uvnitř kontejneru". V prohlížeči otevřešhttp://localhost:8080. Pozor: pořadí jeHOST:KONTEJNER, splést si je znamená, že se nikam nedostaneš. - Image vs kontejner —
podman run -d nginxspustíš dvakrát, pakpodman ps. Máš jeden image a dva kontejnery — image je neměnná šablona, kontejner je běžící instance z ní. Poměr klidně 1 image : N kontejnerů. Pozor: smazání jednoho kontejneru se druhého ani image nedotkne. - Ztráta dat — soubor tam není. Souborový systém kontejneru žije jen po dobu jeho existence;
podman rmho zahodí. Aby soubor přežil, musíš při spuštění připojit volume (-v ./data:/cesta/uvnitr) — zapisovat do něj, a data pak leží na hostiteli. Pozor: přežije jen to, co je uvnitř cesty volume, nic jiného. - Containerfile —
FROMurčuje základní image, ze kterého se staví;COPYnakopíruje soubory z hostitele do image;RUNspustí příkaz při stavbě (např. instalace závislostí) a zapeče výsledek do image;CMDříká, co se spustí až při běhu kontejneru. Pozor:RUN= build-time,CMD= run-time — pletou se nejčastěji.
🧠 Otázky & odpovědi
Jaký je rozdíl mezi kontejnerem a virtuálním strojem?
Virtuální stroj emuluje celý počítač — má vlastní jádro, bootuje a běží v něm kompletní operační systém nad hypervizorem. Kontejner je oproti tomu jen izolovaný proces na sdíleném jádře hostitele: nemá vlastní jádro, nebootuje, jádro ho jen schová do svých namespaces a omezí cgroupami. Proto je kontejner mnohem rychlejší a lehčí (megabajty, start za zlomek vteřiny), ale izolovaný slaběji, protože o jádro se dělí s hostitelem i s ostatními kontejnery.
Co jsou namespaces a cgroups a jak spolu souvisí?
Jsou to dvě funkce jádra Linux, na kterých kontejnery stojí. Namespaces izolují pohled procesu — vidí jen svoje procesy, svou síť, své mounty, jako by byl na systému sám. cgroups izolují zdroje — určují, kolik CPU a paměti proces smí spotřebovat. Zkráceně: namespaces řeší co proces vidí, cgroups řeší kolik toho sní. Teprve dohromady dají dojem samostatného systému, i když je to pořád jen proces na tvém jádře.
Jaký je rozdíl mezi image a kontejnerem?
Image je neměnná šablona — zabalený souborový systém plus metadata o tom, co spustit; leží v úložišti a nikdy se sám nemění (jako recept nebo instalační ISO). Kontejner je běžící instance vytvořená z image (jako uvařené jídlo z receptu). Z jednoho image spustíš klidně deset kontejnerů najednou a každý žije vlastním životem. Když kontejner smažeš, image zůstane; když smažeš image, musíš ho příště znovu stáhnout nebo postavit.
Proč používat Podman místo Dockeru?
Podman řeší dvě slabiny klasického Dockeru. Za prvé nemá démona — Docker běží jako pořád zapnutá
root služba, přes kterou jde všechno; Podman jen spustí kontejner jako obyčejný podproces a skončí.
Za druhé umí běžet rootless, pod tvým uživatelem, takže kontejner nemá práva do celého systému,
i kdyby se z něj něco utrhlo. A protože je CLI kompatibilní, skoro všude, kde návod píše docker,
můžeš dát podman a funguje to stejně.
Proč data v kontejneru zmizí a jak je zachovat?
Protože souborový systém kontejneru je dočasný — žije jen po dobu existence toho kontejneru. Jakmile
kontejner smažeš (podman rm), zmizí s ním i všechno, co si dovnitř zapsal. Aby data přežila, musíš
připojit volume přes -v — buď složku hostitele, nebo pojmenovaný svazek. Cokoli aplikace zapíše
do cesty volume, skončí mimo kontejner a přežije jeho smazání i restart. Proto databáze, uploady a logy
patří vždy do volume, ne do „vnitřku" kontejneru.
