GNU/Linux >> Znalost Linux >  >> Linux

Ruční vytváření kontejnerů:jmenný prostor PID

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.


Linux
  1. Maximální hodnota ID procesu?

  2. Budování daňového cloudu

  3. Jak najdu ID procesu v Ubuntu?

  1. Ruční vytváření kontejneru pomocí jmenných prostorů:jmenný prostor UTS

  2. Jak vypočítat využití CPU procesu pomocí PID v Linuxu z C?

  3. Je zaručeno, že PID procesu zůstane stejné, dokud proces nezemře?

  1. Proč není Pgid procesů dítěte PGID rodiče?

  2. Linux – Nalezení PID procesu pomocí konkrétního portu?

  3. Který proces má Pid 0?