Images und die Registry

Mit dem Befehl sudo docker info prüfen Sie, ob die Software nach der Installation erfolgreich gestartet wurde und betriebsbereit ist (Abbildung 2). Die dargestellten Informationen geben Auskunft über einige nützliche Parameter, wie die Anzahl der laufenden Container, die Server- und Kernel-Version sowie die Adresse der verwendeten Registry. Letztere dient als eine zentrale Bezugsquelle für die Images, die als Bausteine für die Container zum Einsatz kommen.

Abbildung 2: Docker meldet sich nach der Installation betriebsbereit.

Im Normalfall genügt die Installation, weiterer Aufwand bei der Konfiguration erfordert der erste Test nicht. Einen Container starten Sie mit dem folgenden Aufruf auf der Kommandozeile:

$ sudo docker run -i -t resin/rpi-raspbian:jessie-20160831 /bin/bash

Die Option -i hält die Standardausgabe der neu erstellten Container offen. Das ermöglicht es Docker, mittels -t ein Pseudo-Terminal zu öffnen. So erhalten Sie über eine interaktive Shell Zugriff auf die normalerweise isolierte Umgebung.

Der Parameter resin/rpi-raspbian:jessie-20160831 weist die Software an, als Basis für den Container das Image rpi-raspbian zu verwenden. Bereitgestellt hat es ein Mitglied aus der Community, der sein gleichnamiges Repository resin im Docker-Hub, der offiziellen Registry, öffentlich zugänglich macht.

Oft stehen mehrere Versionen eines Images bereit, weshalb Docker die Angabe eines Datums erlaubt, in diesem Fall jessie-fixed-version. Für die ARM-Architektur des RasPi finden sich bislang nur wenige Images – betreiben Sie Docker dagegen auf gewöhnlicher x86-Hardware, steht Ihnen eine schier unendliche Auswahl an Images mit fertig gepackter Software offen.

TIPP

In der Registry des Docker-Projekts finden sich neben offiziellen Vorlagen zahlreiche, meist ungeprüfte Community-Beiträge. Beim Einsatz solcher Images sollten Sie mit Vorsicht vorgehen.

Nach dem Absetzen des Kommandos führt Docker die Bash innerhalb des Containers aus (Abbildung 3). Mittels exit verlassen Sie diese wieder. Da das auszuführende Kommando /bin/bash dadurch endet, stoppt der Container ebenfalls, was Sie mit sudo docker ps überprüfen.

Abbildung 3: Für einen ersten Test kommen ein vorbereitetes Image sowie eine einfache Shell als Parameter für den Container zum Einsatz. Das Image stammt aus der offiziellen Docker-Registry.

Beim Start des Containers beobachteten Sie womöglich den Download-Vorgang. Die Software erledigt gleich mehrere Schritte, um einen einsatzbereiten Container zu erstellen: Unter anderem prüft sie, ob sich das gewünschte Image bereits im lokalen Dateisystem befindet.

Haben Sie Docker frisch installiert, leitet der Daemon zunächst das Herunterladen der erforderlichen Software für den Container ein. Das Image speichert es in einem Unterverzeichnis von /var/lib/docker/ und bildet damit die Grundlage für den frisch erstellten Container. Die Images unterscheiden sich in Bezug auf den Aufbau von anderen Ansätzen (siehe Kasten "Image-Format").

Image-Format

Ein Docker-Image besteht aus mehreren Dateisystemen, die wie Ebenen übereinanderliegen. Die unterste Ebene stellt das Boot-Dateisystem (bootfs) dar, mit dem Sie in der Regel nie in Berührung kommen. Darüber legt Docker mit rootfs eine Umgebung für das Betriebssystem, das es beim Start des Containers nur mit Lesezugriff einhängt.

