singularity

Z DCEwiki
Skočit na navigaci Skočit na vyhledávání

Singularity je nástroj pro kontejnerovou virtualizaci linuxových distribucí, napsaný v C a Go. Využívá – podobně jako naše disklessová infrastruktura – jaderný modul overlay.

Kód uveřejněný pod BSD licencí roku 2015 vytvořil tým vývojářů z Berkeley Lab pod vedením Gregory Kurtzera.

V rámci FEL ČVUT se využívá singularity v rámci disklessového linuxu na Katedře kybernetiky, ke kontejnerové virtualizaci linuxové distribuce Ubuntu, protože ta má (na rozdíl od Debianu, na kterém je diskless postaven) v distribuci předkompilované nástroje pro práci s TurtleBoty (ROS).

Jak funguje singularity

Při spuštění shellový skript singularity nejprve zavolá soubor /usr/lib/x86_64-linux-gnu/singularity/cli/shell.exec, který postupně provede následující operace:

  1. Zkontroluje jestli existují adresáře ve /var/lib/singularity.
  2. Pak, s využitím parametru offset, napíchne na loop zařízení komprimovaný datový blok ze souboru s příponou .simg (obraz disku komprimovaný přes squashfs), a toto loop zařízení následně namountuje na adresář /var/lib/singularity/mnt/container.
  3. Ten se poté použije jako podkladová vrstva do sendviče, který ji s využitím jaderného modulu overlay překryje zapisovatelnou vrstvou v RAM. Sestavený sendvič se namountuje na adresář /var/lib/singularity/mnt/final.
  4. Do něj se pak zvenčí nabindují do kontejneru vybrané soubory (passwd, localtime, aj.) – zajímavé, dosud jsem myslel, že nabindovat se dá pouze adresář.
  5. Nakonec se vytvoří přípojný bod pro domovský adresář uživatele, který se na něj namountuje.

Takto singularity připraví kontejner, do kterého lze (dokud existuje) vstupovat několika způsoby:

shell
Použije-li se shell, tak singularity v kontejneru otevře novou konzoli, na které spustí shell. By default se spouští /bin/sh, ale tuto výchozí volbu lze přerazit, pokud se na příkazové řádce singularity předá cesta k jinému shellu parametrem --shell. V prostředí spuštěného shellu bude tato cesta uložena v proměnné SINGULARITY_SHELL.
Upozornění Pokud virtualizovaný kontejner neběží jako instance, budou – poté co konzoli opustíte všechny procesy spuštěné na pozadí ukončeny. Pokud tedy chcete v kontejneru spuštět služby, které mají běžet na pozadí, musíte použít jiný typ uživatelského přístupu (např. exec nebo run), nebo ho musíte spustit jako pojmenovanou instanci.
exec
Přes exec lze spustit v prostředí virtualizovaného kontejneru konkrétní příkaz nebo shellový skript.
run
Pokud se použije run, bude v prostření kontejneru spuštěn předdefinovaný skript (cesta k němu se uvede v rámci sekce %runscript ) – pokud nebude existovat, bude místo něj automaticky spuštěn shell.
test
Volá po spuštění příkazy nakonfigurované v rámci sekce %test

Při spouštění se singularity využívá binární utilitu /usr/lib/x86_64-linux-gnu/singularity/bin/action-suid která dovoluje v rámci kontejněru realizovat operace, pro něž by jinak byla nutná rootovská práva.

Kontejner

Singularity verze 3.x podporuje – kromě kontejnerů vytvořený s využitím squashfs – také kontejnery jaké používá docker, komprimované archívy i lokální adresáře.

.simg

Kontejner, který využívá squashfs (tak jak bylo popsáno výše) je výhodný tím, že jde o kompaktní instalaci podkladové vrstvy, zabalenou do jednoho komprimovaného souboru. Jeho použití je triviální:

$ singularity shell /cesta/k/souboru.simg

Nevýhodné je, že pokud do něj chceme dostat další aplikace, musíme ho buď sestavit znova, nebo použít persistentní overlay.

Persistentní overlay

Persistentní overlay, do sendviče přidává vrstvu, jejíž obsah se po ukončení práce nezahodí. Může to být buď virtuální blokové zařízení, pro jehož vytvoření lze využít příkaz image.create[1]:

