Tento článek pokračuje v sérii jmenných prostorů a zabývá se PID jmenný prostor. Pokud chcete obecný přehled všech jmenných prostorů, podívejte se na první článek. Dříve jste vytvořili nový mnt jmenný prostor. Je zajímavé, jak jste zjistili, i po vytvoření nového mnt jmenného prostoru, měli jste stále přístup k ID procesů (PID) původního hostitele. Když jste se pokusili připojit soubor /proc jmenného prostoru, dostali jste poněkud matoucí oprávnění odepřeno chyba, jak je vidět níže:
root@new-mnt$ mount -t proc proc /procmount:oprávnění odepřeno (jste root?)root@new-mnt$ whoamiroot
I když jste v novém jmenném prostoru připojení mohli vytvářet nejrůznější připojení, nebylo možné interagovat ani měnit /proc . V tomto článku projdu PID jmenný prostor a ukažte, jak jej můžete používat, spolu s mnt jmenný prostor pro další zabezpečení vašeho začínajícího kontejneru.
[ Čtenářům se také líbilo: Jak linuxové jmenné prostory PID fungují s kontejnery ]
Co jsou ID procesů?
Než skočíte rovnou do PID jmenný prostor, myslím, že je dobrý nápad poskytnout jen trochu pozadí, proč je tento jmenný prostor důležitý.
Když je proces vytvořen na většině operačních systémů podobných Unixu, je mu přidělen specifický číselný identifikátor zvaný ID procesu (PID). Tento PID pomáhá jednoznačně identifikovat proces i v případě, že existují dva procesy, které sdílejí stejný člověku čitelný název. Pokud je například v systému aktivních více relací ssh a potřebujete ukončit konkrétní připojení, PID poskytuje správci způsob, jak zajistit, aby byla správná relace uzavřena.
Všechny tyto procesy jsou sledovány ve speciálním souborovém systému zvaném procfs
. I když lze tento souborový systém technicky připojit kamkoli, většina nástrojů (a konvencí) očekává procfs
k připojení pod /proc
. Pokud provedete výpis /proc
, uvidíte složku pro každý proces aktuálně spuštěný ve vašem systému. Uvnitř této složky jsou nejrůznější speciální soubory používané pro sledování různých aspektů procesu. Pro účely tohoto článku nejsou tyto soubory důležité. Stačí vědět, že /proc
je místo, kde většina systémů podobných Unixu ukládá informace týkající se procesů v běžícím systému.
Jmenný prostor PID
Jeden z hlavních důvodů PID jmenný prostor má umožnit izolaci procesů. Přesněji, jak říká manuálová stránka:
Jmenné prostory PID izolují prostor ID procesu, což znamená, že procesy v různých jmenných prostorech PID mohou mít stejné PID.
To je důležité, protože to znamená, že lze zaručit, že procesy nebudou mít konfliktní PID s žádným jiným procesem. Při zvažování jediného systému samozřejmě neexistuje žádná možnost konfliktu PID, protože systém neustále zvyšuje číslo ID procesu a nikdy nepřiděluje stejné číslo dvakrát. Při manipulaci s kontejnery na více strojích se tento problém stává nápadnějším. Jak je popsáno v manuálové stránce:
Jmenné prostory PID umožňují kontejnerům poskytovat funkce, jako je pozastavení/obnovení sady procesů v kontejneru a migrace kontejneru na nového hostitele, zatímco procesy uvnitř kontejneru si udržují stejné PID.
Kromě izolace funguje PID systém téměř identicky jako mimo jmenný prostor. ID procesů v novém jmenném prostoru začínají na 1 , přičemž první proces je považován za init proces. Počáteční proces je zpracován velmi odlišně od všech ostatních PID na hostiteli. To má konkrétní důsledky pro běžící systém, který je mimo rozsah této řady. Máte-li zájem o další informace, podívejte se do části „Signals and the init process“ v článku LWN Namespaces.
Za zmínku však stojí, že kterýkoli proces má PID 1 je zásadní pro životnost jmenných prostorů. Pokud PID 1 je z jakéhokoli důvodu ukončen, jádro odešle SIGKILL
všem zbývajícím procesům ve jmenném prostoru, čímž se tento jmenný prostor účinně vypne.
Zkoumání jmenných prostorů PID
Pokud vás zajímá, stejně jako já, zda můžete vnořit PID jmenné prostory, odpověď je ano. Ve skutečnosti jádro vytváří prostor až pro 32 vnořených PID jmenné prostory. Toto je považováno za jednosměrný vztah. To znamená, že rodič vidí PID dětí, vnoučat atd. Nevidí však žádné PID svých předků. Zvažte následující:
[user@localhost ~] sudo unshare -fp /bin/bash[root@localhost ~] spánek 90 000 &[root@localhost ~] ps -efUID PID PPID C STIME TTY [ . zkrácený TIME CMD] ...root 11627 11620 0 09:16 pts/0 00:00:00 sudo unshare -fp /bin/bashroot 11633 11627 0 0 09:17 0 3 09:17 3 0 0 0 1 0 3 0 0 0 0 16 0 0/0 09:17 bodů/0 00:00:00 /bin/bashroot 11639 11634 0 09:17 bodů/0 00:00:00 spánek 90:00:00 spánek 90000kořen 0:0:00 kořen 9 ps 0:0 @localhost ~] sudo unshare -fp /bin/bash[root@localhost ~] spánek 8000 &[root@localhost ~] ps -ef[zkrácený ].....UID PID PPID C STIME TTY TIME 10 6 3 ot. :17 bodů/0 00:00:00 sudo unshare -fp /bin/bashroot 11654 11650 0 09:17 pts/0 00:00:00 unshare -fp /bin/bashroot:0 9 0 9 0 7 0 7 00:00 /bin/bashroot 11661 11655 0 09:17 bodů/0 00:00:00 spánek 8000root 11671 11655 0 09:17 p ts/0 00:00:00 ps -ef
Všimněte si, že jsem výstup zkrátil, protože PID objeví se jmenný prostor abyste měli úplný přístup ke všem PID v /proc
. Pozorujte, co se stane, když se pokusíte zastavit proces, který je v předkovi:
[root@localhost ~] kill -9 11361bash:kill:(11361) - Žádný takový proces
Proč je to? Jednoduše řečeno, tradiční nástroje jako ps
neznají jmenný prostor a ve skutečnosti čtou z /proc
adresář. Pokud jste provedli ls /proc
, stále byste viděli všechny složky a soubory z dřívějška, protože, jak bylo uvedeno v minulém článku, PID jmenný prostor zdědí všechny z mnt připojení jmenného prostoru. Této situaci se budu věnovat později. Prozatím se vraťte k uvedenému příkladu.
V dalším prostředí identifikujte spící procesy:
[user@localhost ~] ps -ef |grep sleeproot 11639 11634 0 09:17 pts/0 00:00:00 spánek 90000root 11661 0 0 0 01 0:0 0 0 0 0 0 01 01 01 01
Pokud chcete ověřit, že tyto procesy jsou v různých jmenných prostorech, budete muset najít bash
zpracovat PID. Nezapomeňte, protože jste spustili sudo unshare -fp /bin/bash
, bash
proces je inicializace proces v novém jmenném prostoru. Proto je to PID, který bude spojen s ID jmenného prostoru. Vezmeme PID:
[root@localhost ~] ps -ef |grep bashroot 11627 11620 0 09:16 pts/0 00:00:00 sudo unshare -fp /bin/bashroot /9:7 pts 0 11130 11163 0 11163 0 :00:00 unshare -fp /bin/bashroot 11634 11633 0 09:17 pts/0 00:00:00 /bin/bashroot 11650 11634 0 070 09:sud:0 070 09 bashroot 11654 11650 0 09:17 pts/0 00:00:00 unshare -fp /bin/bashroot 11655 11654 0 09:17 09:17 09:17 09:17 pts/0:0 bin / 0
Můžete vidět PID 11634 a 11655 ve výstupu. Pokud to porovnáte s výstupem lsns
(seznam jmenných prostorů), uvidíte následující:
[root@localhost ~] lsns | grep bash ns typ nProcs pid user příkaz4026532952 pid 4 11634 root/bin/bash4026532954 pid 4 11655 root/bash
Jak můžete vidět, ID jmenného prostoru se liší, a proto jsou procesy v různých jmenných prostorech.
Nyní, když jste zjistili, že jmenné prostory jsou skutečně odlišné, podívejme se na výše zmíněný původ PID. Můžete to provést identifikací NSpid atribut daného PID v /proc
adresář, jak je vidět níže:
sudo cat /proc/11655/status |grep NSpidNSpid: 11655 6 1
Sloupce se čtou zleva doprava a označují PID ve svých příslušných jmenných prostorech. PID zcela vlevo je primární nebo kořenový jmenný prostor. V tomto případě má PID 11655 , sekundární PID 6 a terciární PID 1 . Protože jmenné prostory vlastní každý potomek PID jmenný prostor, můžete si to představit takto:
- Na hostiteli
bash
proces, na kterém běžísleep 8000
příkaz má PID 11655 . - Uvnitř prvního „kontejneru“
bash
proces, na kterém běžísleep 8000
příkaz má PID 6 . - Uvnitř vnořeného druhého „kontejneru“ je PID 1 . Toto je kontejner, který skutečně spustil proces.
Každý z těchto bash
příkazy byly vytvořeny ve vlastním jmenném prostoru, ale jsou viditelné pro nadřazeného prvku (v tomto případě root jmenný prostor).
/proc, PID a neprivilegovaní uživatelé
Bystrý čtenář by si všiml, že v posledních dvou článcích mohl běžný uživatel vytvořit oba uživatele a mnt jmenné prostory. V tomto článku jsem použil sudo
příkaz. Důvodem je, že nemůžete vytvořit PID jmenný prostor sám o sobě s neprivilegovaným uživatelem. Odpovědí na to je spojit více vytvořených jmenných prostorů do jedné události. Existuje několik různých řešení pro připojení /proc
jako neprivilegovaný uživatel.
Pokud se jednoduše pokusíte vytvořit nového uživatele jmenného prostoru, dostanete podivný výsledek:
[ user@localhost ~] unshare -Urp-bash:fork:Nelze alokovat paměť-bash-5.1# ps -ef-bash:fork:Nelze alokovat paměť-bash-5.1# ls-bash:fork:Nelze alokovat paměť
Co se tady děje? Pamatujte si, jak probíhá první proces uvnitř nového PID jmenný prostor se stává init proces? V tomto případě nemůže aktuální shell přesouvat jmenné prostory. Existuje v kořenovém adresáři jmenný prostor a když jste vytvořili nový PID jmenný prostor, systém nevěděl, jak s ním zacházet. Řešením je mít samotnou procesní vidlici. To umožňuje, aby se aktuální shell stal potomkem procesu unshare
příkaz. Pomocí -f
flag má za následek vytvoření jmenného prostoru:
[ uživatel@localhost ~] zrušit sdílení -Urfp[ root@localhost ~]
Stále však vidíte kontaminaci /proc
montážní bod. Na to existují dvě řešení. Nejprve můžete vytvořit nový mnt jmenný prostor a poté znovu připojte /proc
sebe:
[ user@localhost ~]$ unshare -Urpmf[ root@localhost ~]# mount -t proc proc /proc[ root@localhost ~]# ps -efUID PID PPID C STIME TTY 0 TIME 0 ot 1 09:31 bodů/0 00:00:00 -bashroot 10 1 0 09:31 bodů/0 00:00:00 ps -ef
Po mnoho let to byla jediná možnost, ale příznak --mount-proc
byla vytvořena před časem, aby to bylo možné provést v jediném kroku. Manuová stránka zní:
Těsně před spuštěním programu připojte souborový systém proc k bodu připojení (výchozí je /proc). To je užitečné při vytváření nového jmenného prostoru PID. Znamená to také vytvoření nového jmenného prostoru připojení, protože připojení /proc by jinak narušilo existující programy v systému. Nový souborový systém proc je explicitně připojen jako soukromý (s MS_PRIVATE|MS_REC).
Proto můžete vidět odkazy na následující příkaz:
unshare -Urpf --mount-proc
Tím se vytvoří nový mnt jmenný prostor při připojování /proc
pro vás.
Zadání jmenného prostoru
Pro snížení složitosti jsem opustil dříve vytvořené jmenné prostory. Vytvořil jsem nový jmenný prostor pomocí následujícího příkazu:
unshare -Urfp --mount-proc
Vytvořil jsem také jiné spát
proces jen proto, aby pomohl identifikovat jmenný prostor. Protože mám pouze jeden nový jmenný prostor, mohu použít lsns
příkaz k určení správného PID:
[ uživatel@localhost ~]$ lsns |grep bash4026532965 pid 2 13142 uživatel -bash
Poté spusťte nsenter
příkaz:
sudo nsenter -t 13142 -a
-a
příznak říká nsenter
zadejte všechny jmenné prostory tohoto PID. sudo
je vyžadováno s -a
příznak, jinak nebudete moci přejít na všechny příslušné jmenné prostory. Nyní byste měli být schopni vypsat všechny PIDS v tomto NS:
[root@localhost ~] $ ps -efuid pid ppid c stime tty time cmdroot 1 0 0 09:54 PTS/0 00:00:00 -BasHroot 8 1 0 09:54 PTS/0 00:00:00 spánek 99999root 25 0 0 10:15 pts/1 00:00:00 -bashroot 31 > 25 0 10:15 ps:0 0 10:15 pts:0
[ Naučte se základy používání Kubernetes v tomto bezplatném cheatu. ]
Koneckonců
PID jmenný prostor je důležitý, pokud jde o vytváření izolovaných prostředí. Umožňuje procesům mít své vlastní PID bez ohledu na hostitelský systém. Ve světě, kde může být do organizování izolovaných prostředí (kontejnerů) zapojeno více hostitelů, se stává zásadní mít zařízení, které zaručuje jedinečné PID při zmrazování a migraci procesů. Navíc z bezpečnostních důvodů, pokud provozujete jmenné prostory pro izolaci aplikací, PID jmenný prostor je životně důležitý pro zabránění úniku informací prostřednictvím procesů, které může hostitel spouštět.
V kombinaci s uživatelem a mnt jmenné prostory, PID jmenný prostor poskytuje velkou ochranu bez nutnosti oprávnění roota. Moderní prohlížeče jako Firefox a Vivaldi využívají jmenné prostory k poskytování sandboxingu prohlížeče. V příštím článku předvedu síť jmenný prostor a podívejte se, jak můžete pokračovat ve vytváření kontejneru ručně přidáním samostatných síťových komponent.
5 tipů pro rozhodování, které úlohy a zátěže Linuxu automatizovat
Stručný přehled rozhraní CNI (Container Network Interface) v Kubernetes
Linux