Dann macht die Software Gebrauch vom Linux-Feature Union Mount [16], mit dessen Hilfe es Dateisysteme übereinanderlegt und als eine Einheit präsentiert. Dieser Mechanismus ermöglicht es, dass im resultierenden Dateisystem Dateien und (Unter-)Verzeichnisse von allen darunter befindlichen Ebenen bereitstehen. Jedes der Dateisysteme heißt im Docker-Jargon etwas verwirrend Image, wobei die Ebene über bootfs den Namen Base-Image trägt. Typische Kandidaten dafür wären Ubuntu, Debian oder Fedora.

Erstellt Docker aus einem heruntergeladenen Image einen Container, legt es ein zusätzliches leeres Dateisystem mit Lese- und Schreibzugriff über alle anderen Ebenen. Alle Prozesse und Änderungen am Dateisystem aus Sicht von Anwendungen und Benutzern geschehen dort. Ändern Sie eine Datei aus einem darunterliegenden Dateisystem, kopiert das System diese zunächst in die oberste Ebene, ändert sie und speichert sie dann dort ab. Die bisherige Version der Datei, die schreibgeschützt bereitsteht, bleibt zwar erhalten, die Kopie überlagert diese aber (Abbildung 4).

Abbildung 4: Docker kombiniert mehrere Ebenen mit Dateisystemen zu einem Image. Die Schreibzugriffe geschehen dann auf einer neuen zusätzlichen Ebene, die Docker beim Start des Containers hinzufügt.

Mit sudo docker images sehen Sie bereits heruntergeladene Images ein, mit dem Pull-Kommando laden Sie bei Bedarf auch selbst Images herunter:

$ sudo docker pull resin/rpi-raspbian:jessie-20160831

Ohne die Angabe eines Datums verwendet das Tool den Standardwert latest, womit Sie stets die aktuellste Version beziehen. Bei vielen Base-Images repräsentiert ein Tag die OS-Version, wie etwa ubuntu:16.04 oder fedora:22. Diese Bezeichnungen finden Sie direkt in der Registry [4], alternativ gehen Sie mittels sudo docker search imagename auf die Suche oder erstellen selbst ein angepasstes Image für Ihre Zwecke.

Im Eigenbau

Gerade für den RasPi fällt die Auswahl an vorbereiteten Images eher mager aus. Daher ergibt der Bau von eigenen Containern durchaus Sinn. Docker bietet dafür zwei Wege an, wobei sich nur einer davon empfiehlt.

Die unübliche Methode sieht vor, dass Sie einen Container mit einem fertigen Image starten, die gewünschten Änderungen vornehmen und die Daten im Anschluss mit commit speichern. Wie das im Detail funktioniert, erklärt die offizielle Dokumentation [5].

Die aufwendigere, aber besser strukturierte Variante besteht im Anlegen einer Konfiguration in Form eines Dockerfiles, das den Zusammenbau beschreibt. Je nach Bedarf schieben Sie so beim Bau zusätzlich eigene Dateien oder Ordner in den Container. Diese Methode sorgt für bessere Reproduzierbarkeit und erlaubt den Bau von Containern aus einem Git-Repository heraus.

Container kommen häufig bei Webanwendungen zum Einsatz. In diesem Kontext ist eine abgeschottete Umgebung sinnvoll. Zudem sorgt dieser Ansatz für ein gehöriges Maß an Portabilität: Ein Entwickler packt seine Anwendung in einen Container, lädt das Image in eine Registry hoch und auf einem anderen Rechner wieder herunter. Dass Docker mittlerweile über Tricks selbst auf Windows-Maschinen und Macs läuft, macht diese Vorgehensweise zusätzlich attraktiv.

Die spezielle Architektur des RasPi bedingt, dass die selbst gebauten Container in der Regel nur auf anderen RasPi-Geräten laufen. Um ein erstes Image zu bauen, erstellen Sie auf dem Raspberry Pi einen Ordner im Home-Verzeichnis:

$ mkdir ~/simple_website

Wechseln Sie in das Verzeichnis und erstellen Sie dort die Datei index.html, die Sie anschließend mit beliebigem HTML-Code füllen. Erstellen Sie im gleichen Verzeichnis die Datei Dockerfile und übernehmen Sie den Inhalt aus Listing 2. Zeile 1 beschreibt, auf welchem Image der Container basiert. Beim Bau lädt Docker das entsprechende Image herunter und beginnt, alle weiteren Schritte darauf aufzubauen.

