Lesezeit ca. 11 Min.
arrow_back

Sauber angedockt


Logo von Raspberry Pi Geek
Raspberry Pi Geek - epaper ⋅ Ausgabe 1/2023 vom 17.11.2022

Docker

Netz&System

Artikelbild für den Artikel "Sauber angedockt" aus der Ausgabe 1/2023 von Raspberry Pi Geek. Dieses epaper sofort kaufen oder online lesen mit der Zeitschriften-Flatrate United Kiosk NEWS.

Bildquelle: Raspberry Pi Geek, Ausgabe 1/2023

README

Linux-Softwarepakete kann man immer nur auf exakt der Distributionsversion installieren, für die sie paketiert wurden. Benötigen Sie eine ältere Anwendung, für die es keine aktuellen Pakete gibt, lösen Sie dieses Problem dank Container-Virtualisierung mit Docker nahezu mühelos.

Mit einer virtuellen Maschine (VM) können Sie Software nutzen, die für eine andere Linux-Distribution oder sogar ein anderes Betriebssystem gedacht ist. Eine VM einzurichten, ist aber aufwendig: Wenn Sie Virtualbox, Vmware oder Gnome Boxes verwenden, konfigurieren und starten Sie in der Programmoberfläche einen virtuellen PC, auf dem Sie dann eine reguläre Betriebssysteminstallation durchspielen. Nach Abschluss dieser Prozedur läuft dann im Fenster zum Beispiel ein vollständiger grafischer Desktop, etwa KDE oder Gnome, und Sie fahren die VM wie einen richtigen PC hoch und herunter.

In vielen Fällen ist ...

Weiterlesen
epaper-Einzelheft 9,99€
NEWS Jetzt gratis testen
Bereits gekauft?Anmelden & Lesen
Leseprobe: Abdruck mit freundlicher Genehmigung von Raspberry Pi Geek. Alle Rechte vorbehalten.
Lesen Sie jetzt diesen Artikel und viele weitere spannende Reportagen, Interviews, Hintergrundberichte, Kommentare und mehr aus über 1050 Magazinen und Zeitungen. Mit der Zeitschriften-Flatrate NEWS von United Kiosk können Sie nicht nur in den aktuellen Ausgaben, sondern auch in Sonderheften und im umfassenden Archiv der Titel stöbern und nach Ihren Themen und Interessensgebieten suchen. Neben der großen Auswahl und dem einfachen Zugriff auf das aktuelle Wissen der Welt profitieren Sie unter anderem von diesen fünf Vorteilen:

  • Schwerpunkt auf deutschsprachige Magazine
  • Papier sparen & Umwelt schonen
  • Nur bei uns: Leselisten (wie Playlists)
  • Zertifizierte Sicherheit
  • Freundlicher Service
Erfahren Sie hier mehr über United Kiosk NEWS.

Mehr aus dieser Ausgabe

Titelbild der Ausgabe 1/2023 von Mangelware. Zeitschriften als Abo oder epaper bei United Kiosk online kaufen.
Mangelware
Titelbild der Ausgabe 1/2023 von Fundament. Zeitschriften als Abo oder epaper bei United Kiosk online kaufen.
Fundament
Titelbild der Ausgabe 1/2023 von Stromzähler. Zeitschriften als Abo oder epaper bei United Kiosk online kaufen.
Stromzähler
Titelbild der Ausgabe 1/2023 von Schickes Präsent. Zeitschriften als Abo oder epaper bei United Kiosk online kaufen.
Schickes Präsent
Mehr Lesetipps
Blättern im Magazin
Private Lauscher
Vorheriger Artikel
Private Lauscher
Schnell serviert
Nächster Artikel
Schnell serviert
Mehr Lesetipps

... eine solche Vollinstallation genau die richtige Lösung für ein Problem, aber manchmal will man einfach nur schnell ein Programm testen. In so einen Fall steht der Aufwand für die VM-Installation eines kompletten Systems in keinem Verhältnis zum gewünschten Effekt. Warum Sie Programme nicht immer direkt auf Ihrem Linux-System laufen lassen können, verrät der Kasten Abhängigkeit von Bibliotheken.

