Hyppää sisältöön

Welcome to our weekly research support coffee hour on Zoom! Click here for more information.

Warning!

Puhti scratch disk is becoming very full (80+ % ) resulting in performance degradation. Everybody is advised to only keep actively processed data on scratch, all other data should be deleted, transferred to host institute or stored in Lumi-O. No new quota will be granted. Click here for a tool for examining your disk usage.

Apptainer-kontit

Tässä osiossa annetaan ohjeet konttien rakentamiseen ja ajamiseen Apptainerilla CSC:n supertietokoneilla. Vaikka keskitymme CSC-kohtaiseen käyttöön ja parhaisiin käytäntöihin, virallinen Apptainer-dokumentaatio toimii kattavana yleiskäytön viitteenä. Käytännönläheisiä ohjeita löydät Esimerkit -osiosta, joka sisältää CSC-järjestelmiin räätälöityjä konkreettisia esimerkkejä.

Huomaa, että Apptainer tunnettiin aiemmin nimellä Singularity, ja vanha nimi voi edelleen tulla vastaan ohjelmiston sisäisissä osissa ja vanhassa dokumentaatiossa. Projekti nimettiin uudelleen, kun se siirtyi Sylabsilta Linux Foundationille, mutta ydintoiminnallisuus pysyi samana. Sylabs ylläpitää projektista haarautusta nimeltä SingularityCE.

Perustelut

Apptainer-konttikuva on yksi pakattu tiedosto, joka sisältää kaiken sovelluksen ajamiseen tarvittavan. Tämä muuttumaton tiedosto sisältää täydellisen juuritiedostojärjestelmän, mukaan lukien kaikki sovellukset, kirjastot ja riippuvuudet, sekä metadataa, kuten ympäristömuuttujia ja ajonaikaisia asetuksia. Apptainer käyttää kuvilleen Singularity Image Format (SIF) -muotoa, jonka tunnistaa .sif-tiedostopäätteestä.

Apptainer-konttien avulla voit valita peruskuvaksi minkä tahansa Linux-jakelun, kuten Ubuntun, Rocky Linuxin tai OpenSUSEn, ja hyödyntää sen omaa paketinhallintaa ohjelmistojen asentamiseen kyseisessä ympäristössä. Konttien rakentamiseen CSC:n supertietokoneilla liittyy kuitenkin tiettyjä rajoituksia, erityisesti silloin, kun valittu peruskuva eroaa isäntäjärjestelmän Linux-jakelusta. Näitä ongelmia ja niiden ratkaisuja käsitellään tarkemmin myöhemmin.

Ohjelmiston ajaminen Apptainer-kontista voi merkittävästi parantaa käynnistysaikoja ja vähentää I/O-pullonkauloja Lustre rinnakkaistiedostojärjestelmässä. Tämä on erityisen hyödyllistä sovelluksille, jotka sisältävät paljon tiedostoja tai lataavat käynnistyksen aikana suuren määrän jaettuja kirjastoja. Esimerkiksi Python-ympäristöt ovat tunnettuja tästä ongelmasta laajojen moduuliriippuvuuksiensa ja dynaamisen latauskäyttäytymisensä vuoksi.

Apptainer-kontit varmistavat toistettavan suorituksen, koska niiden kuvat ovat muuttumattomia. Kun konttikuva on rakennettu, se pysyy muuttumattomana, mikä takaa yhdenmukaisen toiminnan eri järjestelmissä ja ajan kuluessa. Lisäksi Apptainerin build-määrittelyt dokumentoivat tarkasti vaiheet, paketit ja asetukset, joita käytettiin kontin luomiseen, mikä tekee koko rakennusprosessista läpinäkyvän ja toistettavan.

Konttikuvilla on yksi tärkeä rajoitus: ne eivät ole yhdisteltäviä. Toisin kuin perinteiset paketinhallintajärjestelmät, joissa ohjelmistoja voidaan lisätä järjestelmään vähitellen, olemassa olevia kontteja ei voi yksinkertaisesti yhdistää uuden kontin luomiseksi. Esimerkiksi se, että sinulla on yksi kontti Pythonille ja toinen R:lle, ei anna pääsyä molempiin ympäristöihin samanaikaisesti. Jos haluat käyttää molempia työkaluja yhdessä, sinun on luotava uusi konttikuva, joka sisältää sekä Python- että R-asennukset alusta alkaen.

