GNU/Linux >> Znalost Linux >  >> Linux

Ruční vytváření kontejneru pomocí jmenných prostorů:jmenný prostor připojení

Tento článek se zabývá připojením jmenný prostor a je třetí v řadě Linux Namespace. V prvním článku jsem uvedl sedm nejpoužívanějších jmenných prostorů, čímž jsem položil základy pro praktickou práci započatou v článku o uživatelských jmenných prostorech. Mým cílem je vybudovat základní znalosti o tom, jak fungují základy linuxových kontejnerů. Pokud vás zajímá, jak Linux řídí prostředky v systému, podívejte se na sérii CGroup, kterou jsem psal dříve. Doufejme, že až skončíte s praktickou prací se jmennými prostory, dokážu CGroups a jmenné prostory smysluplným způsobem spojit dohromady a dokončit obrázek za vás.

Prozatím však tento článek zkoumá jmenný prostor mount a jak vám může pomoci přiblížit se k pochopení izolace, kterou linuxové kontejnery přinášejí správcům systému a potažmo platformám jako OpenShift a Kubernetes.

[ Také by se vám mohlo líbit: Sdílení doplňkových skupin s kontejnery Podman ]

Jmenný prostor připojení

Jmenný prostor připojení se po vytvoření nového uživatelského jmenného prostoru nechová tak, jak byste mohli očekávat. Ve výchozím nastavení, pokud byste vytvořili nový jmenný prostor připojení pomocí unshare -m Váš pohled na systém by zůstal do značné míry nezměněn a neomezený. Je to proto, že kdykoli vytvoříte nový jmenný prostor připojení, kopii bodů připojení z nadřazeného jmenného prostoru se vytvoří v novém jmenném prostoru připojení. To znamená, že jakákoli akce provedená se soubory ve špatně nakonfigurovaném jmenném prostoru připojení bude ovlivnit hostitele.

Některé kroky nastavení pro připojení jmenných prostorů

K čemu je tedy jmenný prostor připojení? Abych to demonstroval, používám tarball Alpine Linux.

Stručně řečeno, stáhněte si jej, zrušte jeho rozbalení a přesuňte jej do nového adresáře, čímž udělíte oprávnění k adresáři nejvyšší úrovně pro neprivilegovaného uživatele:

[root@localhost ~] export CONTAINER_ROOT_FOLDER=/container_practice[root@localhost ~] mkdir -p ${CONTAINER_ROOT_FOLDER}/fakeroot[root@localhost ~] cd ${CONTAINER_ROOT_FOLDER]hostitel ~root@ https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-minirootfs-3.13.1-x86_64.tar.gz[root@localhost ~] tar xvf alpine-minirootfs-3.11. -x86_64.tar.gz -C fakeroot[root@localhost ~] chown kontejner-uživatel. -R ${CONTAINER_ROOT_FOLDER}/fakeroot 

fakeroot adresář musí vlastnit uživatel container-user protože jakmile vytvoříte nový uživatelský jmenný prostor, root uživatel v novém jmenném prostoru bude mapován na container-user mimo jmenný prostor. To znamená, že proces uvnitř nového jmenného prostoru si bude myslet, že má schopnosti potřebné k úpravě svých souborů. Oprávnění systému souborů hostitele však zabrání uživateli kontejneru účet před změnou souborů Alpine z tarballu (které mají root jako vlastník).

Co se tedy stane, když jednoduše spustíte nový jmenný prostor připojení?

PS1='\u@new-mnt$ ' unshare -Umr 

Nyní, když jste v novém jmenném prostoru, možná neočekáváte, že uvidíte některý z původních přípojných bodů od hostitele. To však není tento případ:

root@new-mnt $ df -hfilesystem Velikost použitá k dispozici k použití% namontováno/dev/mapper/cs-root 36g 5,2G 31g 15%/tmpfs 737m 0 737m 0%/Sys/FS/CGroupDevTM 720M 0 720M 0% /DEVTMPFS 737M 0 737M 0% /DEV /SHMTMPFS 737M 8,6M 728M 2% /RUNTMPFS 148M 0 148M /RUN /RUN /User /Dev /VDA1 976M 713M 22% /Bootroot@new-MNT $ ls /bin   container_practice  etc   lib    media  opt   root  sbin  sys  usrboot  dev                 home  lib64  mnt    proc  run   srv   tmp  var

Důvodem je to, že systemd výchozím nastavením je rekurzivní sdílení přípojných bodů se všemi novými jmennými prostory. Pokud jste připojili tmpfs souborový systém někde, například /mnt v novém jmenném prostoru připojení, může to hostitel vidět?

root@new-mnt$ mount -t tmpfs tmpfs /mntroot@new-mnt$ findmnt |grep mnt└─/mnt     tmpfs               tmpfs      rw,label=100,0 

Hostitel však toto nevidí:

[root@localhost ~]# findmnt |grep mnt 