Falls Sie eigene Software entwickeln, möchten Sie vielleicht testen, ob die erzeugten Programmdateien auf allen Distributionsversionen laufen, die Sie unterstützen: Lässt sich das generierte RPModer Debian-Paket einspielen? Sind alle Abhängigkeiten zu Bibliotheken erfüllt, sodass das Programm auch startet? Und arbeitet es schließlich wie erwartet? Auch für solche Softwaretests ist der Einsatz einer VM eher umständlich.

Eine Alternative zu virtuellen Maschinen oder echter Hardware bieten Container: Sie virtualisieren zwar keinen vollständigen Computer und eignen sich daher nicht für alle Einsatzzwecke, aber in vielen Fällen genügen sie durchaus. Dann spielen sie den Vorteil aus, dass sie ressourcenschonender sind (also weniger RAM und Plattenplatz benötigen) und sich sehr viel schneller einrichten lassen als eine VM. Einen neuen Container stellen Sie in Sekundenschnelle bereit, während eine frische Installation in einer VM eine Viertelstunde Zeit kostet. Selbst beim Klonen einer bereits vorhandenen virtuellen Maschine fallen einige Minuten Wartezeit an, weil dabei mehrere GByte Daten kopiert werden.

Auf den folgenden Seiten lernen Sie Docker kennen. Es gibt aber noch andere Werkzeuge, die unter Linux Container bereitstellen. Beliebt ist auch der Konkurrent Linux Containers (LXC ), den zum Beispiel das VM- und Container- Management-Tool Proxmox nutzt.

Docker installieren

Das Einrichten von Docker haben Sie schnell erledigt: Unter Ubuntu spielen Sie das Paket ein (Listing 2, Zeile 2) und tragen sich mit usermod als Mitglied in die neue Gruppe docker ein (Zeile ). Auf einem OpenSuse-System verwenden Sie Zypper für die Paketinstallation (Zeile 5). Dort heißt das Paket einfach docker, und der Docker-Service ist nach der Einrichtung noch inaktiv, was Sie mit zwei Systemctl-Aufrufen ändern (Zeile 6 und 7). Melden Sie sich danach ab und wieder an, damit die neue Gruppenmitgliedschaft greift.

Abhängigkeit von Bibliotheken

Dass sich nicht beliebige Linux-Anwendungen auf jedem System starten lassen, liegt daran, dass die Programmdateien meist nur Teile des Binärcodes enthalten, den der Rechner ausführt. Ein Großteil der Funktionalität findet sich in Bibliotheksdateien, die Linux beim Programmstart zusätzlich lädt. Will zum Beispiel ein interaktives Programm im Textmodus eine Zeile Text einlesen, nutzt es dafür keine eigene Routine, sondern greift auf die Funktion readline aus der gleichnamigen Bibliothek zurück. Abbildung1 1zeigt ein kleines Beispielprogramm, das eine Zeile Text einliest und mit einem Hinweis unverändert wieder ausgibt. Der Code für Ein- und Ausgabe stammt aus den Bibliotheksfunktionen readline für die Eingabe und printf für die Ausgabe. Beim Übersetzen mit GCC sorgt die Option ?lreadline dafür, dass der Compiler die Abhängigkeit von der Readline-Bibliothek in der erzeugten Programmdatei vermerkt. Das letzte Kommando in Abbildung1 1 zeigt alle Bibliotheken, die das Testprogramm benötigt, darunter . Die Endung .so.8 weist darauf hin, dass das Programm eine bestimmte Version der Bibliothek erwartet, die Version 8. Versuchen Sie, das Programm auf einem Rechner mit der älteren Readline-Version 6 oder 7 zu starten, findet der Programmlader die Bibliothek nicht und beschwert sich (Listing 1). Fehlende Bibliotheken kann man nachinstallieren, Linux gibt sich da durchaus flexibel und lässt es zu, verschiedene Versionen derselben Bibliothek gleichzeitig zu installieren. Ob Sie aber eine fehlende Version für eine bestimmte Linux-Distribution finden, ist eine andere Frage. In Linux und den dafür verfügbaren Anwendungen steckt so viel Dynamik, dass jede Distributionsaktualisierung etliche Bibliotheken auf einen neuen Stand bringt. Programme, die zu neue oder zu alte Bibliotheken benötigen, laufen dann nicht mehr. Noch schwerer fällt der Wechsel zu einer anderen Distribution, denn die Distributoren treffen oft voneinander abweichende Entscheidungen, bestimmte Softwarepakete auf einem älteren als dem verfügbaren Stand zu halten. Ein für OpenSuse übersetztes Programm braucht dann unter Ubuntu vielleicht Bibliotheken aus zwei verschiedenen Releases.

