Kontejnerizace: proč nahradila virtuální stroje

Kontejnerizace: Proč nahradila virtuální stroje

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/Buildpacks konzistentně 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 USER v 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

  1. Inventarizace: závislosti, konfigurace, stav, profily I/O a latence.
  2. Refaktoring: oddělení konfigurace, logů a perzistence; kontroly stavu.
  3. Kontejnerizace: Dockerfile/Buildpacks, minimální image, skenování.
  4. 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.