Das RUN in Zeile 2 markiert einen Aufruf, der intern via /bin/sh -c Kommandos zur Installation des Nginx-Pakets übergibt. Im Anschluss sorgt die COPY-Anweisung für die Platzierung der Datei index.html im Container, wobei Docker davon ausgeht, dass sich die Datei im selben Verzeichnis befindet wie das Dockerfile.

Listing 2

FROM resin/rpi-raspbian:jessie-20160831
RUN apt-get update; apt-get install -y nginx
COPY index.html /var/www/html/
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]
EXPOSE 80

Existiert das Zielverzeichnis nicht, legt Docker es automatisch an. Damit der Webserver Nginx im Container läuft, definiert ENTRYPOINT den passenden Befehl inklusive Parameter, der den Dienst im Vordergrund startet. Docker ruft dieses Kommando nach dem Start des Containers auf, wobei die Schreibweise mit eckigen Klammern dafür sorgt, dass das Ausführen ohne /bin/sh -c gelingt.

Die Zeile EXPOSE 80 bewirkt, dass der Container den Port 80 öffnet, über den Sie eine Verbindung zu Nginx herzustellen. Übrigens hält der im Vordergrund laufende Webserver den Container offen. Docker killt den Container erst, wenn Nginx stoppt.

Rufen Sie aus dem Verzeichnis ~/simple_website/ heraus nun das Kommando für den Bau des Containers auf (Listing 3, Zeile 1). Die Option build leitet die Aktion ein, der Schalter -t akzeptiert die Angabe eines symbolischen Namens (Tag). Üblicherweise besteht dieser aus einem Benutzernamen und einer kurzen Bezeichnung, zwischen denen ein Schrägstrich steht. Der Punkt am Ende gibt das Build-Verzeichnis an.

Listing 3

$ sudo docker build -t "rpi-geek/simple_website" .
$ sudo docker run -d --name simple_website -p 80:8080 "rpi-geek/simple_website"

Wenn Sie das Image zum ersten Mal bauen, führt Docker alle Schritte aus und speichert die Zwischenschritte ab. Leiten Sie den Vorgang erneut ein, läuft er unter Umständen um einiges schneller ab und erzeugt weniger Ausgaben (Abbildung 5).

Abbildung 5: Haben Sie das Image einmal komplett gebaut, speichert Docker die Zwischenschritte und sorgt so dafür, dass ein späterer Build unter Umständen weniger Zeit in Anspruch nimmt.

Mit sudo docker images verifizieren Sie, dass die Software das selbst erstellte Image kennt und in der Lage ist, es als Grundlage für einen Container zu verwenden. Mit dem Kommando aus der zweiten Zeile von Listing 3 bewirken Sie, dass Docker nun eine Umgebung auf Basis des eben gebauten Images bereitstellt.

Durch den Schalter -d läuft der Container im Hintergrund, --name sorgt für eine leicht zu identifizierende Benennung. Vergeben Sie keinen Namen, verwendet Docker beim Start einen Hash als Namen – im Alltag etwas unhandlich. Bei nachträglichen Aktionen am Container suchen Sie immer erst via sudo docker ps den Namen heraus und geben diesen dann in den Kommandos an.

Mit dem Schalter -p 80:8080 schleifen Sie den Container-Port 80 auf Port 8080 des lokalen Systems durch. Sie erreichen den Container im Browser entsprechend unter http://localhost:8080 (Abbildung 6). Beim Aufruf der Adresse erscheint die Ausgabe der zuvor ins Image kopierten Datei index.html.

Abbildung 6: Dank Port Forwarding schleifen Sie die Ausgabe des Webservers im Container auf den lokalen Rechner durch.

