Docker: Grundlagen 2

Container aufräumen

Wenn Container fertig sind (Status exited) sollten sie aufgeräumt werden, wenn sie nicht gleich wieder verwendet werden. Das geschieht mit
docker rm <ID>
Versucht man das bei einem laufenden container, bekommt man eine Fehlermeldung.

Übergibt man beim Erzeugen die Option –rm, wird der container automatisch aufgeräumt, wenn er in den exited-Status wechselt.

Software mit Docker installieren

Es gibt 3 Arten, wie man mit Docker Software installieren kann

  • aus dem Docker Hub oder anderen Registrierungen
  • aus Image-Dateien mittels docker save und docker load
  • Images mit Dockerfiles erzeugen

Wenn ein Image erstellt wird, bekommt es eine eindeutige Identifizierung, bestehend aus Zahlen und Buchstaben. Jede Änderung am Image erzeugt einen neuen Identifizierer. Tatsächlich arbeiten tut man mit den Identifizieren eigentlich nicht, sondern nur mit den Repositories.

Repositories

Ein Repository ist eine Menge bestehend aus Images. Der Name ist ähnlich wie eine URL aufgebaut. Er besteht aus dem Host, dem Benutzernamen und einer Kurzbezeichnung, die der Ersteller gewählt hat. Mit : kann man zusätzlich noch ein tag anhängen, um eine bestimmte Version zu laden.

Indices

docker pull und docker run benutzen ohne Angabe eines anderen Repositories stets Docker Hub und dessen Index.

Dockerfile

Ein Dockerfile ist ein Skript, das alle Anweisungen enthält, um ein Image zu erzeugen. Docker Hub erzeugt aus dem Dockerfile und den zugehörigen Daten mittels eines continuous build system automatisch Images. Images, die auf diese Art im Docker Hub erzeugt sind, bekommen die Kennzeichnung vertrauenswürdig, weil der Weg von den Einzelteilen zum Image bekannt ist.

Docker-Account, wofür?

An die Images auf Docker Hub kommt man auch ohne Login ran, also warum sollte man sich einen Account anlegen?

Für die meisten wird ein Account vielleicht gar nicht nötig sein. Wenn man nur die aktuellen Images laden und ausführen will, ist ein Account tatsächlich nicht notwendig.

Ein Account bietet aber ein paar Vorteile. Bei einigen Repositories kann es sogar erforderlich sein, sich anzumelden und damit zu authentifizieren.

Mit einem Account bekommt man Zugriff auf private Repositories. Man erhält die Möglichkeit, Images selbst hochzuladen und seine eigenen Images zu taggen.

docker login und docker logout sind die Kommandos, die man dazu braucht. Mit docker search <begriff> kann man den Index nach dem Begriff durchsuchen lassen. Das Kommando hat einen eingebauten Timeout, es installiert nichts, sondern zeigt nur die gefundenen Treffer an.

Installation von einem Dockerfile aus

Wenn man ein Dockerfile bekommen hat, kann man mit
docker build –t <repositorie_to_build_into> <dockerfile>
das Image daraus erzeugen.

Problem dabei ist, dass sich die Quellen auf die sich das Dockerfile bezieht inzwischen verschoben haben könnten.

Das Erzeugen des Images dauert unter Umständen eine Weile.

Layers

Ein Layer ist ein Image, das mit mindestens einem anderen Image verbunden ist. Das Parent Layer ist eine direkte Abhängigkeit vom aktuellen Image.

Wenn man z.B. ein Image benutzt, welches eine SQL-Datenbank braucht, ist das Image mit der SQL-DB ein Parent Layer. Images, die die Datenbank braucht, sind dann keine direkten Abhängigkeiten mehr.

Wenn man ein Image ausführt, werden alle Layer zu einem gemeinsamen Dateisystem zusammengemerged. Man könnte sich die Parent Layer wie DLLs vorstellen, die zur Laufzeit direkt eingebunden werden.

Um aus einem allgemeinen Layer ein speziallisiertes zu machen, reicht es, wenn man die speziellen Dinge in einem neuen Layer einfügt.

Schwächen eines gemeinsamen (Union) Dateisystems

Docker sucht sich das beste Dateisystem aus für das System auf dem es ausgeführt wird. Aber Dateisysteme unterscheiden sich natürlich in ihren Dateiattributen, -größen und Regeln für Namen.

Union Dateisysteme müssen ständig zwischen den Regeln der Dateisysteme übersetzen. Im besten Fall funktioniert das gut, im schlechtesten gehen Features verloren.

Volumes

Eine Schwierigkeit mit Containern ist, dass sie Daten nicht dauerhaft speichern können, weil die Images, aus denen sie erstellt werden, schreibgeschützt sind. Wie soll man also Daten, Logs usw. in die äußere Welt bringen?

Die Antwort auf diese Frage sind Volumes.

Der Verzeichnisbaum eines Containers wird aus einem Satz von mount points erzeugt, die beschreiben, wie das Dateisystem zusammen zu setzen ist.

Ein Volume ist ein mount point des Containers, wo ein Teil des Hostverzeichnisbaums eingebunden ist.

Als Beispiel soll folgender Container dienen, in dem ein Programm zwei Dateien schreibt.

Abb 1: Beispiel für Volume

Die erste Datei wird nur in die Layer des containers geschrieben und würde beim Beenden der Layer verloren gehen. Die zweite Datei wird an ein Volume geschrieben welches mit dem Host verbunden ist. Die Datei kann nach einem Neustart des Containers wieder benutzt werden.

