Co je kontejner
Kontejner je izolované běhové prostředí pro aplikaci a její závislosti, které sdílí jádro operačního systému s hostitelem. Na rozdíl od virtuálního stroje (VM) nekopíruje celý operační systém; místo toho využívá namespaces a cgroups k izolaci procesů, zdrojů a souborového systému. Výsledkem je lehké, rychle startující a snadno přenositelné balení aplikace napříč prostředími.
Proč kontejnery nahradily (mnoho) VM
- Hustota: bez hypervizoru a hostovaného OS běží na stejné infrastruktuře více instancí.
- Rychlý start: kontejnery startují v řádu milisekund až sekund, VM v řádu desítek sekund až minut.
- Přenositelnost: standardy OCI zaručují, že image běží stejně ve vývojovém, testovacím i produkčním prostředí.
- Opakovatelnost: deklarativní
Dockerfile/Buildpackskonzistentně vytvářejí spustitelné artefakty. - Ekosystém: orchestrace (Kubernetes), registry, observabilita a síťové pluginy zjednodušují provoz.
- Náklady: vyšší využití zdrojů snižuje TCO, zejména u mikroservisní architektury.
Architektura: jak kontejnery fungují
Základ tvoří dvě techniky v Linuxu (a jejich obdoby v dalších OS):
- Namespaces (pid, net, mnt, ipc, uts, user): oddělují procesy, síť, připojené souborové systémy, IPC, název hostitele a uživatele.
- cgroups v2: omezují a účtují využití CPU, paměti, I/O a dalších kvót; chrání hostitele před vyčerpáním zdrojů.
Izolaci souborového systému zajišťují union filesystémy (OverlayFS). Kontejner má vrstvy image pouze pro čtení a samostatnou vrstvu pro čtení i zápis pro každou instanci.
Image a vrstvy: neboli „balíček runtime“
- OCI image se skládá z vrstev (archivů tar), které sdílejí obsah mezi kontejnery – šetří místo a využívají cache.
- Dockerfile/Buildpacks popisují proces sestavení; běžnou praxí je vícestupňové sestavení pro minimalizaci výsledného image.
- Registry (Docker Hub, GHCR, ECR, GCR) slouží k distribuci image; podpisy (cosign), SBOM a skenování jsou zásadní pro zabezpečení dodavatelského řetězce.
Běh kontejneru: runtime a shim
Spuštění kontejneru zajišťuje container runtime. V praxi:
- Vyšší úroveň: containerd, CRI-O (komunikuje s Kubernetes prostřednictvím CRI).
- Nižší úroveň (OCI runtime): runc, crun – volají jádro, nastavují namespaces/cgroups a spouštějí proces PID 1 v kontejneru.
Komponenta shim zajišťuje životní cyklus a logy procesu i po ukončení klienta.
Síťování kontejnerů
- Bridge (lokální): NAT přes hostitele, izolované podsítě, mapování portů (
-p). - Overlay (více hostitelů): virtuální sítě L3/L2 nad existující infrastrukturou.
- Pluginy CNI v Kubernetes (Calico, Cilium, Flannel): přidělují IP adresy, nastavují směrování a zásady, někdy i akceleraci eBPF.
- Service discovery: DNS služeb (
kube-dns/CoreDNS), virtuální IP adresy a vyvažování zátěže.
Perzistence dat
Data musí být uložena mimo životní cyklus kontejneru:
- Volumes (hostPath, block, NFS, CSI): připojitelné úložiště s řízením přístupu a kvótami.
- Stavové úlohy v Kubernetes: StatefulSet + PersistentVolumeClaim, stabilní identita a převzetí při selhání.
Bezpečnost: izolace a důsledné zabezpečení
- Princip nejnižších oprávnění: nespouštět procesy jako root; použít
USERv Dockerfile a režimy rootless. - Bezpečnostní moduly Linuxu: seccomp (filtr systémových volání), profily AppArmor/SELinux a capabilities – odstranit nepotřebná oprávnění.
- Dodavatelský řetězec: skenování zranitelností, podpisy image, policy engines (OPA/Gatekeeper, Kyverno), SBOM.
- Sandboxing: ve vícetenantním prostředí lze použít kata-containers/gVisor (lehké VM) – představují další pevnou izolační hranici.
Orchestrace: proč samotný kontejner nestačí
Ve větším měřítku je nutné řešit plánování, škálování, aktualizace a odolnost:
- Kubernetes: deklarativní API (Deployment, StatefulSet, DaemonSet), automatické škálování (HPA/VPA), Pod jako základní jednotka běhu.
- Service mesh (Istio, Linkerd): mTLS, zásady provozu, observabilita bez změn kódu.
- Ingress/Edge: řízení příchozího provozu (Ingress Controller/Gateway API), omezení rychlosti požadavků a WAF.
CI/CD: od kódu k běžícímu kontejneru
- Sestavení: reprodukovatelná sestavení (BuildKit, kaniko), cache, více architektur (amd64/arm64).
- Testování: jednotkové a integrační testy, bezpečnostní skenování; dočasná prostředí.
- Vydání: neměnné tagy (digest sha256), GitOps (Argo CD/Flux), postupné nasazení (canary/blue-green).
Výkon: proč jsou kontejnery efektivnější
- Nižší režie: sdílené jádro znamená menší nároky na paměť/CPU pro infrastrukturní vrstvu než VM s hostovaným OS.
- Cache vrstev: rychlejší sestavení a nasazení; minimalizace image zkracuje studený start.
- QoS zdrojů: limity cgroups, požadavky a limity v Kubernetes, NUMA a připínání procesů pro citlivé úlohy.
Kdy dát přednost VM nebo fyzickému stroji
- Silná izolace a soulad s předpisy: různá úroveň důvěry mezi tenanty, starší regulace vyžadující izolační hranice VM.
- Specializovaný hardware: PCIe passthrough, některé scénáře s GPU/FPGA nebo modely ovladačů lépe vyhovují VM či fyzickému serveru.
- Závislosti na monolitickém OS: aplikace pevně svázané s konkrétní verzí jádra/OS.
Návrh kontejneru: 12-Factor a osvědčené postupy
- Jeden proces na kontejner (PID 1 dělá jen jednu věc; dohled nad procesy prostřednictvím init wrapperu, nikoli cron uvnitř image).
- Konfigurace mimo image: prostřednictvím proměnných nebo secrets/config maps; v image neukládat žádné tajné klíče.
- Neměnnost: image je pouze pro čtení, stav se uchovává mimo něj; sestavení → testování → vydání bez změny artefaktu.
- Observabilita: logy na stdout/stderr, kontroly stavu (liveness/readiness/startup), metriky a trace.
Monolit vs. mikroslužby
Kontejnery podporují oba přístupy. Monolit je na začátku jednodušší, mikroslužby umožňují nezávislé cykly vydávání a škálování. Klíčové jsou smlouvy API, verzování, observabilita, odolnost (circuit breaker, opakování požadavků, časové limity) a správa závislostí.
Náklady a ekonomika provozu
- Využití zdrojů: vyšší hustota snižuje potřebu uzlů a licencí.
- Rychlost dodávky: kratší doba realizace zvyšuje hodnotu pro podnikání.
- Skryté náklady: orchestrátory přinášejí komplexitu – je nutné investovat do SRE, bezpečnosti a správy.
Bezpečný dodavatelský řetězec (Supply Chain)
- Minimální základní image: distroless/ubi-minimal, odstranit shell a správce balíčků.
- Reprodukovatelnost: připínání verzí, hermetická sestavení, SBOM a podpisy artefaktů.
- Vynucování zásad: admission kontrolery, pravidla pro původ image, skenování v CI i v clusteru.
Windows a další platformy
Kontejnery existují také ve Windows (Windows Server Containers, Hyper-V Containers) a macOS (prostřednictvím VM). Image pro více architektur umožňují jednotné vydávání pro amd64/arm64.
Observabilita v kontejnerech
- Metriky: cAdvisor/Node Exporter, Prometheus + Alertmanager; klíčové signály (latence, chybovost, provoz, saturace).
- Logy: sidecar/agent (Fluent Bit/Vector), standardní formát, korelace s ID trace.
- Trasování: OpenTelemetry, vzorkování a baggage; korelace napříč službami.
Migrace z VM na kontejnery
- Inventarizace: závislosti, konfigurace, stav, profily I/O a latence.
- Refaktoring: oddělení konfigurace, logů a perzistence; kontroly stavu.
- Kontejnerizace: Dockerfile/Buildpacks, minimální image, skenování.
- Provoz: nasazení do orchestrátoru, limity/požadavky, HPA, strategie postupného nasazení, observabilita.
Příklady anti-patternů
- „VM uvnitř kontejneru“: velké image s init systémy a více démony – ztráta výhod kontejneru.
- Stav uvnitř kontejneru: zápis do vrstvy pro čtení a zápis → problémy se škálováním a perzistencí.
- Root a široká oprávnění: neomezuje se útočná plocha; používejte
USER, odebírejte oprávnění, používejte profily seccomp. - Konfigurační odchylky: ruční zásahy do běžících kontejnerů; vše řešte opětovným sestavením a nasazením.
Budoucnost: lehké VM a konvergence
Ve vícetenantních scénářích se prosazuje kombinace lehkých VM (Firecracker, Kata) a kontejnerů: výkon a hustota kontejnerů s izolační hranicí VM. Trendem je eBPF pro síťování, bezpečnost a observabilitu a WASM pro ultralehké sandboxované moduly na okraji sítě (edge).
Závěr
Kontejnery přinášejí standardizované, lehké a rychlé běhové prostředí, které výrazně zjednodušuje vývoj i provoz. VM zcela nenahradily, ale ve velké části aplikačních scénářů převzaly jejich roli díky vyšší hustotě, rychlejšímu nasazení a bohatému ekosystému orchestrace a observability. Správně navržený kontejner, spravovaný deklarativně, s minimálními oprávněními a jasně nastaveným dodavatelským řetězcem, je dnes základním stavebním kamenem moderní cloud-native architektury.
