GNU/Linux >> Znalost Linux >  >> Linux

Historie nízkoúrovňových runtime kontejnerů Linuxu

Ve společnosti Red Hat rádi říkáme:„Kontejnery jsou Linux – Linux jsou kontejnery.“ Zde je uvedeno, co to znamená. Tradiční kontejnery jsou procesy v systému, které mají obvykle následující tři charakteristiky:

1. Omezení zdrojů

Linuxové kontejnery

  • Co jsou kontejnery systému Linux?
  • Úvod do terminologie kontejnerů
  • Stáhnout:Containers Primer
  • Operátoři Kubernetes:Automatizace platformy pro orchestraci kontejnerů
  • eKniha:Vzory Kubernetes pro navrhování cloudových nativních aplikací
  • Co je Kubernetes?

Když v systému spouštíte mnoho kontejnerů, nechcete, aby žádný kontejner monopolizoval operační systém, takže používáme omezení zdrojů k řízení věcí, jako je CPU, paměť, šířka pásma sítě atd. Linuxové jádro poskytuje funkci cgroups, která lze nakonfigurovat tak, aby řídil prostředky kontejnerového procesu.

2. Bezpečnostní omezení

Obvykle nechcete, aby se vaše kontejnery mohly navzájem napadat nebo útočit na hostitelský systém. Využíváme několik funkcí linuxového jádra k nastavení oddělení zabezpečení, jako je SELinux, seccomp, schopnosti atd.

3. Virtuální separace

Procesy kontejneru by neměly mít přehled o žádných procesech mimo kontejner. Měli by být ve své vlastní síti. Procesy kontejnerů se musí umět vázat na port 80 v různých kontejnerech. Každý kontejner potřebuje jiný pohled na svůj obraz, potřebuje svůj vlastní kořenový souborový systém (rootfs). V Linuxu používáme jmenné prostory jádra k zajištění virtuálního oddělení.

Proto proces, který běží v cgroup, má nastavení zabezpečení a běží ve jmenných prostorech, lze nazvat kontejnerem. Když se podíváte na PID 1, systemd, na systému Red Hat Enterprise Linux 7, uvidíte, že systemd běží v cgroup.

# tail -1 /proc/1/cgroup
1:name=systemd:/

ps vám ukáže, že systémový proces má označení SELinux ...

# ps -eZ | grep systemd
system_u:system_r:init_t:s0             1 ?     00:00:48 systemd

a schopnosti.

# grep Cap /proc/1/status
...
CapEff: 0000001fffffffff
CapBnd: 0000001fffffffff
CapBnd:    0000003fffffffff

Nakonec, když se podíváte na /proc/1/ns subdir, uvidíte jmenný prostor, ve kterém běží systemd.

ls -l /proc/1/ns
lrwxrwxrwx. 1 root root 0 Jan 11 11:46 mnt -> mnt:[4026531840]
lrwxrwxrwx. 1 root root 0 Jan 11 11:46 net -> net:[4026532009]
lrwxrwxrwx. 1 root root 0 Jan 11 11:46 pid -> pid:[4026531836]
...

Pokud má PID 1 (a opravdu každý další proces v systému) omezení zdrojů, nastavení zabezpečení a jmenné prostory, tvrdím, že každý proces v systému je v kontejneru.

Nástroje pro běh kontejnerů pouze upravují tato omezení zdrojů, nastavení zabezpečení a jmenné prostory. Poté linuxové jádro spustí procesy. Po spuštění kontejneru může běhový modul kontejneru monitorovat PID 1 uvnitř kontejneru nebo stdin kontejneru /stdout —kontejner runtime spravuje životní cykly těchto procesů.

Doby běhu kontejneru

Možná si řeknete, dobře systemd zní dost podobně jako běhový modul kontejneru. Po několika e-mailových diskuzích o tom, proč běhová prostředí kontejneru nepoužívají systemd-nspawn jako nástroj pro spouštění kontejnerů jsem se rozhodl, že by stálo za to probrat běhové doby kontejnerů a uvést nějaký historický kontext.

Docker se často nazývá kontejnerový runtime, ale "container runtime" je přetížený termín. Když lidé mluví o „kontejnerovém běhovém prostředí“, ve skutečnosti mluví o nástrojích vyšší úrovně, jako jsou Docker, CRI-O a RKT, které přicházejí s vývojářskými funkcemi. Jsou řízeny API. Zahrnují koncepty jako stažení obrázku kontejneru z registru kontejneru, nastavení úložiště a nakonec spuštění kontejneru. Spuštění kontejneru často zahrnuje spuštění specializovaného nástroje, který nakonfiguruje jádro ke spuštění kontejneru, a tyto jsou také označovány jako "kontejnerové runtime". Budu je označovat jako „runtimes kontejnerů nízké úrovně“. Démoni jako Docker a CRI-O, stejně jako nástroje příkazového řádku jako Podman a Buildah, by se pravděpodobně měly místo toho nazývat „správci kontejnerů“.

