Jmenné prostory a cgroups v Linuxu: skutečný základ kontejnerů

Poslední aktualizace: 24 z února 2026
  • Kontejnery v Linuxu se spoléhají na jmenné prostory, aby izolovaly, co mohou procesy vidět, a na kontrolní skupiny, aby omezily, kolik zdrojů mohou používat.
  • Existují různé typy jmenných prostorů (PID, NET, MNT, UTS, IPC, USER, cgroup, time) a řadičů cgroup (CPU, paměť, I/O, PIDS), které se kombinují v závislosti na konkrétním případě.
  • Docker, Kubernetes a systemd se spoléhají na tyto primitivy jádra k vytváření izolovaných prostředí, vynucování politik zdrojů a jednotné správě služeb.
  • Monitorování metrik cgroup a pochopení topologie jmenného prostoru je nezbytné pro diagnostiku OOM, problémů s výkonem a zajištění spolehlivé izolace v produkčním prostředí.

linuxové kontejnery cgroups jmenné prostory

Pokud pracujete s Dockerem, Kubernetes Nebo u jakékoli kontejnerové platformy se dříve či později musíte ponořit do fungování systému. Za touto „magickou“ funkcí spouštění kontejnerů během několika sekund se skrývají dva klíčové prvky linuxového jádra: jmenné prostory a cgroups, duo zodpovědné za izolaci a jemnou správu zdrojůJejich pochopení rozhoduje o tom, zda být pouhým uživatelem nástrojů, nebo být tím, kdo navrhuje infrastrukturu.

V celém tomto článku se klidně, ale bez zacházení do přílišných detailů, budeme zabývat tím, jak fungují jmenné prostory (co proces může vidět) a kontrolní skupiny (co proces může používat)Jak je Docker a Kubernetes využívají; jak si s nimi můžete hrát na nízké úrovni pomocí příkazů jako unshare, ip netns nebo přímo do textu /sys/fs/cgroupA jaké triky jsou užitečné pro výkon, zabezpečení a řešení problémů v produkčním prostředí.

Co vlastně kontejner v Linuxu dělá?

Když spustíte něco jako docker runmagický virtuální stroj se nevytvoří; Získáte tak linuxový proces (nebo skupinu procesů) se silnou izolací a omezenými zdroji.Tento „trik“ je založen na čtyřech mechanismech jádra:

  • Jmenné prostoryŘídí, co proces vidí (PID, síť, souborový systém, název hostitele atd.).
  • SkupinyŘídí, kolik může proces využívat (CPU, RAM, I/O, PID…).
  • Chroot / rootfs izolovaný: dávají procesu vlastní souborový systém.
  • Normální linuxové procesyNakonec se vše scvrkne na PID hostitele spravované jádrem.

Jinými slovy, kontejner není nic víc než proces běžící s novou sadou jmenných prostorů, vnořený v jedné nebo více kontrolních skupinách (cgroups) a s vlastním souborovým systémemZbytek zajišťuje nástroj (Docker, container, runc atd.) s automatizací a praktickými API.

Jmenné prostory Linuxu: izolace toho, co každý proces vidí

Jmenné prostory jsou vrstvou abstrakce jádra, která vytváří oddělené „světy“ pro skupiny procesůProces vidí pouze prostředky, které se nacházejí v jeho jmenném prostoru; zbytek systému je stále v systému, ale je pro něj neviditelný.

Linux má v současnosti několik typů jmenných prostorů, z nichž každý se zaměřuje na specifickou část systému. Kombinace... Díky nim se kontejner jeví jako nezávislý operační systém, i když sdílí jádro s hostitelem..

Hlavní typy jmenných prostorů