Konttien ajaminen

Apptainerin käyttäminen suoraan

Oletetaan, että meillä on konttikuva nimeltä container.sif. Voimme suorittaa kontin sisällä mielivaltaisen komennon (korvaa mycommand) komennolla apptainer exec seuraavasti:

apptainer exec container.sif mycommand

Voimme tuoda isäntäjärjestelmän hakemistoja kontin sisälle bind mounttien avulla. Puhdissa ja Mahdissa voimme liittää eri levyalueet konttiin seuraavasti:

apptainer exec --bind="/users,/projappl,/scratch,$TMPDIR,$LOCAL_SCRATCH" container.sif mycommand

Voimme lisätä Nvidia GPU -tuen --nv-valitsimella seuraavasti:

apptainer exec --nv container.sif mycommand

Voimme käyttää samoja valitsimia myös komennoissa apptainer run ja apptainer shell.

Apptainer-wrapperin käyttäminen

Monet CSC:n tarjoamat ohjelmistoympäristöt, jotka käyttävät kontteja, tarjoavat käyttöön apptainer_wrapper-skriptin kautta. Wrapperi käyttää ympäristömuuttujia löytääkseen polun konttikuvaan (SING_IMAGE) ja välittääkseen valitsimia (SING_FLAGS), kuten --nv. Wrapperiskripti lisää automaattisesti valitsimet yleisille bind mount -liitoksille. Voimme suorittaa komentoja kontista seuraavasti:

export SING_IMAGE=/path-to/container.sif
export SING_FLAGS=""
apptainer_wrapper exec mycommand

Myös alikomennot apptainer_wrapper run ja apptainer_wrapper shell ovat käytettävissä.

Konttikuvien rakentaminen

Tässä osiossa kerrotaan, miten Apptaineria käytetään olemassa olevien Docker- ja OCI-kuvien muuntamiseen SIF-kuviksi, miten uusia SIF-kuvia rakennetaan määrittelytiedostoista ja miten kontteja voidaan kehittää interaktiivisesti muokattavana sandboxina eli (ch)root-hakemistona. Lisäksi käsittelemme sopivan rakennusympäristön ja resurssien, kuten muistin, asettamista rakentamista varten Puhdissa ja Mahdissa.

Linux-jakelun valitseminen peruskuvaksi

Kun valitset kontillesi peruskuvaa, voit valita useista Linux-jakeluista, joilla kullakin on oma paketinhallintansa. Red Hat Enterprise Linux (RHEL) -pohjaisissa jakeluissa, jotka käyttävät DNF-paketinhallintaa, suosittuja vaihtoehtoja ovat RedHat Universal Base Images (UBI), joita on saatavilla kuvina redhat/ubi8 ja redhat/ubi9, sekä yhteisövetoiset vaihtoehdot kuten rockylinux ja almalinux. Jos suosit SUSE-pohjaisia järjestelmiä, joissa käytetään Zypper-paketinhallintaa, opensuse/leap tarjoaa vakaan perustan. Debian-pohjaisissa jakeluissa, joissa käytetään APT-paketinhallintaa, sekä debian että ubuntu tarjoavat hyvin ylläpidettyjä peruskuvia laajoilla pakettivarastoilla.

Vaikka Apptainer mahdollistaa konttien rakentamisen käyttäen mitä tahansa Linux-jakelua peruskuvana, rakentamiseen CSC:n supertietokoneilla liittyy joitakin rajoituksia, koska käytössä on Apptainerin fakeroot-tila ilman etuoikeudettomia käyttäjänimiavaruuksia. Tässä ympäristössä tietyt etuoikeutetut komennot, joita suoritetaan yleisesti pakettien asennuksen aikana, epäonnistuvat. Esimerkiksi paketinhallinnat suorittavat usein etuoikeutettuja komentoja, kuten useradd ja groupadd, osana asennusskriptejään, ja nämä epäonnistuvat fakeroot-ympäristössä.

Käyttämällä peruskuvaa samasta tuoteperheestä kuin isäntäjärjestelmä vähennämme fakeroot-tilan käytöstä konttien rakentamisessa aiheutuvien ongelmien määrää. Jos käytät peruskuvaa, joka ei ole samasta tuoteperheestä kuin isäntäjärjestelmä, varaudu siihen, että useampia paketteja ei voida asentaa onnistuneesti. Paras tapa selvittää tämä on yrittää rakentaa kontti.