Im Test unter Ubuntu 22.04 genügte ein Neuanmelden übrigens nicht: Erst nach Abschießen aller eigenen Prozesse mit sudo killall ?9 ?u $USER und frischer Anmeldung klappte es. Sie können zwar auch den Rechner neu starten, aber der Weg über killall ist schneller.

Testen Sie zum Abschluss, ob die Einrichtung geklappt hat (Zeile 9). Das Programm sollte einige Zeilen Text ausgeben, darunter Hello from Docker!. Schlägt dieser Test fehl, dann prüfen Sie mithilfe von groups, ob Sie Mitglied der Gruppe docker sind. Sehen Sie außerdem mit systemctl status docker nach, ob der Docker-Daemon läuft.

Images und Container

Mit dem Docker-Kommando run hello?world aus der letzten Zeile von Listing 2 haben Sie ein Image von Docker Hub heruntergeladen, einen neuen Container aus dem Abbild erzeugt und ihn gestartet. Darin lief ein Hello-World- Programm, das alle Zeilen in der Ausgabe ab Hello from Docker ausgegeben hat.

Sind Sie neu in der Welt der Container, könnten die Begriffe Image (Abbilddatei) und Container Sie verwirren. Ein Image ist eine Sammlung von Dateien, ergänzt um diverse Metadaten. Es dient nur als Vorlage, um einen Container zu erstellen. Wenn Sie den Befehl docker run Image ausführen, erzeugt Docker aus dem angegebenen Image einen Container. Dazu entpackt das Tool das Image; die Dateien liegen dann in einem Unterordner von /var/lib/docker/overlay2/.

Anschließend startet Docker ein Programm aus diesem Ordner, dem es vorgaukelt, der Ordner sei das Wurzel-Filesystem. Auf Dateien, die weiter oben im Dateisystem liegen, kann das Programm nicht zugreifen, was Ihr normales Linux- System gegen Manipulationsversuche aus dem Container schützt. Neben dem Einsperren in einen Unterordner passiert noch viel mehr; unter anderem hat der Container eigene, vom Host-System unabhängige Netzwerkeinstellungen. Aus einer Abbilddatei können Sie mehrere Container erzeugen, in denen dann separate Prozesse laufen. Die Container verändern sich während der Laufzeit, weil Sie darin Dateien löschen, neu erzeugen oder bearbeiten können. Falls Sie eine Analogie für den Unterschied zwischen Images und Containern suchen: Zum Beispiel entspricht bei Virtualisierern wie Vmware und Virtualbox ein Image einer Virtual Appliance, der Container entspricht der individuellen VM.

Einweg-Container

Container nutzt man häufig nur ein einziges Mal. Dann führt eine einzige Anweisung den Container aus, und Docker löscht ihn im Anschluss sofort. Dafür bringt Docker die Option ??rm mit, die das Löschen automatisiert. Dieser verschwenderische Umgang mit Containern ist möglich (und sinnvoll), weil das Erstellen und Löschen von Containern fast keinen Aufwand verursacht. Lediglich beim ersten Start eines Containers müssen Sie das zugehörige Image beschaffen, in der Regel von Docker Hub . Bei allen späteren Starts liegt es bereits im lokalen Cache-Verzeichnis von Docker.

Da Container also oft kurzlebig sind, hat es sich eingebürgert, Konfigurationsdateien und alles andere, was Bestand haben soll, außerhalb des Containers abzulegen. Dazu können Sie entweder einen Teil des normalen Dateisystems im Container verfügbar machen oder spezielle Container-Volumes anlegen.