Každý typ jmenného prostoru izoluje jinou dimenzi. V „vážném“ kontejneru je běžnou praxí používat několik z nich současně. Zde jsou nejdůležitější:

  • Jmenný prostor PID: izoluje prostor identifikátorů procesu. V rámci kontejneru je hlavním procesem obvykle PID 1.i když má hostitel jiné číslo. Procesy z různých jmenných prostorů mohou mít stejné PID, aniž by se vzájemně rušily, a nemohou si navzájem posílat signály, pokud to hostitel výslovně nepovolí.
  • Jmenný prostor sítě (NET): vytváří nezávislý síťový stack s vlastními rozhraními, trasami, pravidly firewallu, sockety atd. Každý kontejner má svou vlastní zpětnou smyčku, vlastní IP adresy a vlastní směrování.Tímto způsobem můžete znovu použít stejnou IP adresu v různých jmenných prostorech bez konfliktu a aplikovat izolovaná pravidla iptables.
  • Jmenný prostor Mount (MNT): odděluje pohled od montážních bodů. Procesy vidí pouze hierarchii souborů svého jmenného prostoru.I když pod nimi existují vázané připojení, sdílené svazky, překryvy atd. Díky tomu se kontejner jeví, jako by měl svůj vlastní "/", aniž by se dotýkal skutečného kořenového adresáře hostitele.
  • Jmenný prostor UTS: řídí název hostitele a doménu NIS. V rámci jmenného prostoru UTS, Název hostitele můžete změnit bez ovlivnění hostitelského systému.Velmi užitečné pro rozlišení kontejnerů nebo simulaci uzlů v testovacích prostředích.
  • Jmenný prostor IPC: izoluje fronty zpráv System V, semafory a sdílenou paměť. Zabraňte tomu, aby různé procesy kontejnerů interferovaly s IPC v důsledku nehody nebo špatného návrhu.
  • Uživatelský jmenný prostorPravděpodobně nejjemnější. Umožňuje Mapování interních UID a GID jmenného prostoru na ID jiných hostitelůDíky tomu je možné namapovat „root“ v kontejneru na neprivilegovaného uživatele na hostiteli, což výrazně snižuje riziko eskalace oprávnění a zlepšuje... zabezpečení kontejneru.
  • Jmenný prostor Cgroup: poskytuje virtualizovaný pohled na /proc/self/cgroup a hierarchii cgroups. Z vnitřku kontejneru jsou viditelné pouze jeho vlastní skupiny.To skrývá skutečnou strukturu hostitele a posiluje izolaci.
  • Časový jmenný prostor: umožňuje nabízení různé vnímání času (hodiny jako CLOCK_MONOTONIC nebo CLOCK_BOOTTIME) pro různé skupiny procesů. Je to užitečné pro testovací scénáře nebo velmi jemnou izolaci.
  Ladění paměti v Linuxu: klíčové nástroje a techniky

Všechny tyto jmenné prostory jsou zveřejněny v /proc/<pid>/ns/a lze jej vytvořit nebo kombinovat s nástroji, jako například unshare y nsenterKdyž poslední proces patřící do jmenného prostoru zanikne, je tento jmenný prostor automaticky zničen.

Experimentování s jmennými prostory z příkazového řádku

Příkaz unshare Je to jeden ze základů experimentování: vytvoří podřízený proces s jedním nebo více novými jmennými prostoryNapříklad pro otestování izolovaného jmenného prostoru PID:

unshare --pid --fork --mount-proc bash
ps aux
echo $$

Uvnitř uvidíte pouze procesy daného jmenného prostoru a váš shell se tam zobrazí jako PID 1, i když hostitel stále obsahuje všechny své obvyklé procesy. Je to v podstatě kostra toho, co běhové prostředí OCI udělá při spuštění kontejneru..

Podrobné informace o jmenných prostorech sítě