Přinejmenším tedy víte, že jmenný prostor připojení funguje správně. Nyní je vhodný čas udělat si malou odbočku k diskusi o šíření bodů připojení. Stručně shrnu, ale pokud máte zájem o větší porozumění, podívejte se na článek Michaela Kerriska na LWN a také na manuálovou stránku jmenného prostoru mount. Obvykle se na manuálové stránky tolik nespoléhám, protože často zjišťuji, že nejsou snadno stravitelné. Nicméně v tomto případě jsou plné příkladů a v (většinou) jednoduché angličtině.

Teorie přípojných bodů

Připojení se šíří ve výchozím nastavení kvůli funkci v jádře zvané sdílený podstrom . To umožňuje, aby měl každý přípojný bod přidružen svůj vlastní typ šíření. Tato metadata určují, zda se nová připojení pod danou cestou šíří do jiných přípojných bodů. Příklad uvedený v manuálové stránce je příklad optického disku. Pokud je váš optický disk automaticky připojen pod /cdrom , obsah by byl viditelný v jiných jmenných prostorech pouze v případě, že je nastaven vhodný typ šíření.

Skupiny a stavy připojení

Dokumentace jádra říká, že "skupina vrstevníků je definována jako skupina vfsmountů, které mezi sebou přenášejí události." Události jsou věci, jako je připojení síťové sdílené položky nebo odpojení optického zařízení. Proč je to důležité, ptáte se? No, pokud jde o jmenný prostor připojení, skupiny vrstevníků jsou často rozhodujícím faktorem, zda je držák viditelný a lze s ním pracovat. Stav připojení určuje, zda může událost přijmout člen v peer skupině. Podle stejné dokumentace jádra existuje pět stavů připojení:

  1. sdíleno - Mount, který patří do skupiny vrstevníků. Veškeré změny, ke kterým dojde, se rozšíří mezi všechny členy partnerské skupiny.
  2. otrok - Jednosměrné šíření. Hlavní přípojný bod bude šířit události na slave, ale master neuvidí žádné akce, které slave provede.
  3. sdílený a otrok - Označuje, že přípojný bod má master, ale má také svou vlastní skupinu peer. Hlavní nebude upozorněn na změny přípojného bodu, ale všichni členové peer skupiny po proudu ano.
  4. soukromé - Nepřijímá ani nepředává žádné události šíření.
  5. nesvázatelné - Nepřijímá ani nepředává žádné události šíření a nemůže být připojeno.

Je důležité si uvědomit, že stav přípojného bodu je na přípojný bod . To znamená, že pokud máte / a /boot , například byste museli samostatně aplikovat požadovaný stav na každý přípojný bod.

V případě, že se zajímáte o kontejnery, většina kontejnerových motorů používá při montáži objemu do kontejneru stavy soukromého připojení. Zatím si s tím moc nedělejte starosti. Chci jen uvést nějaký kontext. Pokud si chcete vyzkoušet nějaké konkrétní scénáře připojení, podívejte se na manuálové stránky, protože příklady jsou docela dobré.

Vytvoření našeho jmenného prostoru připojení

Pokud používáte programovací jazyk, jako je Go nebo C, můžete použít nezpracovaná volání jádra systému k vytvoření vhodného prostředí pro své nové jmenné prostory. Protože však záměrem je pomoci vám porozumět tomu, jak interagovat s kontejnerem, který již existuje, budete muset udělat nějaký bash trik, abyste dostali svůj nový jmenný prostor připojení do požadovaného stavu.

Nejprve vytvořte nový jmenný prostor připojení jako běžný uživatel:

unshare -Urm 

Jakmile jste uvnitř jmenného prostoru, podívejte se na findmnt mapovacího zařízení, které obsahuje kořenový souborový systém (pro stručnost jsem z výstupu odstranil většinu možností připojení):

findmnt |grep mapper/       /dev/mapper/cs-root      xfs           rw,relatime,[...] 

Existuje pouze jeden přípojný bod, který má mapovač kořenového zařízení. To je důležité, protože jednou z věcí, které musíte udělat, je svázat mapovací zařízení s adresářem Alpine:

export CONTAINER_ROOT_FOLDER=/container_practicemount --bind ${CONTAINER_ROOT_FOLDER}/fakeroot ${CONTAINER_ROOT_FOLDER}/fakerootcd ${CONTAINER_ROOT_FOLDER}/fakeroot 

Je to proto, že používáte nástroj s názvem pivot_root pro provedení chroot -jako akce. kořenový_adresář_klíče má dva argumenty:new_root a old_root (někdy označované jako put_old ). kořenový_adresář_klíče přesune kořenový souborový systém aktuálního procesu do adresáře put_old a vytvoří new_root nový kořenový souborový systém.

DŮLEŽITÉ :Poznámka o chroot . chroot je často považován za mající další bezpečnostní výhody. Do jisté míry je to pravda, protože k tomu, abyste se z toho vymanili, je potřeba většího množství odborných znalostí. Pečlivě vytvořený chroot může být velmi bezpečný. Nicméně chroot nemění ani neomezuje možnosti Linuxu, kterých jsem se dotkl v předchozím článku o jmenném prostoru. Ani to neomezuje systémová volání na jádro. To znamená, že dostatečně zkušený agresor by mohl potenciálně uniknout chrootu že to nebylo dobře promyšlené. Připojovací a uživatelské jmenné prostory pomáhají tento problém vyřešit.