Ubuntu-Versionen

Mit den Kommandos aus Listing 3 legen Sie Container mit verschiedenen Ubun-tu-Versionen an. Jeder dieser Befehle erzeugt aus einem Ubuntu-Image einen Container und startet darin eine Bash- Shell. Die Optionen ?i (interaktiv) und ?t (Terminal) lassen den Container im interaktiven Modus mit virtuellem Terminal laufen, sodass Sie ihn aus dem aktuellen Terminalfenster heraus steuern können. Ohne diese Optionen würde der Container im Hintergrund starten.

Am Root-Prompt sehen Sie, dass Sie im Container mit Administratorrechten arbeiten (Listing 4, Zeile 2 bis 5). In der Shell können Sie nun wie gewohnt Befehle eingeben (Zeile 2, Zeile 6). Wenn Sie dabei externe Programme verwenden, starten Sie Versionen aus dem Container. Um herauszufinden, welche Distributionsversion im Container läuft, können Sie nach den Dateien /etc/os?release, /etc/debian_version oder /etc/ redhat?release suchen (Zeile 6).

Wissen Sie schon beim Start des Containers, dass Sie keine Shell benötigen, sondern einfach einen bestimmten Befehl ausführen möchten, hängen Sie diesen im Aufruf hinter dem Namen des Images an (Listing 5).Die Optionen ?i und ?t lassen Sie weg, wenn keine interaktive Nutzung nötig ist. Abbildung 2 2zeigt, wie Sie Container mit verschiedenen Ubuntu-Versionen starten. Dazu hängen Sie an den Image-Namen einfach einen Doppelpunkt und die gewünschte Version an (etwa ubuntu:16.04).

Welche Versionen verfügbar sind, finden Sie mit dem Docker-Tool nicht heraus. Die Informationen erhalten Sie über die Docker-Hub-Seite . Nutzen Sie dort die Suchfunktion, wählen Sie das passende Image aus den Treffern, und wechseln Sie dann zum Reiter Tags. Dort finden Sie auf einer länglichen Seite Hinweise zu allen verfügbaren Tags. Das können Versionsnummern sein, aber auch Codenamen oder Bezeichnungen wie latest. Wenn Sie die Sortierung auf A-Zumstellen, sehen Sie die ältesten Versionsnummern zuerst 3 3 . Kennen Sie den Namen des Images, können Sie auch direkt von Hand eine URL der Form ? _/Image/Tags zusammenbauen.

Eine Alternative dazu bietet die Bash- Funktion aus Listing 6. Wenn Sie diesen Codeschnipsel in die Datei ~/.bashrc auf nehmen und die Tools Skopeo und Jq nach (bei Ubuntu in den gleichnamigen Paketen) installieren, können Sie in allen neuen Shells den Befehl dfind verwenden, um auf Docker Hub nach Versionen zu suchen (Listing 7).

Dateizugriff

Programme im Container laufen zu lassen, ist in der Regel nur sinnvoll, wenn ein Zugriff auf Dateien des Host-Rechners gelingt. Eine Freigabe können Sie mit Docker viel leichter einrichten als in einer virtuellen Maschine; Sie geben einfach beim Docker-Aufruf eine zusätzliche Option der Form ?v OrdnerHost:OrdnerContainer an. Um beispielsweise Ihr Home-Verzeichnis auf dem Host für einen Ubuntu- Container unter /var/homedir/ verfügbar zu machen, starten Sie Docker wie in der ersten Zeile von Listing 8. Sie finden dann den ganzen Verzeichnisbaum samt Ihres Home- Verzeichnisses und allen Unterordnern in /var/homedir/.

Es ist möglich, mehrere solche Zuordnungen einzurichten, und Sie können sogar einzelne Dateien mit ?v in den Container einbauen. Wenn Sie mit dieser Methode die für die Benutzerverwaltung wichtigen Dateien /etc/passwd, /etc/ shadow und /etc/group in den Container mappen, können Sie darin mit su in Ihren eigenen Account wechseln und wie gewohnt in Ihrem Home-Verzeichnis arbeiten (Zeile 3ff).