Když byl Docker původně napsán, spouštěl kontejnery pomocí lxc sada nástrojů, která předchází systemd-nspawn . Původní práce Red Hatu s Dockerem byla pokusit se integrovat libvirt (libvirt-lxc ) do Dockeru jako alternativu k lxc nástroje, které nebyly podporovány v RHEL. libvirt-lxc také nepoužil systemd-nspawn . V té době tým systemd říkal, že systemd-nspawn byl pouze nástroj pro testování, nikoli pro výrobu.

Ve stejnou dobu se vývojáři Dockeru, včetně některých členů mého týmu Red Hat, rozhodli, že chtějí spíše golang-nativní způsob spouštění kontejnerů než spouštění samostatné aplikace. Začaly práce na libcontaineru jako nativní golangové knihovně pro spouštění kontejnerů. Inženýrství Red Hatu se rozhodlo, že toto je nejlepší cesta vpřed, a upustilo od libvirt-lxc .

Později vznikla iniciativa Open Container Initiative (OCI), strana, protože lidé chtěli mít možnost vypouštět kontejnery jinými způsoby. Tradiční kontejnery oddělené jmenným prostorem byly populární, ale lidé také toužili po izolaci na úrovni virtuálních strojů. Intel a Hyper.sh pracovali na kontejnerech oddělených KVM a Microsoft pracoval na kontejnerech založených na Windows. OCI chtěla standardní specifikaci definující, co je kontejner, a tak se zrodila specifikace OCI Runtime.

Specifikace OCI Runtime definuje formát souboru JSON, který popisuje, jaký binární soubor by měl být spuštěn, jak by měl být obsažen a umístění kořenových souborů kontejneru. Nástroje mohou vygenerovat tento soubor JSON. Pak mohou další nástroje číst tento soubor JSON a spustit kontejner na rootfs. Části libcontaineru Dockeru byly rozbity a darovány OCI. Upstream inženýři Dockeru a naši inženýři pomohli vytvořit nový frontendový nástroj pro čtení souboru JSON specifikace OCI Runtime Specification a interakci s libcontainer za účelem spuštění kontejneru. Tento nástroj se nazývá runc , byl také darován OCI. Zatímco runc může číst soubor OCI JSON, uživatelé si jej mohou vygenerovat sami. runc se od té doby stal nejoblíbenějším nízkoúrovňovým kontejnerem runtime. Téměř všechny nástroje pro správu kontejnerů podporují runc , včetně CRI-O, Docker, Buildah, Podman a Cloud Foundry Garden. Od té doby implementovaly OCI Runtime Spec pro spouštění kontejnerů kompatibilních s OCI i další nástroje.

Jak Clear Containers, tak Hyper.sh runV nástroje byly vytvořeny pro použití OCI Runtime Specification ke spouštění kontejnerů založených na KVM a spojují své úsilí v novém projektu nazvaném Kata. Minulý rok společnost Oracle vytvořila demonstrační verzi runtime nástroje OCI s názvem RailCar napsaného v Rustu. Od aktualizace projektu GitHub uběhly dva měsíce, takže není jasné, zda je stále ve vývoji. Před několika lety Vincent Batts pracoval na přidání nástroje nspawn-oci , který interpretoval soubor specifikace OCI Runtime Specification a spustil systemd-nspawn , ale nikdo to pořádně nezachytil a nebyla to nativní implementace.

Pokud chce někdo implementovat nativní systemd-nspawn --oci OCI-SPEC.json a nechte jej přijmout týmem systemd pro podporu, pak by jej CRI-O, Docker a nakonec Podman mohli používat kromě runc  a Clear Container/runV (Kata). (Nikdo z mého týmu na tom nepracuje.)

Sečteno a podtrženo, tři nebo čtyři roky zpět, upstream vývojáři chtěli napsat nízkoúrovňový golang nástroj pro spouštění kontejnerů, a tento nástroj se nakonec stal runc . Tito vývojáři v té době měli k tomu nástroj založený na C s názvem lxc a odstěhoval se od něj. Jsem si docela jistý, že v době, kdy se rozhodli postavit libcontainer, by je systemd-nspawn nezajímal nebo jakýkoli jiný nepůvodní (golangský) způsob spouštění kontejnerů oddělených "jmenným prostorem".


Linux
  1. Analýza historie Bash v Linuxu

  2. 5 důvodů, proč byste měli vyvinout linuxovou kontejnerovou strategii

  3. 7 zábavných funkcí pro přenos kontejnerů/obrázků v Linuxu

  1. Jaký je rozdíl mezi linuxovým kontejnerem a obrázkem?

  2. Mých 5 oblíbených obrázků kontejneru Linuxu

  3. Jak vytvářet, zobrazovat a mazat kontejnery Docker v systému Linux

  1. Příkaz historie v Linuxu Vysvětleno do hloubky

  2. Historie příkazového řádku v Linuxu

  3. historie dostupnosti linuxu