Pokud používáte kořenový_adresář_kontingenčního bodu bez připojení vazby příkaz odpoví:

pivot_root:nepodařilo se změnit kořenový adresář z `.' to `old_root/':Neplatný argument 

Chcete-li přejít na kořenový souborový systém Alpine, nejprve vytvořte adresář pro old_root a poté se natočte do zamýšleného (Alpine) kořenového souborového systému. Protože kořenový souborový systém Alpine Linux nemá symbolické odkazy pro /bin a /sbin , budete je muset přidat do cesty a nakonec odpojit old_root :

mkdir old_rootpivot_root . old_rootPATH=/bin:/sbin:$PATHumount -l /old_root 

Nyní máte příjemné prostředí, kde uživatel a připojit jmenné prostory spolupracují a poskytují vrstvu izolace od hostitele. Již nemáte přístup k binárním souborům na hostiteli. Zkuste zadat findmnt příkaz, který jste použili dříve:

root@new-mnt$ findmnt-bash:findmnt:příkaz nenalezen 

Můžete se také podívat na kořenový souborový systém nebo se pokusit zjistit, co je připojeno:

root@new-mnt$ ls -l /celkem 12drwxr-xr-x    2 kořen     kořenový adresář          4096 28. ledna 21:51 bindrwxr-xr-x    2 kořenový     kořenový adresář    2  -1  dř 15 Root Root 4096 Jan 28 21:51 atddrwxr-xr-x 2 root root 6. ledna 28 21:51 Homedrwxr-Xr-X 7 Root Root 247 Jan 28 21:51 libdrwxr-xr-x 5 kořen kořenů 44 leden 28 21::51 MediaDrwxr-XR-X 2 Root Root 6. ledna 28 21:51 MNTDRWXRWXR-X 2 Root Root 6. února 23:09 Old_rootdrwxr-xr-x 2 Root Root 6. ledna 28 21:51 OPTDRWXR-XR-X 2 Root Root 6 28. ledna 21:51 Procdrwxr-xr-x 2 Root Root 6. února 17. února 22:53 put_olddrwx ------ 2 Root Root 27. února 17. 22:53 Rootdrwxr-XR-x 2 Root Root 6. ledna 28. 21:51 Rudrwxr -xr-x    2 kořen     kořen          4096 28. ledna 21:51 sbindrwxr-xr-x    2 kořen     kořen             6. ledna 28 21:51 srvdrwxr-xr- x    root 28 21:51 sysdrwxrwxrwt 2 Root Root 6. února 19. 16:38 Tmpdrwxr-xr-x 7 kořen 66 leden 28 21:51 USRDRWXR-XR-X 12 Root Root 137 leden 28 21:51 Varroot@new-MNT $ MountMount :žádné /proc/mounts 

Zajímavé je, že neexistuje žádný proc souborový systém je standardně připojen. Zkuste jej připojit:

root@new-mnt$ mount -t proc proc /procmount:oprávnění odepřeno (jste root?)root@new-mnt$ whoamiroot 

Protože proc je speciální typ připojení související s jmenným prostorem PID, nemůžete jej připojit, i když jste ve svém vlastním jmenném prostoru připojení. To se vrací k dědičnosti schopností, o které jsem hovořil dříve. Tuto diskuzi naberu v příštím článku, až se budu věnovat jmennému prostoru PID. Pro připomenutí dědičnosti se však podívejte na níže uvedený diagram:

V příštím článku tento diagram zopakuji, ale pokud jste to sledovali od začátku, měli byste být schopni udělat nějaké závěry předtím.

[ Uživatelská příručka API:7 osvědčených postupů účinných programů API ] 

Koneckonců

V tomto článku jsem se zabýval nějakou hlubší teorií kolem jmenného prostoru mount. Diskutoval jsem o skupinách vrstevníků a jejich vztahu ke stavům připojení, které jsou aplikovány na každý bod připojení v systému. Pro praktickou část jste si stáhli minimální souborový systém Alpine Linux a poté si prošli, jak používat uživatele a připojovat jmenné prostory k vytvoření prostředí, které vypadá hodně jako chroot s výjimkou potenciálně bezpečnějšího.

Prozatím otestujte připojování souborových systémů uvnitř i vně vašeho nového jmenného prostoru. Zkuste vytvořit nové přípojné body, které používají sdílené , soukromé a slave montážní stavy. V příštím článku použiji jmenný prostor PID k dalšímu vytváření primitivního kontejneru, abyste získali přístup k proc souborový systém a izolace procesů.


Linux
  1. Odstraňte problémy s použitím souborového systému proc na Linuxu

  2. Demystifikace jmenných prostorů a kontejnerů v Linuxu

  3. Budování důvěry v linuxovou komunitu

  1. 7 nejpoužívanějších jmenných prostorů Linuxu

  2. Jak snížit zátěž registru kontejnerů pomocí Quay.io

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

  1. Ověření platnosti připojení NFS

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

  3. Docker v Dockeru nemůže připojit svazek