Zielverzeichnisse im Container müssen übrigens nicht vorhanden sein, Docker erzeugt sie im laufenden Betrieb. Abbildung4 4zeigt, wie Sie aus dem Host-System und aus dem Container heraus dasselbe Home-Verzeichnis sehen. Aber Vorsicht: Änderungen, die Sie im Container an den Dateien vornehmen, greifen dann auch im Host-System. Aus Sicherheitsgründen empfiehlt es sich, stattdessen die Dateien in den Container zu kopieren.

Dateitransfer

Für den Transfer in den Container und aus dem Container heraus bietet Docker ein eigenes Kommando: Mit docker cp ko-pieren Sie ähnlich wie mit dem SSH-Tool Scp Dateien. Sie können damit keine Dateien in ein Image kopieren, sondern müssen zunächst einen Container starten.

Läuft der Container, finden Sie im Prompt seinen Rechnernamen. Es handelt sich um eine ID, die aus Hexadezimalzahlen besteht. Sie können auch mit docker ps nach dem Container suchen. In der aus sehr langen Zeilen bestehenden Übersicht gibt es neben der numerischen ID auch noch eine aussprechbare Bezeichnung, die Docker zufällig vergibt, sofern Sie beim Starten keinen Namen für den neuen Container vorgeben.

Beide IDs, die numerische und den Namen, können Sie für das Copy-Kommando nutzen, etwa um die Datei /etc/ passwd in den Container zu kopieren. Das Kommando aus der letzten Zeile von Listing 8 kopiert die Datei /etc/passwd vom Host-System in den Container mit der ID 22340547e6a3 und dort mit unverändertem Namen in denselben Ordner.

X Window System

Grafische Anwendungen bereiten Docker zunächst Probleme, die sich aber leicht lösen lassen. Der Trick für klassische X-Anwendungen (nicht Wayland) ist, das Verzeichnis /tmp/.X11?unix/ und die Umgebungsvariable $DISPLAY an den Container durchzureichen. So könnten Sie eine ältere Version des Gnome- Editors Gedit zum Laufen bringen, indem Sie ein eigenes Image namens oldgedit erstellen. Wie das geht, verrät der Kasten Image bauen per Dockerfile.

Das Image oldgedit ist so konfiguriert, dass es nicht die Shell /bin/bash startet, sondern direkt den Editor Gedit. Das erledigt es mit normalen Benutzerrechten, also nicht als root, sondern als User mit der User-ID 1000. Beim Versuch, nun einfach einen Container mit docker run ?it ??rm oldgedit zu starten, erscheinen Fehlermeldungen, die mit cannot open display enden: Das Programm kann keinen X-Server erreichen und damit kein Fenster öffnen.

Der auf dem Host laufende X-Server hat unterhalb von /tmp/.X11?unix/ eine Spezialdatei vom Typ Socket namens X0 erzeugt, über die Anwendungen Kontakt mit ihm aufnehmen können. Neben X0 können hier noch weitere Einträge liegen (X1, X2 und so weiter), falls mehrere X-Server aktiv sind. Welcher X-Server Programmfenster anzeigen soll, das legt die Umgebungsvariable $DISPLAY fest. Typischerweise enthält sie den Wert :0.

Image bauen per Dockerfile