Síťový aspekt je jedním z nejvšestrannějších. Při vytváření jmenného prostoru NET s ip netns addZískáte prázdný zásobník s výjimkou zásobníku zpětné smyčky. Odtud můžete:

  • Připojte daný jmenný prostor k hostiteli s párem veth (dvě virtuální rozhraní spojená logickým kabelem).
  • Vytvářejte mosty typ br0 a propojit několik jmenných prostorů s tímto mostem, aby se navzájem viděly pomocí soukromých IP adres.
  • NAT a přesměrování poskytnout přístup k internetu těm „domácím kontejnerům“ s iptables a /proc/sys/net/ipv4/ip_forward.

Přesně tak, na velmi nízké úrovni, tohle Docker dělá s mostem. docker0 a jejich výchozí sítě: Nastavuje jmenné prostory sítě, uzly veth, mosty a pravidla NAT. aby si kontejnery mohly mezi sebou povídat a jít ven.

Připojení a uživatelské jmenné prostory pro rootfs a zabezpečení

S příkazem `mount namespace` můžete experimentovat s vytvářením kontejnerového souborového systému bez použití Dockeru. Typický vzorec je:

  • Sestavit nebo připravit minimální rootfs (například minirootfs Alpine stažený uživatelem wget a extrahováno do adresáře).
  • Vytvořte jmenný prostor připojení a proveďte to pivot_root o chroot do daného adresáře.
  • Jízda /proc, /sys a další pseudosystémy v rámci nového kořene.

Díky tomu váš shell uvidí pouze tento souborový systém, ale Zůstáváte normálním hostitelským procesem se svým skutečným PID, který může spravovat administrátor.Pokud také používáte uživatelský jmenný prostor s --map-root-userMůžete mít uvnitř „roota“, který je mimo uživatele bez oprávnění.

Cgroups: kolik zdrojů může každý proces spotřebovat

Pokud jmenné prostory určují, co proces může vidět, cgroups vymezují kolik systémových prostředků může sada procesů spotřebovatByly zavedeny v jádře 2.6.24 a nyní jsou nezbytné na jakékoli moderní kontejnerové platformě.

Na konceptuální úrovni je cgroup adresář uvnitř /sys/fs/cgroup se soubory, které popisují limity, priority a metrikyKdyž do příslušného souboru přidáte PID (například cgroup.procs), tento proces podléhá těmto pravidlům.

Řadiče zdrojů v cgroups

C-skupiny se skládají z kontrolérů (subsystémů), které pracují se specifickými zdroji. Mezi nejčastěji používané patří:

  • Procesor (CPU): řídí přidělený čas CPU. S sdílení definuje relativní prioritu; s Kvóty pevné limity (např. časový limit CPU 50 ms na každých 100 ms periody); s CPU sety Opravujete procesy na konkrétní jádra.
  • Memory: omezuje RAM a swap. Umožňuje Tvrdé a měkké limity, nastavení OOM killer, statistiky a paměťový tlakVelmi užitečné pro zabránění tomu, aby služba spotřebovávala celý server.
  • Blokové I/O (blkio / IO): omezuje šířku pásma a IOPS na zařízení. Můžete přiřadit proporcionální váhu nebo nastavit přesné limity v bajtech/s operacích/s.
  • SíťExistují mechanismy pro omezení šířky pásma a paketů, ačkoli podpora je méně vyspělá a obvykle se kombinuje s tc a QoS.
  • PIDyoznačte maximální počet procesů/vláken což může vytvořit skupinu, zmírnit tak útoky fork bomb nebo chyby kódu, které spouštějí vlákna.

Praktická myšlenka je velmi jednoduchá: Aplikaci umístíte do cgroup a zadáte maximální počet CPU, paměti, I/O a PID.Od té chvíle jádro přebírá vynucování pravidel.

cgroups v1 vs cgroups v2