$ singularity image.create moje-data.img

…nebo adresář. Ten pak předhodíme přes parametr --overlay:

$ sudo singularity shell --overlay my-overlay.img ubuntu.simg

Tohle řešení se hodí, pokud si chce někdo doinstalovat aplikaci, která chybí v referenčním kontejneru chybí, případně potřebuje prostor pro vlastní data, s nimiž bude v kontejneru pracovat.

Poznámka Pokud byste nespustili singularity přes sudo, tak byste neměli k instalaci práva.

Nové sestavení pomocí konfiguračního souboru

Pokud chcete přidat novou aplikaci do referenčního kontejneru, musíte udělat nový build.

To lze udělat dvěma způsoby. Obvykle se nový build dělá pomocí konfiguračního souboru, tzv. "receptu" (recipe), což není nic jiného než soubor, který obsahuje několik sekcí, které se postupně zavolají během sestavení aktualizované verze kontejneru.

Výhodu je, že takhle máme podchyceno co jsme do kontejneru přidali.

Vybalení referenčního kontejneru do adresáře

Druhá možnost je vybalit referenční kontejner do lokálního adresáře, upravit, a následně z něj vytvořit aktualizovanou verzi referenčního kontejneru ve formátu .simg – pokud tedy pro vás není lepší používat rovnou tento adresář.

Konverze kontejneru do lokálního adresáře

$ singularity build --sandbox development/ production.simg
Upozornění Abyste mohli vybalený kontejner upravit, musíte do něj "vstoupit" jako uživatel root (přes sudo) s parametrem --writable
$ sudo singularity shell --writable lolcow/

Bez toho je přístup k souborům překryté základní vrtvy jen pro čtení.

Sestavení nového kontejneru z aktualizovaného obsahu adresáře

$ singularity build production2 development/

Referenční kontejner

Abyste si mohli vytvořit vlastní build, musíte mít k dispozici výchozí referenční kontejner, který si pak budete upravovat.

Ten získáte buď tak, že…

  • …si odněkud stáhnete již připravený soubor s příponou .simg (lokální cesta k souboru)
  • Nebo použijete knihovnu kontejnerů (prefix library://)
  • Nebo stáhnete existující kontejner ze Singularity hub (prefix shub://)
  • Nebo zkonvertujete kontejner původně vytvořený pro Docker, tím že použijete Docker hub (prefix docker://)
  • Nebo předáte cestu k referenčnímu souboru s názvem Singularity, který získáte z repozitáře na githubu

Vlastní sestavení pak bude vypadat např. takto:

$ singularity build lokalni_kontejner.simg shub://GodloveD/lolcow

{{Poznámka| Více o použití Singularity hub pro vytvoření výchozího buildu viz dokumentace na githubu

Instance

ROS vyžaduje, aby běžel na pozadí proces roscore. Ten sice můžete spustit přes tmux v rámci jiného okna terminálu, ale mnohem praktičtější je použití pojmenované instance, která běží na pozadí jako služba.

To můžeme realizovat následujícím způsobem

$ singularity instance start /cesta/k/image jmeno_prvni_instance

Je-li singularity kontejner spuštěn takovým způsobem, zůstane spuštěný na pozadí a přistupovat do něj můžete buď přes run, nebo exec následujícím způsobem:

$ singularity run instance://jmeno_prvni_instance

vykoná akce nakonfigurované výchozím skriptem (napž nahození roscore) a

$ singularity exec instance://jmeno_prvni_instance cat /etc/os-release

vykoná konkrétní v kontejneru konkrétní příkaz.

Pochopitelně se dá v rámci spuštěné instance otevřít i shell:

$ singularity shell instance://jmeno_prvni_instance

Spuštěných instancí stejného konktejneru může být i více – stačí je pouze jinak pojmenovat. Jaké instance jsou k dispozici si lze jednoduše vypsat:

$ singularity instance list

Suuštěnou instanci lze ukončit příkazem

$ singularity instance stop jmeno_prvni_instance
Poznámka Je-li spuštěních instancí více než jedna, můžeme použít místo jména instance parametr --all (resp. -a)
  1. Singularity na základě tohoto příkazu vytvoří virtuální disk, formátovaný na ext3.