Man könnte den Zusammenhang zwischen Images und Volumen so beschreiben, dass Images die statischen, unveränderlichen Dateien, wie Programme, enthält. Während Volumen für die sich ändernden Daten benutzt werden.

Volumenarten

Es gibt zwei Arten von Volumen, die in einem Container gemountet werden können.

  1. Bind mount: Damit kann jedes benutzerdefinierte Verzeichnis oder jede Datei gemountet werden.
  2. Docker managed space: Der Speicherplatz wird vom Docker daemon verwaltet

Bind mount

Bind mounting wird benutzt, wenn man die Dateien bereits auf dem Host hat oder äußere Programme diese Dateien ebenfalls benutzen sollen/müssen.

Wenn man ein Volumen in einen container einbindet, werden die in dem (Container-)Verzeichnis befindlichen Daten ausgeblendet und nur die Dateien des Volumen sind sichtbar.

Um ein Volumen einzubinden benutzt man die Option -v
docker run … -v dir_on_host:mount_in_container

Wenn man sicherstellen will, dass der Container keine Dateien ändern kann, kann man das Volumen als schreibgeschützt mounten:
docker run … -v dir_on_host:mount_in_container:ro

Verwendet man ein host-Verzeichnis, das es nicht gibt, legt Docker es für einen an.

Man kann nicht nur Verzeichnisse sondern auch  einzelne Dateien binden. Das ist besonders dann sinnvoll, wenn man in ein Verzeichnis, welches bereits Dateien enthält, eine zusätzliche Datei hinzufügen will. Die Datei muss vorhanden sein, sonst nimmt Docker an, es handelt sich um ein Verzeichnis und legt es an.

Beispiel: Ein Container enthält einen Web-Shop für einen Kunden. Man kann ihn nun für verschiedene Kunden anpassen, indem man die Bilddatei mit dem Logo (und einige andere Kleinigkeiten) mittels verschiedener eingebundener Volumen austauschen.

  • Das Binden mit Volumen erzwingt für die sonst portablen Container ein bestimmtes Dateisystem eines bestimmten hosts
  • Mögliche Konflikte, wenn aus dem Image mehrere Container erzeugt werden und immer dasselbe Volumen benutzt wird

Docker managed space

Verwaltete Volumen unterscheiden sich von Bind mount indem  die Volumen vom Docker daemon in einem von ihm geschützten Bereich angelegt wird.

Damit werden die Volumen von bestimmten Pfaden des Dateisystems entkoppelt. Diese Volumen werden erzeugt, indem nur der mount point bei der Option -v (–volume) angegeben wird
docker … -v mount_point

Volumen teilen

Wenn man Volumen zwischen mehreren Containern teilen muss, weil alle auf die selben Dateien zugreifen sollen, hat man natürlich erstmal ein Problem, wenn der Docker daemon die Daten „irgendwo“ ablegt. Um diesem Problem Herr zu werden, gibt es zwei Wege.

Wenn man Bind mount benutzt, ist der offensichtlichste Weg, dass man bei den Aufrufen das gleiche Verzeichnis übergibt. Dies wird host-dependant sharing

Um die Volumen nicht für jeden Container neu angeben zu müssen, kann man Docker sagen, dass es die Volumen eines oder mehrerer anderer Container übernehmen soll. Dies teilt man mit –volumes-from mit.

Verwaltete Volumen haben einen Lebenszyklus, der unabhängig von irgendwelchen Containern ist, aber man kann sie nur über die Container referenzieren.

Besitztum der Volumen

Verwaltete Volumen sind so genannte zweite Klasse Einheiten. Es gibt keinen Weg, sie zu teilen oder zu löschen, weil man keine Möglichkeit hat, sie einzeln zu identifizieren.

Jeder Container, der ein Volumen mountet, kann als dessen Besitzer angesehen werden.

Volumen löschen

Aufräumen von verwalteten Volumen ist eine manuelle Aufgabe. Docker kann keine bind mount Volumen löschen, weil diese nicht von Docker verwaltet werden. Docker kann verwaltete Volumen löschen, wenn die Container gelöscht werden.
docker rm -v …
versucht alle gebundenen verwalteten Volumen zu löschen. Noch von anderen Containern benutzte Volumen können nicht gelöscht werden. Löscht man einen Container und gibt die Option -v nicht an, entstehen Waisen. Waisen zu löschen erfordert viel händische Arbeit.

Netzwerk

Will man Container zu Verfügung stellen, die z.B. Webserver oder Email-Server betreiben, müssen sie auch für das Netzwerk freigegeben werden.

Als Protokoll bezeichnet man eine Vereinbarung auf eine gemeinsame Sprache.
Das Interface ist die Adresse eines Gesprächspartners.
Eine bridge ist ein Adapter zwischen zwei Netzwerken, um diese miteinander zu verbinden.

Docker setzt eine bridge ein, um sein virtuelles Netzwerk mit dem realen Netzwerk des hosts zu verbinden. Docker setzt zwei Arten von virtuellen Netzwerken ein, single-host und multi-host. Die single-host virtual networks dienen dazu, Container zu isolieren.

Alle Container sind mit einem virtuellen Netzwerk docker0

Vier Netzwerk Container Archetypen

Es gibt vier Archetypen und jeder Container folgt genau einem davon:

  • Closed containers / geschlossene Container
  • bridged containers / überbrückte Container
  • joined containers / vereinigte Container
  • open containers / offene Container

Leave a Reply