Mit Docker können Sie nicht nur vorgefertigte Images von Docker Hub nutzen, sondern auch Images anpassen. Das klappt unter anderem, indem Sie einen Container starten, im laufenden System Änderungen vornehmen und aus dem geänderten Stand mit dem Kommando docker commit ein neues Image erzeugen. Eine Alternative funktioniert ohne Interaktion mit einem laufenden Container: Sie schreiben ein sogenanntes Dockerfile, das eine Bauanleitung für ein Image enthält. Es beginnt mit einer FROM-Zeile, die ein (schon vorhandenes) Basis-Image festlegt, das Sie anschließend mit den passenden Befehlen verändern. Ein auf Ubuntu 14.04 basierendes Image erzeugen Sie beispielsweise mit dem Dockerfile aus Listing 9, das Sie in einem ansonsten leeren Ordner unter dem Namen Dockerfile anlegen. Hinter FROM steht ein Image-Name, wie Sie ihn auch mit docker run verwenden. Im Beispiel lautet er ubuntu:14.04 für die älteste auf Docker Hub verfügbare Version von Ubuntu. Es folgen drei RUN-Zeilen mit Befehlen, die Docker in einem temporär erzeugten Ubuntu-14.04-Container ausführt. Die beiden Apt-Aufrufe spielen das Paket gedit ein, useradd erzeugt einen nicht privilegierten Benutzer mit dem Namen user und der User- ID 1000. Die USER-Zeile legt fest, dass alle weiteren Schritte unter der User-ID 1000 ausgeführt werden. Es folgt eine CMD-Zeile, die festlegt, welches Kommando später beim Container-Start laufen soll. Um nun mit diesem Image-Rezept einen Container namens oldgedit zu erzeugen, führen Sie im Ordner mit diesem Dockerfile den Befehl docker build ?t oldgedit . aus. Achten Sie bei der Eingabe darauf, dass der letzte Parameter des Kommandos ein einzelner Punkt ist – er steht für das aktuelle Verzeichnis. Docker führt dann vollautomatisch die Anweisungen aus dem Dockerfile aus. Klappt alles, steht anschließend das neue Image oldgedit bereit.

Den Inhalt der Variablen und den Zugriff auf die Sockets in /tmp/.X11?unix/ geben Sie nun über die Optionen ?e DISPLAY und ?v /tmp/.X11?unix:/tmp/?

.X11?unix an den Container weiter (Listing 10).Dann läuft Gedit, und dank des zusätzlichen Mappings des Home-Verzeichnisses auf /home/user/ im Container sollte der Editor auch Dateien öffnen und bearbeiten können 5 5.

Wayland

Ubuntu setzt in aktuellen Versionen Wayland als Nachfolger des X Window Systems ein, und Wayland bietet eine Kompatibilitätsschicht, mit der X-Anwendungen darauf laufen können. Andersherum laufen echte Wayland-Programme aber unter X nicht. Ein Beispiel ist das Terminalprogramm Foot, das Sie unter Ubuntu mit sudo apt install foot installieren. Starten Sie es in einer Wayland-Session, öffnet sich ein Terminalfenster. Versuchen Sie dasselbe in einer X-Session, erscheint eine längere Fehlermeldung, die mit failed to connect to wayland; no compositor running? goodbye endet.

Wayland nutzt andere Sockets und Dateien, um Zugriffe auf den Wayland-Server zu ermöglichen: Als Socket-File dient /run/user/1000/wayland?0 statt /tmp/? .X11?unix/X0, und anstelle von $DIS? PLAY enthält die Variable $XDG_RUNTIME_

DIR relevante Informationen wie etwa den Ordnernamen /run/user/1000/. Beides geben Sie mit ähnlichen Optionen an den Container weiter wie beim Einsatz von X, wie Listing 11 zeigt. Dabei ist waylandtest der Name eines weiteren Test-Images. Support für X und Wayland können Sie auch kombinieren, wenn ein Wayland-Server läuft: Dann reichen Sie beide Sockets und beide Umgebungsvariablen zum Container durch.

Fazit

Docker-Container bieten eine handliche Alternative zu VMs, die Zeit und Rechnerressourcen spart. Es gibt zahlreiche Anwendungsgebiete, und es lohnt sich, den Umgang mit Dockerfiles zu erlernen, mit denen Sie Ihre eigenen Images bauen. Dabei fangen Sie nicht immer bei null an, sondern nutzen ein Image von Docker Hub als Grundlage und konfigurieren es dann nach Ihren Vorstellungen. Spannend wird es, wenn Sie eine ganze Reihe von Containern gleichzeitig einsetzen: Dann tauchen fortgeschrittene Themen wie die Netzwerkkonfiguration der Container und die Orchestrierung mit Tools wie Kubernetes auf.

(jlu)

Dateien zum Artikel herunterladen unter

Weitere Infos und interessante Links