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 viitteenä yleiseen käyttöön. 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. Projektin nimi muutettiin, kun se siirtyi Sylabsilta Linux Foundationille, mutta ydintoiminnallisuus pysyi samana. Sylabs ylläpitää projektista haarautettua versiota nimeltä SingularityCE.
Perustelut
Apptainer-kontti-imago 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 ajoaikaisia asetuksia.
Apptainer käyttää imageilleen Singularity Image Format (SIF) -muotoa, jonka tunnistaa .sif-tiedostopäätteestä.
Apptainer-konttien avulla voit valita perusimageksi minkä tahansa Linux-jakelun, kuten Ubuntun, Rocky Linuxin tai OpenSUSEn, ja hyödyntää sen omaa paketinhallintaa ohjelmistojen asentamiseen kyseiseen ympäristöön. Konttien rakentamiseen CSC:n supertietokoneilla liittyy kuitenkin tiettyjä rajoituksia, erityisesti silloin, kun valittu perusimage poikkeaa 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 ajon, koska niiden imagot ovat muuttumattomia. Kun kontti-imago on kerran rakennettu, se pysyy muuttumattomana, mikä takaa yhdenmukaisen toiminnan eri järjestelmissä ja ajan kuluessa. Lisäksi Apptainerin build-määrittelyt dokumentoivat tarkasti ne vaiheet, paketit ja asetukset, joilla kontti on luotu, mikä tekee koko rakennusprosessista läpinäkyvän ja toistettavan.
Kontti-imageilla on yksi tärkeä rajoitus: ne eivät ole yhdisteltäviä. Toisin kuin perinteisissä paketinhallintajärjestelmissä, joissa ohjelmistoja voidaan lisätä järjestelmään vaiheittain, olemassa olevia kontteja ei voi yksinkertaisesti yhdistää uuden kontin luomiseksi. Esimerkiksi yksi Pythonin sisältävä kontti ja toinen R:n sisältävä kontti eivät anna pääsyä molempiin ympäristöihin samanaikaisesti. Jos haluat käyttää molempia työkaluja yhdessä, sinun on luotava uusi kontti-imago, joka sisältää sekä Python- että R-asennukset alusta alkaen.
Konttien ajaminen
Apptainerin käyttäminen suoraan
Oletetaan, että meillä on kontti-imago nimeltä container.sif.
Voimme suorittaa mielivaltaisen komennon (korvaa mycommand) kontin sisällä komennolla apptainer exec seuraavasti:
Voimme tuoda isäntäjärjestelmän hakemistoja saataville kontin sisällä bind mounttien avulla. Roihussa ja Mahdissa voimme liittää eri levyalueet konttiin seuraavasti:
Roihussa voimme käyttää komentoa csc-common-bind yleisten levyalueiden bind mounttaamiseen:
Voimme lisätä Nvidia GPU -tuen --nv-valitsimella seuraavasti:
Voimme käyttää samoja valitsimia myös komentojen apptainer run ja apptainer shell kanssa.
Apptainer-wrapperin käyttäminen (vanhentunut)
Apptainer-wrapper on vanhentunut
Apptainer-wrapper on vanhentunut. Se ei ole käytettävissä Roihussa. Käytä sen sijaan Apptaineria suoraan.
Monet CSC:n tarjoamat ohjelmistoympäristöt, jotka käyttävät kontteja, tarjoavat pääsyn apptainer_wrapper-skriptin kautta.
Wrapper käyttää ympäristömuuttujia löytääkseen polun kontti-imageen (SING_IMAGE) ja välittääkseen valitsimia (SING_FLAGS), kuten --nv.
Wrapper-skripti lisää automaattisesti valitsimet yleisille bind mounteille.
Voimme suorittaa komentoja kontista seuraavasti:
Myös alikomennot apptainer_wrapper run ja apptainer_wrapper shell ovat käytettävissä.
Kontti-imagejen rakentaminen
Tässä osiossa kerrotaan, miten Apptainerilla muunnetaan olemassa olevia Docker- ja OCI-imageja SIF-imageiksi, miten uusia SIF-imageja rakennetaan määrittelytiedostoista ja miten kontteja voidaan kehittää interaktiivisesti muokattavana sandboxina käyttäen (ch)root-hakemistoa. Lisäksi käsittelemme sopivan rakennusympäristön ja resurssien, kuten muistin, asettamista rakentamista varten Roihussa ja Mahdissa.
Linux-jakelun valitseminen perusimageksi
Kun valitset kontillesi perusimagen, 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 imageina redhat/ubi8 ja redhat/ubi9, sekä yhteisö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ä perusimageja laajoilla pakettivarastoilla.
Vaikka Apptainer mahdollistaa konttien rakentamisen käyttäen mitä tahansa Linux-jakelua perusimagena, 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 tavallisesti 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ä perusimagea 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 perusimagea, 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:
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:
Tämä lähestymistapa mahdollistaa pakettiasennusten onnistumisen samalla, kun käyttöoikeuksiin liittyvät virheet ohitetaan.
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 haluat rakentaa laskentasolmulla, voit varata Slurm-työn paikallisella levyllä.
Voimme esimerkiksi varata interaktiivisen työn paikallisella levyllä (--tmp) seuraavasti:
Väliaikaishakemisto
Ympäristömuuttujan TMPDIR on osoitettava paikalliselle levylle.
Apptainer käyttää sitä tunnistaakseen hakemiston väliaikaishakemistokseen konttia rakennettaessa.
Mahti-klusteri asettaa ympäristömuuttujan TMPDIR automaattisesti kirjautumissolmuilla, joilla paikallinen levy on oletuksena käytettävissä, sekä laskentasolmuilla silloin, kun paikallinen levy on varattu.
Lustre-rinnakkaistiedostojärjestelmää ei voi (eikä pidä) käyttää väliaikaishakemistona.
Välimuistihakemisto
Apptainer tallentaa välimuistiin kerroksia ja blob-objekteja, kuten perusimageja, välimuistihakemistoon.
Oletussijainti on kotihakemistossa ($HOME/.apptainer), jossa Mahdissa on rajallinen kiintiö.
Siksi välimuistin sijainti kannattaa ehkä vaihtaa scratch-alueelle, jotta kotihakemisto ei täyty (muokkaa project_id omaksi projektitunnukseksesi).
Voimme myös tarvittaessa tyhjentää välimuistihakemiston:
Virtuaalimuistin raja
Virtuaalimuistin raja 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:
Jos rakennusprosessisi loppuu kesken virtuaalimuistin puutteen vuoksi kirjautumissolmulla, sinun kannattaa käyttää interaktiivista työtä, jossa virtuaalimuisti on rajattu työlle varatun muistin määrään.
Väliaikaishakemiston bind mounttaaminen
Oletuksena Apptainer bind mounttaa isäntäjärjestelmän /tmp-hakemiston rakennusympäristön /tmp-hakemistoksi.
Roihussa 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-imagen rakentaminen olemassa olevasta Docker- tai OCI-imagesta
Voimme hakea olemassa olevia kontti-imageja konttirekisteristä pullaamalla ne. Apptainer muuntaa ne Docker- tai OCI-muodosta Singularity Image Format (SIF) -muotoon.
SIF-imagen rakentaminen määrittelytiedostosta
Apptainerin määrittelytiedostot käyttävät tiedostopäätettä .def.
Tässä on yksinkertainen esimerkki kontin määrittelystä:
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:
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 Lustre-rinnakkaistiedostojärjestelmään.
Voimme alustaa sandboxin perusimagesta 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:
Nyt voimme asentaa ohjelmistoja normaalisti:
Roihun perusimaget
CSC tarjoaa erilliset perusimaget sekä Roihun CPU:lle että Roihun GPU:lle. Nämä perusimaget on rakennettu Rocky Linux 9 -imagejen päälle. Jokainen image sisältää yhden Spackilla rakennetun ohjelmistopinon sekä sen riippuvuudet ja modulefile-tiedostot ympäristön aktivointia varten. Ohjelmistoversiot vastaavat järjestelmäohjelmistojen versioita.
Perusimaget mahdollistavat sellaisten konttien rakentamisen, joissa on alustan kanssa identtinen ohjelmistopino, kuten optimoidut MPI-kontit. Tuloksena syntyvät kontti-imaget ovat omavaraisia eivätkä vaadi binäärien bind mounttaamista ajon aikana. Nämä kontit eivät kuitenkaan ole siirrettäviä muihin koneisiin. Kontti-imaget ovat saatavilla OCI-muodossa Satamassa.
Katso esimerkkejä Esimerkit -osiosta.
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:
Data on saatavilla kontin sisällä polussa /data.
Kontti-wrapperit
Tykky -konttiwrapper on saatavilla kontitettujen Pip- ja Conda-asennusten luomiseen wrapper-skriptien 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.