Nächste: Container mit Guix System, Nach oben: Container [Inhalt][Index]
Der einfachste Einstieg ist, guix shell
mit der
Befehlszeilenoption --container aufzurufen. Siehe Aufruf von
guix shell in Referenzhandbuch zu GNU Guix für eine Referenz der
möglichen Optionen.
Folgende Befehle legen einen minimalen Shell-Prozess an, bei dem die meisten Namensräume vom übrigen System getrennt sind. Das aktuelle Arbeitsverzeichnis bleibt für den Prozess sichtbar, aber das restliche Dateisystem ist unzugänglich. Diese äußerste Isolation kann sehr hilfreich sein, wenn Sie jeglichen Einfluss durch Umgebungsvariable, global installierte Bibliotheken oder Konfigurationsdateien ausschließen möchten.
guix shell --container
Diese Umgebung ist kahl und leer. Sie haben in der brachen Umgebung nicht einmal die GNU coreutils und müssen zu ihrer Erkundung mit den in die Shell eingebauten Werkzeugen vorliebnehmen. Selbst das Verzeichnis /gnu/store hat seine für gewöhnlich gigantischen Ausmaße verloren und ist nur mehr ein Schatten seiner selbst.
$ echo /gnu/store/* /gnu/store/…-gcc-10.3.0-lib /gnu/store/…-glibc-2.33 /gnu/store/…-bash-static-5.1.8 /gnu/store/…-ncurses-6.2.20210619 /gnu/store/…-bash-5.1.8 /gnu/store/…-profile /gnu/store/…-readline-8.1.1
In einer solchen Umgebung gibt es nichts für Sie zu tun außer die Umgebung
wieder zu verlassen. Das geht, indem Sie ^D drücken oder
exit
aufrufen, womit die eingeschränkte Shell-Umgebung ihr Ende
findet.
Sie können zusätzliche Verzeichnisse in der Container-Umgebung zugänglich machen. Verwenden Sie dazu --expose=VERZEICHNIS für eine Verzeichniseinbindung nur mit Lesezugriff innerhalb des Containers oder verwenden Sie --share=VERZEICHNIS für Schreibzugriff. Mit einem zusätzlichen Argument nach dem Verzeichnisnamen können Sie den Namen festlegen, der dem Verzeichnis innerhalb des Containers zugeordnet wird. Folgendes Beispiel zeigt, wie Sie das Verzeichnis /etc aus dem Wirtssystem auf /das/wirtssystem/etc innerhalb eines Containers abbilden, in dem die GNU coreutils installiert sind.
$ guix shell --container --share=/etc=/das/wirtssystem/etc coreutils $ ls /das/wirtssystem/etc
Gleichermaßen können Sie verhindern, dass das aktuelle Arbeitsverzeichnis eine Zuordnung in den Container bekommt, indem Sie die Befehlszeilenoption --no-cwd angeben. Es ist eine gute Idee, ein Verzeichnis anzulegen, das innerhalb des Containers das Persönliche Verzeichnis (auch „Home-Verzeichnis“) ist. Aus diesem heraus lassen Sie die Shell für den Container starten.
Auf einem fremden System ist es möglich, in einer Container-Umgebung
Software zu kompilieren, die mit den Bibliotheken des Systems oder mit
dessen Compiler-Toolchain inkompatibel ist. In der Forschung kommt es
häufiger vor, dass man in einer R-Sitzung Pakete installieren möchte. Ohne
Container ist es gut möglich, dass die Compiler-Toolchain des Fremdsystems
und dessen inkompatible Bibliotheken Vorrang haben und die Binärdateien
nicht zusammenpassen und in R nicht benutzt werden können. In
einer Container-Shell gibt es das Problem nicht, denn die
Bibliotheken und Programme des äußeren Systems sind schlicht gar nicht da,
weil der mount
-Namensraum getrennt ist.
Schauen wir uns ein umfassendes Manifest für eine komfortable R-Entwicklungsumgebung an:
(specifications->manifest
(list "r-minimal"
;; grundlegende Pakete
"bash-minimal"
"glibc-locales"
"nss-certs"
;; Befehlszeilenwerkzeuge, die man oft braucht, sonst
;; wäre der Container so gut wie leer.
"coreutils"
"grep"
"which"
"wget"
"sed"
;; R-Programme für Markdown
"pandoc"
;; Toolchain und häufige Bibliotheken für "install.packages"
"gcc-toolchain@10"
"gfortran-toolchain"
"gawk"
"tar"
"gzip"
"unzip"
"make"
"cmake"
"pkg-config"
"cairo"
"libxt"
"openssl"
"curl"
"zlib"))
Nehmen wir dieses Manifest und richten uns eine Container-Umgebung ein, in
der wir R ausführen. Der Einfachheit halber wollen wir den
net
-Namensraum teilen und bekommen Zugriff auf die
Netzwerkschnittstellen des Wirtssystems. Damit können wir R-Pakete auf
traditionelle Weise aus ihrem Quellcode erstellen, ohne uns um inkompatible
ABIs oder sonstige Inkompatibilitäten sorgen zu müssen.
$ guix shell --container --network --manifest=manifest.scm -- R R version 4.2.1 (2022-06-23) -- "Funny-Looking Kid" Copyright (C) 2022 The R Foundation for Statistical Computing … > e <- Sys.getenv("GUIX_ENVIRONMENT") > Sys.setenv(GIT_SSL_CAINFO=paste0(e, "/etc/ssl/certs/ca-certificates.crt")) > Sys.setenv(SSL_CERT_FILE=paste0(e, "/etc/ssl/certs/ca-certificates.crt")) > Sys.setenv(SSL_CERT_DIR=paste0(e, "/etc/ssl/certs")) > install.packages("Cairo", lib=paste0(getwd())) … * installing *source* package 'Cairo' ... … * DONE (Cairo) The downloaded source packages are in '/tmp/RtmpCuwdwM/downloaded_packages' > library("Cairo", lib=getwd()) > # success!
Containerisierte Shells einzusetzen ist lustig, aber wenn man mehr will als einen einzelnen interaktiven Prozess, werden sie ein bisschen umständlich. Manche Aufgaben sind einfach leichter zu lösen, wenn Sie sie auf einem ordentlichen Guix-System als festem Fundament aufbauen. Dann bekämen Sie Zugriff auf das reichhaltige Angebot von Systemdiensten. Im nächsten Abschnitt wird Ihnen gezeigt, wie Sie eine vollständige Instanz von Guix System in einem Container starten können.
Nächste: Container mit Guix System, Nach oben: Container [Inhalt][Index]