Voit tunnistaa isäntäjärjestelmäsi Linux-jakelun seuraavasti:

cat /etc/os-release
stdout
NAME="Rocky Linux"
VERSION="8.10 (Green Obsidian)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="8.10"
...

Lisäksi voimme korvata ongelmalliset komennot valeversioilla, jotka onnistuvat aina:

cp /usr/bin/true /usr/sbin/useradd
cp /usr/bin/true /usr/sbin/groupadd

Tämä lähestymistapa mahdollistaa pakettiasennusten onnistumisen ohittamalla käyttöoikeuksiin liittyvät virheet.

Ohjelmistojen asentaminen konttiin

Tyypillinen tapa asentaa ohjelmistoja konttiin on aloittaa käyttämällä järjestelmän paketinhallintaa, kuten DNF:ää, APT:tä tai Zypperiä, "järjestelmätason" ohjelmistojen asentamiseen hakemistoon /usr, ja asentaa sen jälkeen ohjelmistoja käyttäjätilan paketinhallinnalla, kuten Pipillä, Condalla tai Spackilla, tai asentaa ohjelmistoja käsin hakemistoon /usr/local tai yksilölliseen hakemistoon polun /opt alle.

Rakennussijainti

Voimme rakentaa kontteja millä tahansa solmulla, jolla on paikallinen levy käytettävissä. Kirjautumissolmuilla paikallinen levy on oletuksena käytettävissä. Jos haluamme rakentaa laskentasolmulla, voimme varata Slurm-työn paikallisella levyllä. Voimme esimerkiksi varata interaktiivisen työn paikallisella levyllä (--tmp) seuraavasti:

sinteractive --cores 4 --mem 4000 --tmp 10 --time 0:15:00

Väliaikaishakemisto

Ympäristömuuttujan TMPDIR on osoitettava paikalliselle levylle. Apptainer käyttää sitä tunnistaakseen hakemiston väliaikaishakemistokseen kontin rakentamisen aikana. Puhti- ja Mahti-klusterit asettavat TMPDIR-ympäristömuuttujan automaattisesti kirjautumissolmuilla, joilla paikallinen levy on oletuksena käytettävissä, sekä laskentasolmuilla, kun paikallinen levy on varattu. Lustren rinnakkaistiedostojärjestelmää ei voi (eikä pidä) käyttää väliaikaishakemistona.

Välimuistihakemisto

Apptainer tallentaa välimuistiin kerroksia ja blob-objekteja, kuten peruskuvia, välimuistihakemistoon. Oletussijainti on kotihakemistossa ($HOME/.apptainer), jossa on Puhdissa ja Mahdissa rajallinen kiintiö. Siksi välimuistin sijainti kannattaa ehkä vaihtaa scratch-alueelle, jotta kotihakemisto ei täyty (muuta project_id omaksi projektitunnukseksesi).

export APPTAINER_CACHEDIR=/scratch/project_id/$USER/.apptainer

Voimme myös tarvittaessa tyhjentää välimuistihakemiston:

apptainer cache clean

Virtuaalimuistin raja

Virtuaalimuistin raja Puhdin ja Mahdin kirjautumissolmuilla on melko pieni (10 GiB), ja sitä voidaan kasvattaa kovaan rajaan asti (24 GiB). Virtuaalimuistin rajan ylittäminen aiheuttaa muistivirheitä rakennuksen aikana. Voit tarkistaa nykyisen virtuaalimuistin rajan komennolla ulimit -v ja kovan rajan komennolla ulimit -Hv. Voimme asettaa virtuaalimuistin rajan kovaan rajaan seuraavasti:

ulimit -v $(ulimit -Hv)

Jos rakennusprosessisi loppuu virtuaalimuistiin kirjautumissolmulla, sinun kannattaa käyttää interaktiivista työtä, jossa virtuaalimuisti on rajattu työlle varatun muistin määrään.

Väliaikaishakemiston bind mounttaus

Oletuksena Apptainer bind mounttaa isäntäjärjestelmän /tmp-hakemiston rakennusympäristön /tmp-hakemistoksi. Puhdissa ja Mahdissa /tmp:n koko on kuitenkin rajallinen, joten bind mounttaamme paikallisen levyn ($TMPDIR) hakemistoon /tmp, jotta levytila ei lopu kesken, seuraavasti: --bind="$TMPDIR:/tmp".