V produkčním prostředí se setkáte se dvěma druhy cgroups a je důležité si ujasnit, na jakém území se pohybujete:

  • cgroup v1Každý kontroler má svou vlastní nezávislou hierarchii. Máte trasy jako /sys/fs/cgroup/cpu/..., /sys/fs/cgroup/memory/..., Etc. Je flexibilní, ale ve velkém měřítku složité ho spravovat.Mnoho klasických distribucí a platforem jej stále používá nebo podporuje z důvodu kompatibility.
  • cgroup v2seskupuje vše pod jeden celek jednotná hierarchie en /sys/fs/cgroupLimity se konfigurují pomocí souborů, jako například cpu.max, memory.max, io.max a podobně. Zjednodušuje správu a zlepšuje jemné doladění zdrojůModerní distribuce obvykle standardně používají v2, někdy s hybridním režimem.
  Všechny nové funkce systému iOS 26 a aktualizace 26.4 v detailu

En /proc/cgroups Můžete vidět, které kontrolery jsou povoleny, kolik aktivních cgroup je a zda jste ve verzi v1 nebo v2 (ve verzi v2 uvidíte sjednocenou hierarchii s ID 0). Příkaz mount | grep cgroup Také vám sdělí typ souborového systému (cgroup2fs implikuje v2, tmpfs (obvykle ukazuje na v1).

Ruční vytváření kontrolních skupin a typických limitů

Abychom plně pochopili, co Docker dělá „pod kapotou“, je vhodné vytvořit cgroups ručně. Obecný vzorec je:

  • Vytvořte adresář cgroup.
  • Konfigurace souborů s omezeními/prioritou (CPU, paměť, I/O, PID…).
  • Přidejte PID do cgroup zadáním cgroup.procs o tasks (ve verzi 1).

Například v cgroups v2 byste mohli mít pro CPU a paměť něco takového:

mkdir /sys/fs/cgroup/test_app
echo "+cpu +memory +io +pids" > /sys/fs/cgroup/cgroup.subtree_control
echo "50000 100000" > /sys/fs/cgroup/test_app/cpu.max
echo "512M" > /sys/fs/cgroup/test_app/memory.max
echo $$ > /sys/fs/cgroup/test_app/cgroup.procs

Tímto je současný proces omezen na 50 % jádra a 512 MB RAMPokud začnete s něčím intenzivním (např. dd například do /dev/null), uvidíte, že systém se nezblázní. V cgroups v1 je schéma podobné, ale se soubory jako cpu.shares, cpu.cfs_quota_us, memory.limit_in_bytesatd., každý ve své vlastní hierarchii.

Jak Docker, Kubernetes a kernel stackují

Nad jmennými prostory a cgroup se nachází několik vrstev softwaru, které si předávají odpovědnost tam a zpět, dokud se nedostanou k jádru. I když se název nástroje změní, Konečný výsledek je vždy stejný: volání jádra pro vytváření jmenných prostorů, konfiguraci cgroups a připojení souborových systémů..

Typický „stack“ kontejnerů dnes vypadá hodně podobně:

  • Orchestrační vrstvaKubernetes, Docker Swarm, Nomad… Zajišťují životní cyklus podů/služeb, plánování, škálování a podporu. architektury mikroslužeb.
  • běhové prostředí kontejneru na vysoké úrovniDocker Engine, kontejnerový systém, CRI-O. Přijímají rozkazy orchestrátora a proměňují je v konkrétní činy. (stahování obrázků, vytváření kontejnerů, správa snímků atd.).
  • Nízkoúrovňové běhové prostředí OCIRunc, crun a podobné nástroje implementují specifikaci OCI a jsou přímo zodpovědné za její implementaci. volají clone(), unshare(), mount() a společnost materializovat kontejner.
  • Linuxové jádroPoskytuje jmenné prostory, cgroups, OverlayFS a všechny ostatní primitivy. A právě zde se děje ta pravá „magie“.

Když hodíte docker runCesta je: CLI klient → dockerd → containerd → runc → volání jádra. Podél této cesty se vytvářejí jmenné prostory, přiřazují se cgroups, připojuje se kořenový souborový systém (rootfs) s OverlayFS a svazky a připojují se síťová rozhraní a bridge. To, co vidíte jako „kontejner“, je pro jádro hrstka procesů s určitými příznaky a speciálními cestami..

Požadavky a předchozí kontroly v systému

Než se začnete na serveru pohrávat s jmennými prostory a cgroup, je dobré se ujistit, že Hardware a jádro splňují rozumné minimální požadavky.zvláště pokud plánujete založit něco podobného produkci.

Jako referenci, alespoň 2 logické procesory, 4 GB RAM (8 GB nebo více je lepší), přibližně 20 GB volného místa na disku a jádro 3.10 nebo vyšší (ideálně 4.x nebo 5.x, aby mělo všechny výhody cgroups v2 a moderní funkce).

Chcete-li ověřit, zda jádro podporuje jmenné prostory a cgroups, jednoduše zkontrolujte konfigurační soubor používané verze:

grep -E "CONFIG_.*_NS" /boot/config-$(uname -r)
grep -E "CONFIG_CGROUP" /boot/config-$(uname -r)

Měly by se tam objevit takové možnosti. KONFIG_JMENOVÉ_PROSTORY, KONFIG_PID_NS, KONFIG_NET_NS, KONFIG_CGROUPS, KONFIG_MEMCG, KONFIG_CGROUP_SCHED označeno jako =yBez toho z hry moc neuděláš.

Dalším praktickým detailem je, zda systém umožňuje vytvářet uživatelské jmenné prostory bez oprávnění rootTo je velmi užitečné pro testování a některé nástroje. Ovládá se to pomocí sysctl. kernel.unprivileged_userns_clonePokud je na 0, budete ho muset aktivovat (nebo všude použít svůj pot).

Prozkoumání cgroup a jmenných prostorů na „reálných“ počítačích

Poměrně přímý způsob, jak si tyto koncepty osvojit, je podívat se jak je systém samotný a vaše kontejnery používajíNěkolik užitečných tipů:

  • ls /proc/self/ns/ Zobrazuje jmenné prostory, do kterých váš aktuální shell patří (cgroup, ipc, mnt, net, pid, user, uts…).
  • systemd-cgtop Zobrazuje využití CPU, paměti a I/O podle cgroup, velmi podobné top ale seskupené podle služeb a kontejnerů.
  • En /sys/fs/cgroup Skupiny cgroups, které Docker nebo Podman vytvoří pro každý kontejner, obvykle najdete pomocí ID kontejneru v cestě. Uvnitř, cgroup.procs Vypište související PIDy.
  • /proc/<pid>/cgroup Říká vám, do kterých cgroup je konkrétní proces přiřazen, což je ideální pro sledování problematické aplikace.
  Kompletní průvodce upgradem na Ubuntu 26.04 LTS

Uvidíte, že kontejnery nejsou nic víc než Další větev hierarchie cgroups s omezeními CPU, paměti, blkio atd., stejně jako byste je mohli vytvořit ručně.Krása Dockeru spočívá v tom, že to dělá automaticky a pomocí uživatelsky přívětivého API.

Výkonnostní, NUMA a afinitní strategie

Ve scénářích s vysokou zátěží (rozsáhlé databáze, intenzivní zpracování, streamování atd.) nestačí pouhé „spuštění kontejnerů a to je vše“. Způsob, jakým přidělujete CPU a paměť jednotlivým službám, výrazně ovlivňuje výkon..

S ovladačem Sada procesorů Procesy nebo služby můžete přiřadit konkrétním sadám CPU a uzlů NUMA. Něco tak jednoduchého jako:

mkdir /sys/fs/cgroup/cpuset/dedicated_cpus
echo "4-7" > /sys/fs/cgroup/cpuset/dedicated_cpus/cpuset.cpus
echo "0" > /sys/fs/cgroup/cpuset/dedicated_cpus/cpuset.mems
echo 1 > /sys/fs/cgroup/cpuset/dedicated_cpus/cpuset.cpu_exclusive

Umožňuje rezervovat skupinu jader pro konkrétní službu a zabránit zbytku systému v rušení. To snižuje šum, migrace vláken a problémy s latencí. které se obvykle objevují, když se všichni perou o stejné procesory.

Na úrovni paměti kombinujte numactl Použití cgroups (nebo přímo pomocí knoflíků NUMA řadiče paměti, pokud jsou k dispozici) pomáhá udržovat data na fyzickém uzlu nejblíže jádrům, která je používají. To je patrné u aplikací citlivých na latenci.

Monitorování a pozorovatelnost cgroup a jmenných prostorů

Stanovení limitů zdrojů je v pořádku, ale Pokud neměříte, co se děje, můžete si střelit do nohy, aniž byste si to uvědomili.cgroup v2 sám o sobě nabízí v logech poměrně dost užitečných metrik. *.stat, *.events y *.pressure.

Několik praktických příkladů:

  • cpu.stat Ukazuje, kolik času CPU skupina využila, kolikrát byla omezena její zátěž atd.
  • memory.current y memory.max Zobrazují aktuální spotřebu a nakonfigurovaný limit.
  • memory.events Zaznamenává OOM, dosažení měkkých limitů a další hrozby.
  • io.stat shromažďuje čtení/zápisy na zařízení.

Pro rychlý přehled, systemd-cgtop Je to velmi praktické a pokud chcete něco industriálnějšího, nástroje jako cPoradce Exportují metriky cgroup z Dockeru/kontejnerů do Prometheusu, což vám umožňuje bez větší námahy vytvářet kompletní dashboardy v Grafaně, ideální pro... pokročilý monitor systému.

Při ladění problémů s jmennými prostory jednoduché skripty, které procházejí /proc/<pid>/ns/ a porovnejte symbolické odkazy, které pomáhají zjistit, které procesy sdílejí přesně stejný jmenný prostornebo k nalezení „ztraceného“ jmenného prostoru sítě, který se zasekl.

Použití systemd jako správce cgroup

Ve většině moderních distribucí, systemd se pro správu služeb, segmentů a oborů silně spoléhá na cgroups.Když definujete jednotku s omezeními zdrojů, systemd ve skutečnosti vytvoří kontrolní skupinu pro danou službu a nakonfiguruje její obslužné rutiny.

Služba deklarovaná pomocí direktiv, jako například:

CPUQuota=50%
CPUWeight=500
MemoryMax=512M
IOReadBandwidthMax=/dev/sda 10M

nakonec přeloženo do Omezení cgroup pro CPU, paměť a I/O pro zpracování dané jednotky. To umožňuje sladit „klasickou“ správu služeb s modelem kontejneru s použitím stejného základního subsystému jádra. Více informací o systemd a jeho požadavcích naleznete v změny v systemd.

Pro týmy, které kombinují tradiční služby s kontejnery (což je velmi běžné), je elegantním způsobem, jak se spoléhat na systemd k nastavení limitů pro kritické démony. zabránit spotřebě zdrojů pody v kontejnerizovaném prostředí.

V prostředích, kde koexistuje více úloh, od databází po monitorovací agenty a vlastní aplikace, umožňuje zvládnutí jmenných prostorů a kontrolních skupin Definujte silné zásady izolace, upravte kvalitu služeb a zajistěte, aby každá část měla dobře řízený „zápletku“ CPU a paměti.Pochopení toho, jak Docker, Kubernetes a systemd využívají tyto funkce jádra, vám umožní navrhovat bezpečnější multi-tenant infrastruktury, ladit složité problémy (od OOM až po úzká hrdla I/O) a maximalizovat využití hardwaru bez obětování stability.

Podpora systemd 259 pro musl
Související článek:
systemd 259: podpora pro musl, zabezpečení a změny klíčů