Modul 7 — Virtualizace a kontejnery: Docker

28. Co je virtualizace a v čem se liší od kontejnerizace

Rozdíl mezi hypervizorem a kontejnerovým enginem, výhody a nevýhody virtuálních strojů oproti kontejnerům a kdy se která technologie hodí.

Odhadovaná délka studia: 50 minut · Stav: nehotovo

Technologie: Docker

Úvod a kontext

Předchozích 27 lekcí pracovalo s aplikacemi běžícími přímo na jednom
Linuxovém serveru. V reálném provozu se ale na jednom fyzickém stroji
téměř nikdy neběhá jen jedna aplikace — z důvodu izolace, přenositelnosti
a efektivního využití hardwaru se aplikace balí do virtuálních strojů
nebo kontejnerů. Obě technologie řeší podobný problém — spustit víc
izolovaných prostředí na jednom fyzickém serveru — ale zcela odlišným
způsobem. Tato lekce vysvětluje rozdíl, protože nepochopení této
odlišnosti je nejčastější zdroj zmatku u lidí, kteří se učí Docker.

Teorie

Virtualizace a hypervizor

Virtualizace vytváří virtuální stroj (VM) — softwarovou napodobeninu
celého počítače, včetně virtualizovaného hardwaru (CPU, paměť, disk,
síťová karta), na kterém běží kompletní vlastní operační systém s
vlastním jádrem. Vrstva softwaru, která virtuální stroje vytváří a řídí,
se nazývá hypervizor:

  • Hypervizor typu 1 (bare-metal) — běží přímo na hardwaru bez
    hostitelského OS (např. VMware ESXi, Xen, KVM). Používá se v
    datacentrech a cloudu.
  • Hypervizor typu 2 — běží jako aplikace nad existujícím operačním
    systémem (např. VirtualBox, VMware Workstation). Používá se hlavně na
    vývojářských strojích.

Každý virtuální stroj obsahuje kompletní operační systém — vlastní jádro,
vlastní ovladače, vlastní systémové procesy — což znamená spotřebu řádově
stovek MB až jednotek GB paměti jen na start VM, než v ní vůbec začne
běžet aplikace, a start trvá desítky sekund až minuty (bootuje se celý
OS).

Kontejnerizace

Kontejner nevirtualizuje hardware ani nespouští vlastní jádro
kontejnery na jednom hostitelském serveru sdílejí jedno a totéž jádro
Linuxu. Izolace mezi kontejnery se dosahuje pomocí funkcí přímo v jádře
Linuxu:

  • namespaces — izolují, co proces uvnitř kontejneru "vidí": vlastní
    pohled na procesy (PID namespace), síťová rozhraní (network namespace),
    souborový systém (mount namespace), uživatele (user namespace) atd.
    Proces v kontejneru si myslí, že běží sám na svém stroji, i když ve
    skutečnosti sdílí jádro s desítkami dalších kontejnerů.
  • cgroups (control groups) — omezují a měří, kolik CPU, paměti a
    I/O smí kontejner spotřebovat, aby jeden "žravý" kontejner nepřipravil
    ostatní o zdroje.

Protože kontejner nemusí startovat vlastní jádro ani celý OS, jeho
spuštění trvá zlomky sekundy a jeho paměťová režie navíc oproti běžnému
procesu je minimální — v kontejneru běží jen samotná aplikace a to, co
nezbytně potřebuje (knihovny, konfigurace), ne celý operační systém.

Srovnání

Vlastnost Virtuální stroj Kontejner
Izolace Silná (vlastní jádro) Slabší (sdílené jádro hostitele)
Velikost Stovky MB — desítky GB Jednotky — stovky MB
Start Desítky sekund až minuty Zlomky sekundy
Výkonová režie Vyšší Minimální
Přenositelnost Nižší (velké image, hypervizor-specifické formáty) Vysoká (stejný image běží všude, kde je kontejnerový engine)
Typický běh na jednom stroji Jednotky až desítky VM Desítky až stovky kontejnerů

Kontejner sdílí jádro hostitele, což znamená i důležité bezpečnostní
omezení: kontejner nemůže spustit jiný operační systém než ten, jehož
jádro sdílí (Linuxový kontejner potřebuje Linuxové jádro), a únik z
kontejneru (container escape) je z principu snazší představitelný než
únik z virtuálního stroje, protože izolace je na úrovni procesu v rámci
jednoho jádra, ne na úrovni celého virtualizovaného hardwaru.

Kdy použít co

Obě technologie se v praxi běžně kombinují, ne vylučují:

  • Virtuální stroje se hodí, když je potřeba silná bezpečnostní
    izolace mezi zákazníky (multi-tenant cloud), různé operační systémy na
    jednom hardwaru, nebo starší aplikace, které nejdou snadno
    kontejnerizovat.
  • Kontejnery se hodí pro nasazování moderních aplikací — rychlý
    start, malá režie, snadná přenositelnost mezi vývojářským notebookem,
    testovacím a produkčním prostředím ("funguje mi to na mém stroji"
    problém řeší právě kontejnerizace).
  • V praxi cloudoví poskytovatelé typicky spouští kontejnery uvnitř
    virtuálních strojů — VM poskytuje silnou izolaci mezi zákazníky
    cloudu, kontejnery uvnitř VM poskytují rychlé a efektivní nasazování
    jednotlivých aplikací daného zákazníka.

Praktický příklad

Porovnání spotřeby zdrojů lze na Linuxu demonstrovat přímo: spuštění
kontejneru a pohled na to, že "uvnitř" běží jen daný proces, ne celý OS:

docker run -d --name test-nginx nginx:alpine

# proces uvnitř kontejneru je vidět i v procesech hostitele —
# na rozdíl od VM, kde by hostitel viděl jen proces hypervizoru
ps aux | grep nginx

# kontejner má vlastní PID namespace: uvnitř vidí jen svoje procesy
docker exec test-nginx ps aux

Výstup druhého příkazu ukáže typicky jen 2–3 procesy (nginx master a
worker) s PID 1 pro hlavní proces — uvnitř kontejneru vypadá, jako by byl
jediným procesem v celém systému, přestože na hostiteli běží mezi
desítkami dalších procesů.

Kontrola, kolik paměti a CPU si kontejner skutečně bere (cgroups v akci):

docker stats test-nginx

Pro srovnání: spuštění a vypnutí typického virtuálního stroje v cloudu
trvá řádově desítky sekund až minuty (start celého Linuxového jádra a
init systému), zatímco výše uvedený docker run typicky proběhne pod
jednu sekundu (kromě prvního stažení image).

Shrnutí

Virtualizace vytváří kompletní virtuální počítač s vlastním jádrem
odděleným hypervizorem, zatímco kontejnery sdílejí jádro hostitele a
izolují procesy pomocí namespaces a cgroups přímo v Linuxovém jádře. To
dělá kontejnery výrazně lehčí a rychlejší na start, ale s o něco slabší
izolací než u virtuálních strojů. V praxi se obě technologie často
kombinují — VM pro silnou izolaci mezi zákazníky, kontejnery uvnitř pro
efektivní nasazování jednotlivých aplikací.

Kontrolní otázky

  1. Co je hypervizor a jaký je rozdíl mezi hypervizorem typu 1 a typu 2?
  2. Vysvětlete, k čemu slouží namespaces a k čemu cgroups v kontextu
    kontejnerů.
  3. Proč je start kontejneru řádově rychlejší než start virtuálního
    stroje?
  4. Proč cloudoví poskytovatelé často spouští kontejnery uvnitř
    virtuálních strojů, místo aby použili jen jednu z obou technologií?

Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.