SIF-kuvan rakentaminen olemassa olevasta Docker- tai OCI-kuvasta

Voimme hakea olemassa olevia konttikuvia konttirekisteristä pullaamalla ne. Apptainer muuntaa ne Docker- tai OCI-muodosta Singularity Image Format (SIF) -muotoon.

apptainer build rockylinux.sif docker://docker.io/rockylinux/rockylinux:8.10

SIF-kuvan rakentaminen määrittelytiedostosta

Apptainerin määrittelytiedostot käyttävät .def-tiedostopäätettä. Tässä on yksinkertainen esimerkki kontin määrittelystä:

container.def
Bootstrap: docker
From: docker.io/rockylinux/rockylinux:8.10

%post
    # Replace the failing commands with always succeeding dummies.
    cp /usr/bin/true /usr/sbin/useradd
    cp /usr/bin/true /usr/sbin/groupadd

    # Continue to install software into the container normally.
    dnf -y update  # would fail without the dummies

Voimme kutsua Apptaineria rakentamaan kontin (container.sif) määrittelytiedostosta (container.def) käyttäen fakerootia seuraavasti:

apptainer build --fakeroot --bind="$TMPDIR:/tmp" container.sif container.def

Katso lisää esimerkkejä Apptainerin määrittelytiedostoista Esimerkit -osiosta.

Kehittäminen interaktiivisella sandboxilla

Voimme myös rakentaa Apptainer-sandboxeja fakerootilla. Sandboxit ovat hyödyllisiä konttien interaktiivisessa kehittämisessä. Sandbox on luotava paikalliselle levylle ($TMPDIR), ei Lustren rinnakkaistiedostojärjestelmään.

Voimme alustaa sandboxin peruskuvasta seuraavasti:

apptainer build --fakeroot --sandbox "$TMPDIR/rockylinux" docker://docker.io/rockylinux/rockylinux:8.10

Sen jälkeen voimme käynnistää shellin sandboxissa ja asentaa siihen ohjelmistoja:

apptainer shell --fakeroot --writable --contain --cleanenv --bind="$TMPDIR:/tmp" "$TMPDIR/rockylinux"

Voimme käyttää samoja keinoja epäonnistuvien komentojen korvaamiseen sandboxissa:

cp /usr/bin/true /usr/sbin/useradd
cp /usr/bin/true /usr/sbin/groupadd

Nyt voimme asentaa ohjelmistoja normaalisti:

dnf -y update

Aineistojen lukeminen SquashFS-tiedostosta

Voimme myös välttää I/O-pullonkauloja aineistoissa, jotka koostuvat suuresta määrästä pieniä tiedostoja, pakkaamalla ne yhdeksi SquashFS-tiedostoksi. SquashFS-tiedosto voidaan bind mountata kontin sisälle, ja sitä voidaan käyttää vain luku -tilassa. Seuraava esimerkki purkaa aineiston paikalliselle levylle, luo aineistosta SquashFS-tiedoston ja siirtää sen sitten takaisin scratch-alueelle:

# Extract individual files to local drive
cd $TMPDIR
tar xf /scratch/project_id/mydataset.tar

# Create squashfs file
mksquashfs mydataset mydataset.sqfs -processors 4

# Move the resulting squashfs file back to the shared drive
mv mydataset.sqfs /scratch/project_id/

Nyt voimme bind mountata aineiston seuraavasti:

apptainer exec --bind=/scratch/project_id/mydataset.sqfs:/data:image-src=/ container.sif mycommand

Data on käytettävissä kontin sisällä polussa /data.

Konttiwrapperit

Tykky -konttiwrapperi on saatavilla kontitettujen Pip- ja Conda-asennusten luomiseen wrapperiskriptien avulla. Jos Tykky on sinulle ennestään tuttu, voit jatkaa sen käyttöä, mutta suosittelemme konttien rakentamista ja ajamista suoraan, kuten edellisissä osioissa on kuvattu.

Suomenkielinen tekoälykäännös

Sisällössä voi esiintyä virheellistä tietoa tekoälykäännöksestä johtuen.

Klikkaa tästä antaaksesi palautetta