Panel | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
|
Uvod
Kontejner je standardna jedinica softvera koja pakira kod i sve njegove ovisnosti tako da se aplikacija može brzo i pouzdano pokretati u različitim okruženjima. Oni "sjede" na fizičkom serveru i njegovom operacijskom sustavu i s njim dijele kernel. Slični su virtualnim strojevima (eng. virtual machines ) utoliko što su također virtualizirani sustavi.
Međutim, za razliku od virtualnih strojeva koji sadrže cijele operacijske sustave i sve ovisnosti koje im trebaju za izvršavanje zadanih operacija (te su zbog toga zahtjevne za resurse), kontejeri s hostom dijele kernel, te u sebi sadržavaju samo aplikacije, njihove ovisnosti i potrebne biblioteke (eng. library).
Slika 1: Hipervizor sjedi na fizičkom stroju i omogućuje kreiranje virtualnih strojeva. Svaki virtualni stroj ima svoj operacijski sustav, i zauzima određene resurse potrebne za pokretanje odvojenih OS-a. S druge strane, kontejneri su povezani s operacijskim sustavom fizičkog računala te dijele njegov kernel i odvojene su samo aplikacije i njihove ovisnosti. Zbog toga kontejneri troše značajno manje resursa od virtualnih strojeva.
...
Apptainer
Singularity Apptainer je jedno od kontejnerskih rješenja. Glavna svojstva su mu:
- mobilnostmobilnost
- reproducibilnost
- korisnička sloboda
- podrška za HPC
Mobilnost računanja omogućuje da se workflow definira u kontejneru te korisnik može biti siguran da će se on moći izvršavati na različitim strojevima, neovisno o operacijskom sustavu (dok god je Linux! Singularity se oslanja na Linux kernel te ne radi na drugim operacijskim sustavima.) i i infrastrukturi. Mobilnost je osigurana time što se Singularity kontejneri spremaju u slike (eng. image) koje su jedna datoteka koja obuhvaća sve datoteke u kontejneru. Slike se mogu izgraditi kao read-only datoteke (tako se grade po defaultu) te je tako osigurana i reproducibilnost.
Korisnička sloboda se odnosi na mogućnost korisnika da unutar kontejnera instaliraju aplikacije s njima poželjnim verzijama i bibliotekama, neovisno o stanju na poslužitelju na kojem će taj kontejner kasnije pokretati. Dopremanjem kontejnera na bilo koji resurs, korisnici mogu koristiti aplikacije koje god žele.
Singularity Apptainer je kompatibilan s HPC-om. Podržava InfiniBand, ima podršku za MPI, radi bez problema s većinom raspoređivača poslova te ima podršku i za rad s GPU-ovima.
Korisnik unutar Singularity Apptainer kontejnera je isti onaj koji je i izvan kontejnera te ima jednake ovlasti unutar i izvan kontejnera. Ako se kontejner koristi na klasteru, korisnik ne može unutar kontejnera napredovati do root ovlasti te nema opasnosti da nehotično (ili namjerno) napravi štetu sustavu. Ako korisnik mora mijenjati kontejner, morat će to raditi na lokalnom računalu, na kojem ima root ovlasti, pa promijenjeni kontejner ponovno dopremiti na klaster.
Singularity Apptainer je vrlo jednostavan za korištenje. Koristi se kao bilo koja druga aplikacija (ne pokreće se servis kao npr. u slučaju Dockera - zato dobro radi s raspoređivačima poslova!).
...
-
build
: naredba za izgradnju kontejnera -
exec
: naredba za izvršavanje naredbe u kontejneru -
inspect
: naredba za gledanje labela, runscripti, test scripti te varijabli okoline -
pull
: naredba za povlačenje slika sa Singularity ili Docker Huba -
run
: naredba za pokretanje slike kao izvršne datoteke -
shell
: naredba za pokretanje ljuske u kontejneru
...
build
može kreirati kontejnere u tri dva različita formata. Prvi i defaultni format je squashfs - kontejneri u tom :
- image - temeljen na SquashFSu, kontejneri u ovom formatu su read-only
- sandbox - u formi direktorija, kontejneri u ovom formatu su pogodni za interaktivnu modifikaciju kontejnera opcijom
--writable
Osim izgradnje, naredbom build
može se konvertirati između image i sandbox formata, ili izgraditi kontejnere iz Apptainer recepta zvanih definition files i sve promjene koje se naprave u kontejneru nisu spremljene nakon što se izađe iz kontejnera. Još su dva formata: writable ext3 format koji je pogodan za interaktivno kreiranje kontejnera (opcija --writable
) te sandbox direktorij (također writable, koristi se opcija --sandbox
).Naredba build
se, osim za izgradnju kontejnera, može koristiti i za konvertiranje formata kontejnera između tri navedena formata te za izgradnju kontejnera iz Singularity recepta.
Izgradnja kontejnera iz Singularity Apptainer recepta se preporuča, budući da je tako osigurana reproducibilnost (svi koraci izgradnje kontejnera su sadržani u Singularity Apptainer receptu koji je vidljiv u kontejneru). Singularity
Apptainer recept se sastoji od dva glavna dijela:
- zaglavlje (
...
- engl. header )
...
- sekcija (
...
- engl. sections )
. Zaglavlje je obvezan dio recepta, dok su sekcije opcionalne. U zaglavlju se definira bazni OS koji se želi instalirati u kontejneru, a u sekcijama se navode svi ostali koraci koje želimo iskoristiti prilikom izgradnje kontejnera (npr. kopirati datoteke, instalirati softver, kreirati varijable okoline i sl.).
Slika 2: Shematski prikaz procesa izgradnje kontejnera. Zelenim strelicama su označene akcije koje se mogu izvoditi bez sudo
ovlasti, za akcije označene crvenim strelicama potrebno je imati sudo
ovlasti.
...
Workflow za izradu i korištenje kontejnera. Slika je preuzeta
sa stranice Singularitya; preteča Apptaineru koja funkcionira
na identičan način.
Apptainer recepti
Header
U headeru se definira bazni operacijski sustav koji će se koristiti u kontejneru. Osnovne ključne riječi su:
Bootstrap
- referencira tip baze koji će se koristiti
...
From
- ime kontejnera (ili referenca na layere u slučaju Dockera) koji će se koristiti
Tip Bootstrap
baze može biti na primjer:
shub
- za slike koje su na Singularity Hubu
...
docker
- za slike na Docker Hubu
...
localimage
- za slike spremljeno lokalno
Primjer za bazu shub
:. Ključna riječ From
je ime kontejnera (ili referenca na layere u slučaju Dockera) koji će se koristiti.
Code Block |
---|
Bootstrap: shub From: vsoch/hello-world |
Ovisno o vrijednosti za ključnu riječ Bootstrap
, dodatne ključne riječi mogu biti potrebne. Primjer za instalaciju Centosa-7 s mirror URL-om:
Code Block |
---|
Bootstrap: yum
OSVersion: 7
MirrorURL: http://mirror.centos.org/centos-%{OSVERSION}/%{OSVERSION}/os/$basearch/
Include: yum |
Više informacija o Singularity Apptainer receptima dostupno je u Singularity korisničkim uputamana službenim stranicama.
Sections
%help
Tekst koji se prikazuje kad se pozove singularity help.
%setup
Naredbe u ovoj sekciji se izvršavaju na host sustavu nakon što se bazni sustav instalira u kontejneru.
%files
U ovoj sekciji se kopiraju datoteke s host sustava u kontejner. Svaka linija je kombinacija izvor destinacija.
%labels
Ovdje se spremaju metapodaci vezani za kontejner.
%environment
Ovdje se dodaju varijable okoline. Treba imati na umu da se varijable u ovoj sekciji kreiraju tijekom runtime-a, tako da u slučaju da su potrebne tijekom procesa izgradnje kontejnera, treba ih također staviti u %post
sekciju kao u primjeru:
Code Block |
---|
%post
echo 'export TEST_VAR=test' >> $SINGULARITY_ENVIRONMENT |
%post
Naredbe u ovoj sekciji se izvršavaju unutar kontejnera nakon što je bazni operacijski sustav instaliran. Tu se radi kreiranje direktorija, instaliranje softvera i biblioteka. U ovoj sekciji se ne mogu kopirati datoteke, ali se mogu downloadati s naredbama git clone
, wget
ili curl
.
%runscript
...
Nakon zaglavlja, izgradnja i namještanje okoline kontejnera zapisuje se u poglavljima. Neka od najvažnijh su:
- %files - dostavljanje datoteka u kontejner
- %post - izvršavanje komandi unutar kontejnera tijekom izgradnje
- %environment - definicija varijabli okoline unutar kontejnera tijekom izvršavanja (nakon njegove izgradnje)
- %runscript - zadane naredbe koje se izvršavaju korištenjem
apptainer run ...
ili direktnim izvršavanjem kontejnera
Primjer recepta sa službenih stranica napisan ispod u sebi će:
- izgraditi osnovni operativni sustav Ubuntu v22.04
- dostaviti datoteku
hello_world.txt
unutar kontejnera u/my_data/hello_world.txt
- osvježiti apt repozitorije i instalirati aplikacije
cowsay
ilolcat
- uključiti izvršne datotke
cowsay
ilolcat
iz/usr/games
u korisničku okolinu - definirati izvršnu naredbu
date | cowsay | lolcat
kao zadanu - definirati autora kontejnera
Code Block | ||
---|---|---|
| ||
BootStrap: library
From: ubuntu:22.04
%files
hello_world.txt /my_data/hello_world.txt
%post
apt-get -y update
apt-get -y install cowsay lolcat
%environment
export LC_ALL=C
export PATH=/usr/games:$PATH
%runscript
date | cowsay | lolcat
%labels
Author GodloveD |
Navedeni recept (npr. apptainer.def
) možemo izgraditi u image naredbom build
:
Code Block | ||
---|---|---|
| ||
# izgradnja imagea korištenjem naredbe build
[korisnik@kompjuter:~] $ apptainer build apptainer.sif apptainer.def
...
INFO: Creating SIF file...
INFO: Build complete: apptainer.sif
# ispis detalja datoteke
[korisnik@kompjuter:~] $ ls -l apptainer.sif
-rwxr-xr-x 1 marko marko 83701760 svi 25 10:41 apptainer.sif |
Korištenje kontejnera
Kada jednom imamo gotov kontejner, postoji nekoliko naredbi za interagiranje s njim:
shell
- pokretanje korisničke ljuskeexec
- pokretanje naredberun
- pokretanje zadane naredbe
. Naredbom shell
pokreće se ljuska unutar kontejnera, te se interagira s kontejnerom kao da je pokrenuta ljuska na malom virtualnom stroju.
Code Block | ||
---|---|---|
| ||
# otvaranje ljuske [korisnik@kompjuter:~] $ singularity shell lolcow.simgapptainer.sif ... # izvršavanje komande unutar kontejnera Apptainer> date | cowsay _______________________________ < Thu May 25 10:59:05 CEST 2023 > ------------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || # izlaženje iz ljuske u kontejneru Apptainer> exit # izvršavanje iste komande izvan kontejnera [korisnik@kompjuter:~] $ date | cowsay bash: cowsay: command not found |
Naredbom exec
izvršava se naredba unutar kontejnera (npr. može se pokrenuti program koji je instaliran u kontejneru).:
Code Block | ||
---|---|---|
| ||
# izvršavanje naredbe cowsay unutar kontejnera [korisnik@kompjuter:~] $ date | singularity exec lolcow.simg ls /apptainer.sif cowsay ... < čet, 25.05.2023. 11:05:46 CEST > -- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || |
Naredbom run
pokreće se kontejner pozivanjem runscripte definirane u Singularity receptu.
Code Block | ||
---|---|---|
| ||
# izvršavanje komandom run [korisnik@kompjuter:~] $ singularity run lolcow.simg |
Kada se kontejner koristi, on automatski povezuje tri direktorija: /home/$USER
, /tmp
i $PWD
. Kontejner navedene direktorije "vidi" kao da su njegovi direktoriji. Dodatni direktoriji se mogu povezati naredbom --bind
. U tom slučaju, mora postojati direktorij unutar kontejnera koji će Singularity koristiti za povezivanje s direktorijem na hostu.
Podnošenje poslova na klasteru
apptainer.sif
...
< čet, 25.05.2023. 11:05:46 CEST >
--
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
# direktno izvršavanje
[korisnik@kompjuter:~] $ ./apptainer.sif
...
< čet, 25.05.2023. 11:06:05 CEST >
--
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| || |
Podnošenje kontejnera kao poslova na Supeku
U slučaju da se koristi Apptainer kontejner na SupekuU slučaju da se koristi Singularity kontejner na klasteru, podnošenje poslova je jednako kao i u slučaju aplikacija koje su instalirane direktno na klasteru, budući da klaster vidi Singularity kao običnu aplikaciju. .
Na primjer, ako želimo pokrenuti kontejner lolcow.simg apptainer.sif
nakon što ga dopremimo na Supek, minimalna SGE skripta PBS apptainer-test.sh
bit će:
Code Block | ||
---|---|---|
| ||
#!/bin/bash
#PBS -N apptainer-test
apptainer run apptainer.sif |
Koju možemo podnijeti na sljedeći način i provjeriti njen izlaz nakon malo vremena:
Code Block | ||
---|---|---|
| ||
# podnošenje skripte apptainer-test.sh
[korisnik@x3000c0s25b0n0:~] $ qsub apptainer-test.sh
# nakon par sekundi provjerimo sadržaj direktorija
[korisnik@x3000c0s25b0n0:~] $ ls -l apptainer-test*
-rw------- 1 mkvakic hpc 75 May 25 11:31 apptainer-test.e10537
-rw------- 1 mkvakic hpc 229 May 25 11:31 apptainer-test.o10537
-rw-r--r-- 1 mkvakic hpc 63 May 25 11:31 apptainer-test.sh
# ispišemo sadržaj standardnog izlaza
[korisnik@x3000c0s25b0n0:~] $ cat apptainer-test.o10537
_________________________________
< Thu May 25 09:31:17 Europe 2023 >
---------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| || |
Podnošenje MPI aplikacija unutar kontejnera
Apptainer podržava paralelizaciju i širenje na više čvorova korištenjem MPI standarda na dva načina:
- hybrid model - izvršavanje korištenjem MPI implementacije u kontejneru
- bind model - izvršavanje korištenjem MPI implementacije izvan kontejnera
Pri tom aplikacija koja koristi MPI mora biti : ABI kompatibilna (MPICH verzija v3.1 nadalje). Način na koji se to inače postiže je dopremanjem knjižnice libmpi.so.12
putem varijable okoliša LD_LIBRARY_PATH
prije poziva aplikacije:
Code Block | ||
---|---|---|
| ||
# postavljanje LD_LIBRARY_PATH
[korisnik@kompjuter] $ export LD_LIBRARY_PATH=/putanja/do/libmpi.so.12:$LD_LIBRARY_PATH
# izvršavanje aplikacijom mpiexec
[korisnik@kompjuter] $ mpiexec -np 10 ./moja_ABI_kompatibilna_MPI_aplikacija |
U slučaju kontejnera, varijable okoliša se uglavnom nasljeđuju od računala s kojeg se pokreće, no u ovom slučaju potrebno je dodatno namjestiti okolinu što se može učiniti na dva načina:
- korištenjem
--env
ili--env-file
opcije pri pokretanju kontejnera - namještanjem
APPTAINERENV_*
varijable okoliša prije pozivanja kontejnera
Na Supeku je potrebno je koristiti bind model, zbog knjižnica koje osiguravaju integraciju sa sustavom za upravljanje PBS i mrežom Slingshot. Moduli koji osiguravaju spajanje definicijom varijabli okoliša CRAY_LD_LIBRARY_PATH
i LD_LIBRARY_PATH
su:
-
cray-pals
- integracija s PBS-om cray-mpich-abi
- dostavljanje ABI kompatibilnih knjižnicacray-pmi
- knjižnica za spajanje s Crayevim sučeljem za pokretanje paralelnih programalibfabric
- mrežni API za spajanje na Slinghot
Dodatno, pri pozivu se moraju spojiti odgovarajući direktoriji u kontejner:
/opt
- putanja za knjižnice Cray/run
- putanja za PBS/usr/lib64
- putanja za sistemske knjižnice
Pri podnošenju posla na Crayu, to se može učiniti na sljedeći način (primjerice, u skripti PBS mpi-test.sh
) :
Code Block | ||
---|---|---|
| ||
Code Block | ||
| ||
#!/bin/shbash #$#PBS -N singularity-test #$ -cwd singularity run lolcow.simg |
A posao se podnosi (ako se gore navedena skripta zove singularity-test.sh
) standardno sa:
mpi-test
#PBS -l select=2:ncpus=1
#PBS -l place=scatter
# dopremanje modula
module load PrgEnv-gnu
module load cray-mpich-abi
module load cray-pals
module load cray-pmi
module load libfabric
# namještanje okolišne varijable LD_LIBRARY_PATH u kontejneru:
#
# 1) CRAY_LD_LIBRARY_PATH - Cray knjižnice iz /opt
# 2) LD_LIBRARY_PATH - sistemske knjižnice iz /usr/lib64
# 3) \$LD_LIBRARY_PATH - očuvanje varijable ako već postoji u kontejneru
# 4) /opt/cray/pe/pals/1.2.3/lib - putanja za PALS servis
#
APPTAINERENV_LD_LIBRARY_PATH="${CRAY_LD_LIBRARY_PATH}:${LD_LIBRARY_PATH}:\$LD_LIBRARY_PATH:/opt/cray/pe/pals/1.2.3/lib"
# izvršavanje kontejnera mpi-test.sif s aplikacijom mpiexec modula cray-pals
mpiexec \
singularity exec \
--bind /opt \
--bind /run \
--bind /usr/lib64 \
mpi4py-install.sif \
/myapp/mpi-test |
Gdje je su recept za izgradnju kontejnera mpi-test.sif
i aplikacija mpi-test.c
:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
Bootstrap: docker
From: rockylinux:8
%files
mpi-test.c /myapp/
%environment
export LD_LIBRARY_PATH=/usr/lib64/mpich/lib:$LD_LIBRARY_PATH
export PATH=/usr/lib64/mpich/bin:$PATH
%post
# dnf
dnf update -y
dnf install mpich-devel -y
# mpich
export LD_LIBRARY_PATH=/usr/lib64/mpich/lib:$LD_LIBRARY_PATH
export PATH=/usr/lib64/mpich/bin:$PATH
# hello world
mpicc -o /myapp/mpi-test /myapp/mpi-test.c |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
// Author: Wes Kendall
// Copyright 2011 www.mpitutorial.com
// This code is provided freely with the tutorials on mpitutorial.com. Feel
// free to modify it for your own use. Any distribution of the code must
// either provide a link to www.mpitutorial.com or keep this header intact.
//
// An intro MPI hello world program that uses MPI_Init, MPI_Comm_size,
// MPI_Comm_rank, MPI_Finalize, and MPI_Get_processor_name.
//
#include <mpi.h>
#include <stdio.h>
int main(int argc, char** argv) {
// Initialize the MPI environment. The two arguments to MPI Init are not
// currently used by MPI implementations, but are there in case future
// implementations might need the arguments.
MPI_Init(NULL, NULL);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// Print off a hello world message
printf("Hello world from processor %s, rank %d out of %d processors\n",
processor_name, world_rank, world_size);
// Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize();
} |
Note | ||
---|---|---|
| ||
Zbog bind model spajanja, potrebno je koristiti operativne sustave koji su slični operativnom sustavu Supeka Red Hat Enterprise Linux 8.6 | ||
Code Block | ||
$ qsub singularity-test.sh |