Das Kommando sudo docker ps listet alle laufenden Container inklusive der gemappten Ports auf, während sudo docker port simple_website nur die Ports zeigt. Die Tabelle "Docker-Kommandos" fasst die essenziellen Befehle zum Verwalten von Containern zusammen. Wenn Sie nicht als Administrator arbeiten, erfordern diese Kommandos ein vorangestelltes sudo. An die Stelle des Platzhalters Name setzen Sie den Namen des gewünschten Containers.

Docker-Kommandos

Kommando Wirkung
docker start Name Container starten
docker stop Name Container stoppen
docker top Name im Container laufende Prozesse anzeigen
docker stats Name Ressourcenverbrauch ermitteln
docker logs Name Logfiles des Containers öffnen
docker rm Name Container löschen
docker rm -f Name Container löschen, selbst wenn er gerade läuft
docker rmi Name Image-Datei löschen
docker history Name Verlauf des Containers anzeigen
docker exec -t -i Name /bin/bash Bash im Container starten

Wollen Sie tiefer in die Materie eintauchen, seien an dieser Stelle ein paar Stichpunkte für die Recherche genannt: Der Befehl docker networking erlaubt das Zusammenschalten von mehreren Containern innerhalb eines Netzwerks, was diesen ermöglicht, Daten auszutauschen. Da sich Docker auf Iptables und Bridge-Interfaces verlässt, setzt dieses Thema fortgeschrittene Kenntnisse im Umgang mit diesen Komponenten voraus.

Im Bereich Daten ermöglicht docker volumes das Einhängen von Ordnern des Hosts in die Container, womit diese selbst keine Daten vorzuhalten und zu speichern brauchen. Löschen Sie einen Container, so überdauern die Daten die Aktion und stehen für andere Umgebungen bereit.

Die Anweisung HEALTHCHECK im Dockerfile gibt dem Daemon Hinweise darauf, wie er einen Container auf seinen Zustand hin überprüft und gegebenenfalls durchstartet. Das Kommando sudo docker inspect Name zeigt dagegen alle Details der Konfiguration des Containers Name. Viele weitere nützliche Informationen finden Sie in der Dokumentation [6].

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 8 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

Kommentare

Infos zur Publikation

LU 12/2017: Perfekte Videos

Digitale Ausgabe: Preis € 5,95
(inkl. 19% MwSt.)

LinuxUser erscheint monatlich und kostet 5,95 Euro (mit DVD 8,50 Euro). Weitere Infos zum Heft finden Sie auf der Homepage.

Das Jahresabo kostet ab 86,70 Euro. Details dazu finden Sie im Computec-Shop. Im Probeabo erhalten Sie zudem drei Ausgaben zum reduzierten Preis.

Bei Google Play finden Sie digitale Ausgaben für Tablet & Smartphone.

HINWEIS ZU PAYPAL: Die Zahlung ist ohne eigenes Paypal-Konto ganz einfach per Kreditkarte oder Lastschrift möglich!

Stellenmarkt

Aktuelle Fragen

Broadcom Adapter 802.11n nachinstallieren
Thomas Mengel, 31.10.2017 20:06, 2 Antworten
Hallo, kann man nachträglich auf einer Liveversion, MX Linux auf einem USB-Stick, nachträglich...
RUN fsck Manually / Stromausfall
Arno Krug, 29.10.2017 12:51, 1 Antworten
Hallo, nach Absturz des Rechners aufgrund fehlendem Stroms startet Linux nicht mehr wie gewohn...
source.list öffnet sich nicht
sebastian reimann, 27.10.2017 09:32, 2 Antworten
hallo Zusammen Ich habe das problem Das ich meine source.list nicht öffnen kann weiß vlt jemman...
Lieber Linux oder Windows- Betriebssystem?
Sina Kaul, 13.10.2017 16:17, 6 Antworten
Hallo, bis jetzt hatte ich immer nur mit
IT-Kurse
Alice Trader, 26.09.2017 11:35, 2 Antworten
Hallo liebe Community, ich brauche Hilfe und bin sehr verzweifelt. Ih bin noch sehr neu in eure...