Difference between revisions of "singularity"

From DCEwiki
Jump to: navigation, search
m
m (Jak funguje singularity)
Line 7: Line 7:
 
== Jak funguje singularity ==
 
== Jak funguje singularity ==
  
Při spuštění shellový skript '''singularity''' nejprve zavolá soubor <code>/usr/lib/x86_64-linux-gnu/singularity/cli/shell.exec</code>
+
Při spuštění shellový skript '''singularity''' nejprve zavolá soubor <code>/usr/lib/x86_64-linux-gnu/singularity/cli/shell.exec</code>, který postupně provede následující operace:
 
   
 
   
Ten postupně provede následující operace:
+
# Zkontroluje jestli existují adresáře ve <code>/var/lib/singularity</code>.
+
# Pak, s využitím parametru ''offset'', napíchne na <code>loop</code> zařízení komprimovaný datový blok ze souboru s příponou <code>.simg</code> (obraz disku komprimovaný přes squashfs), a toto <code>loop</code> zařízení následně namountuje na adresář <code>/var/lib/singularity/mnt/container</code>.
# Zkontroluje jestli existují adresáře ve <code>/var/lib/singularity</code>
+
# Ten se poté použije jako podkladová vrstva do sendviče, který ji s využitím jaderného modulu <code>overlay</code> překryje zapisovatelnou vrstvou v RAM. Sestavený sendvič se namountuje na adresář <code>/var/lib/singularity/mnt/final</code>.
# Pak, s využitím parametru ''offset'', napíchne na <code>loop</code> zařízení komprimovaný datový blok ze souboru .simg (squashfs image), a toto <code>loop</code> zařízení následně namountuje na adresář <code>/var/lib/singularity/mnt/container</code>
+
# Do něj se pak zvenčí nabindují do kontejneru vybrané soubory (<code>passwd</code>, <code>localtime</code>, aj.) – zajímavé, dosud jsem myslel, že nabindovat se dá pouze adresář.
# Ten se pak použije jako podkladová vrstva pro sendvič, využívající kernelový modul <code>overlay</code>, který se namountuje na adresář <code>/var/lib/singularity/mnt/final</code>
+
# Nakonec se vytvoří přípojný bod pro domovský adresář uživatele, který se na něj namountuje.
# 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ář.
 
# 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
+
Takto [[singularity]] připraví kontejner, do kterého lze (dokud existuje) vstupovat několika způsoby:
{{Pozor|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}}
+
:; shell : Použije-li se '''shell''', tak [[singularity]] v kontejneru otevře novou konzoli, na které spustí shell. ''By default'' se spouští <code>/bin/sh</code>, ale tuto výchozí volbu lze přerazit, pokud se na příkazové řádce [[singularity]] předá cesta k jinému shellu parametrem <code>--shell</code>. V prostředí spuštěného shellu bude tato cesta uložena v proměnné SINGULARITY_SHELL.
; exec : Umožňuje spustit v prostředí kontejneru příkaz nebo shellový skript.
+
{{Pozor|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.}}
; 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.
+
:; exec : Přes '''exec''' lze spustit v prostředí virtualizovaného kontejneru konkrétní příkaz nebo shellový skript.
; test : Volá po spuštění příkazy nakonfigurované v rámci sekce %test
+
:; 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 <code>%runscript</code> ) – 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 <code>%test</code>
  
Využívá se při tom binárka <code>/usr/lib/x86_64-linux-gnu/singularity/bin/action-suid</code> která dovoluje v rámci kontejněru realizovat operace, pro něž by jinak byla nutná rootovská práva.
+
Při spouštění se [[singularity]] využívá binární utilitu <code>/usr/lib/x86_64-linux-gnu/singularity/bin/action-suid</code> která dovoluje v rámci kontejněru realizovat operace, pro něž by jinak byla nutná rootovská práva.
  
 
== Kontejner ==
 
== Kontejner ==

Revision as of 14:50, 17 September 2019

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