singularity

From DCEwiki
Revision as of 14:07, 17 September 2019 by Keny (talk | contribs)
Jump to: navigation, search

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

Ten postupně provede následující operace:

  1. Zkontroluje jestli existují adresáře ve /var/lib/singularity
# Pak, s využitím parametru offset, napíchne na loop zařízení komprimovaný datový blok ze souboru .simg (squashfs image), a toto loop zařízení následně namountuje na adresář /var/lib/singularity/mnt/container
  1. Ten se pak použije jako podkladová vrstva pro sendvič, využívající kernelový modul overlay, který se namountuje na adresář /var/lib/singularity/mnt/final
  2. Do něj se pak nabindují do kontejneru vybrané soubory zvenčí (passwd, localtime, aj.) – zajímavé, dosud jsem myslel, že nabindovat se dá pouze adresář.
  3. Nakonec se vytvoří mountpoint pro domovský adresář uživatele, na který namountuje domovský adresář uživatele (home).

Takto singularity připraví kontejner, do kterého uživatel může přistoupit několika způsoby:

shell 
Pokud se spustí kontejner s parametrem shell, tak se po spuštění kontejneru spustí na otevřené konzoli shell. By default se spouští /bin/sh, ale tuto výchozí volbu lze přerazit tím, že se na řádce předá cesta k jinému shellu coby parametr volby --shell. Ve spuštěném prostředí bude tato cesta uložena v proměnné SINGULARITY_SHELL
Upozornění Pokud opustíte spuštěný shell, budou všechny spuštěné procesy ukončeny. Pokud tedy chcete mít kontejner spuštěný na pozadí, musíte použít jiný typ uživatelského přístupu. Např. exec nebo run
exec 
Umožňuje spustit v prostředí kontejneru příkaz nebo shellový skript.
run 
Pokud se použije run, bude po spuštění 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

Využívá se při tom binárka /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 nejenom vlastní formát kontejnerů vytvořený s využitím squashfs. Umí použít také formát co používá docker, komprimovaný archív nebo rovnou adresář.

.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.