{"id":218,"date":"2018-10-30T10:13:21","date_gmt":"2018-10-30T09:13:21","guid":{"rendered":"http:\/\/dtp-soft.de\/?p=218"},"modified":"2018-10-30T10:13:21","modified_gmt":"2018-10-30T09:13:21","slug":"docker-grundlagen-2","status":"publish","type":"post","link":"http:\/\/dtp-soft.de\/?p=218","title":{"rendered":"Docker: Grundlagen 2"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Container aufr\u00e4umen<\/h2>\n\n\n\n<p>Wenn Container fertig sind (Status exited) sollten sie aufger\u00e4umt werden, wenn sie nicht gleich wieder verwendet werden. Das geschieht mit<br>docker rm &lt;ID><br>Versucht man das bei einem laufenden container, bekommt man eine Fehlermeldung.<\/p>\n\n\n\n<p>\u00dcbergibt man beim Erzeugen die Option &#8211;rm, wird der container automatisch aufger\u00e4umt, wenn er in den exited-Status wechselt.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Software mit Docker installieren<\/h2>\n\n\n\n<p>Es gibt 3 Arten, wie man mit Docker Software installieren kann<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>aus dem Docker Hub oder anderen Registrierungen<\/li><li>aus Image-Dateien mittels <em>docker save<\/em> und <em>docker load<\/em><\/li><li>Images mit Dockerfiles erzeugen<\/li><\/ul>\n\n\n\n<p>Wenn ein Image erstellt wird, bekommt es eine eindeutige Identifizierung, bestehend aus Zahlen und Buchstaben. Jede \u00c4nderung am Image erzeugt einen neuen Identifizierer. Tats\u00e4chlich arbeiten tut man mit den Identifizieren eigentlich nicht, sondern nur mit den Repositories.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Repositories<\/h3>\n\n\n\n<p>Ein Repository ist eine Menge bestehend aus Images. Der Name ist \u00e4hnlich wie eine URL aufgebaut. Er besteht aus dem Host, dem Benutzernamen und einer Kurzbezeichnung, die der Ersteller gew\u00e4hlt hat. Mit : kann man zus\u00e4tzlich noch ein tag anh\u00e4ngen, um eine bestimmte Version zu laden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Indices<\/h3>\n\n\n\n<p><em>docker pull<\/em> und <em>docker run<\/em> benutzen ohne Angabe eines anderen Repositories stets Docker Hub und dessen Index.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dockerfile<\/h3>\n\n\n\n<p>Ein Dockerfile ist ein Skript, das alle Anweisungen enth\u00e4lt, um ein Image zu erzeugen. Docker Hub erzeugt aus dem Dockerfile und den zugeh\u00f6rigen Daten mittels eines continuous build system automatisch Images. Images, die auf diese Art im Docker Hub erzeugt sind, bekommen die Kennzeichnung vertrauensw\u00fcrdig, weil der Weg von den Einzelteilen zum Image bekannt ist.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Docker-Account, wof\u00fcr?<\/h2>\n\n\n\n<p>An die Images auf Docker Hub kommt man auch ohne Login ran, also warum sollte man sich einen Account anlegen?<\/p>\n\n\n\n<p>F\u00fcr die meisten wird ein Account vielleicht gar nicht n\u00f6tig sein. Wenn man nur die aktuellen Images laden und ausf\u00fchren will, ist ein Account tats\u00e4chlich nicht notwendig.<\/p>\n\n\n\n<p>Ein Account bietet aber ein paar Vorteile. Bei einigen Repositories kann es sogar erforderlich sein, sich anzumelden und damit zu authentifizieren.<\/p>\n\n\n\n<p>Mit einem Account bekommt man Zugriff auf private Repositories. Man erh\u00e4lt die M\u00f6glichkeit, Images selbst hochzuladen und seine eigenen Images zu taggen.<\/p>\n\n\n\n<p><em>docker login<\/em> und <em>docker logout<\/em> sind die Kommandos, die man dazu braucht. Mit <em>docker search &lt;begriff><\/em> 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.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Installation von einem Dockerfile aus<\/h3>\n\n\n\n<p>Wenn man ein Dockerfile bekommen hat, kann man mit <br><em>docker build &#8211;t &lt;repositorie_to_build_into> &lt;dockerfile><\/em><br>das Image daraus erzeugen.<\/p>\n\n\n\n<p>Problem dabei ist, dass sich die Quellen auf die sich das Dockerfile bezieht inzwischen verschoben haben k\u00f6nnten.<\/p>\n\n\n\n<p>Das Erzeugen des Images dauert unter Umst\u00e4nden eine Weile.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Layers<br><\/h2>\n\n\n\n<p>Ein Layer ist ein Image, das mit mindestens einem anderen Image verbunden ist. Das Parent Layer ist eine direkte Abh\u00e4ngigkeit vom aktuellen Image.<\/p>\n\n\n\n<p>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\u00e4ngigkeiten mehr.<\/p>\n\n\n\n<p>Wenn man ein Image ausf\u00fchrt, werden alle Layer zu einem gemeinsamen Dateisystem zusammengemerged. Man k\u00f6nnte sich die Parent Layer wie DLLs vorstellen, die zur Laufzeit direkt eingebunden werden.<\/p>\n\n\n\n<p>Um aus einem allgemeinen Layer ein speziallisiertes zu machen, reicht es, wenn man die speziellen Dinge in einem neuen Layer einf\u00fcgt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Schw\u00e4chen eines gemeinsamen (Union) Dateisystems<\/h2>\n\n\n\n<p>Docker sucht sich das beste Dateisystem aus f\u00fcr das System auf dem es ausgef\u00fchrt wird. Aber Dateisysteme unterscheiden sich nat\u00fcrlich in ihren Dateiattributen, -gr\u00f6\u00dfen und Regeln f\u00fcr Namen.<\/p>\n\n\n\n<p>Union Dateisysteme m\u00fcssen st\u00e4ndig zwischen den Regeln der Dateisysteme \u00fcbersetzen. Im besten Fall funktioniert das gut, im schlechtesten gehen Features verloren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Volumes<\/h2>\n\n\n\n<p>Eine Schwierigkeit mit Containern ist, dass sie Daten nicht dauerhaft speichern k\u00f6nnen, weil die Images, aus denen sie erstellt werden, schreibgesch\u00fctzt sind. Wie soll man also Daten, Logs usw. in die \u00e4u\u00dfere Welt bringen?<\/p>\n\n\n\n<p>Die Antwort auf diese Frage sind Volumes.<\/p>\n\n\n\n<p>Der Verzeichnisbaum eines Containers wird aus einem Satz von mount points erzeugt, die beschreiben, wie das Dateisystem zusammen zu setzen ist.<\/p>\n\n\n\n<p>Ein <strong>Volume<\/strong> ist ein mount point des Containers, wo ein Teil des Hostverzeichnisbaums eingebunden ist.<\/p>\n\n\n\n<p>Als Beispiel soll folgender Container dienen, in dem ein Programm zwei Dateien schreibt.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"371\" height=\"173\" src=\"http:\/\/dtp-soft.de\/wp-content\/uploads\/2018\/10\/Volumes.png\" alt=\"\" class=\"wp-image-220\" srcset=\"http:\/\/dtp-soft.de\/wp-content\/uploads\/2018\/10\/Volumes.png 371w, http:\/\/dtp-soft.de\/wp-content\/uploads\/2018\/10\/Volumes-300x140.png 300w\" sizes=\"auto, (max-width: 371px) 100vw, 371px\" \/><figcaption>Abb 1: Beispiel f\u00fcr Volume<\/figcaption><\/figure>\n\n\n\n<p>Die erste Datei wird nur in die Layer des containers geschrieben und w\u00fcrde 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.<\/p>\n\n\n\n<p>Man k\u00f6nnte den Zusammenhang zwischen Images und Volumen so beschreiben, dass Images die statischen, unver\u00e4nderlichen Dateien, wie Programme, enth\u00e4lt. W\u00e4hrend Volumen f\u00fcr die sich \u00e4ndernden Daten benutzt werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Volumenarten<\/h3>\n\n\n\n<p>Es gibt zwei Arten von Volumen, die in einem Container gemountet werden k\u00f6nnen.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Bind mount: Damit kann jedes benutzerdefinierte Verzeichnis oder jede Datei gemountet werden.<\/li><li>Docker managed space: Der Speicherplatz wird vom Docker daemon verwaltet<\/li><\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Bind mount<\/h4>\n\n\n\n<p>Bind mounting wird benutzt, wenn man die Dateien bereits auf dem Host hat oder \u00e4u\u00dfere Programme diese Dateien ebenfalls benutzen sollen\/m\u00fcssen.<\/p>\n\n\n\n<p><em>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.<\/em><\/p>\n\n\n\n<p>Um ein Volumen einzubinden benutzt man die Option -v<br><em>docker run &#8230; -v dir_on_host:mount_in_container<\/em><\/p>\n\n\n\n<p>Wenn man sicherstellen will, dass der Container keine Dateien \u00e4ndern kann, kann man das Volumen als schreibgesch\u00fctzt mounten:<br><em>docker run &#8230; -v dir_on_host:mount_in_container<strong>:ro<\/strong><\/em><\/p>\n\n\n\n<p>Verwendet man ein host-Verzeichnis, das es nicht gibt, legt Docker es f\u00fcr einen an.<\/p>\n\n\n\n<p>Man kann nicht nur Verzeichnisse sondern auch\u00a0 einzelne Dateien binden. Das ist besonders dann sinnvoll, wenn man in ein Verzeichnis, welches bereits Dateien enth\u00e4lt, eine zus\u00e4tzliche Datei hinzuf\u00fcgen will. Die Datei muss vorhanden sein, sonst nimmt Docker an, es handelt sich um ein Verzeichnis und legt es an.<\/p>\n\n\n\n<p><strong>Beispiel<\/strong>: Ein Container enth\u00e4lt einen Web-Shop f\u00fcr einen Kunden. Man kann ihn nun f\u00fcr verschiedene Kunden anpassen, indem man die Bilddatei mit dem Logo (und einige andere Kleinigkeiten) mittels verschiedener eingebundener Volumen austauschen.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Das Binden mit Volumen erzwingt f\u00fcr die sonst portablen Container ein bestimmtes Dateisystem eines bestimmten hosts<\/li><li>M\u00f6gliche Konflikte, wenn aus dem Image mehrere Container erzeugt werden und immer dasselbe Volumen benutzt wird<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Docker managed space<\/h4>\n\n\n\n<p>Verwaltete Volumen unterscheiden sich von Bind mount indem\u00a0 die Volumen vom Docker daemon in einem von ihm gesch\u00fctzten Bereich angelegt wird.<\/p>\n\n\n\n<p>Damit werden die Volumen von bestimmten Pfaden des Dateisystems entkoppelt. Diese Volumen werden erzeugt, indem nur der mount point bei der Option -v (&#8211;volume) angegeben wird<br><em>docker &#8230; -v<\/em> <em>mount_point<\/em><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Volumen teilen<\/h3>\n\n\n\n<p>Wenn man Volumen zwischen mehreren Containern teilen muss, weil alle auf die selben Dateien zugreifen sollen, hat man nat\u00fcrlich erstmal ein Problem, wenn der Docker daemon die Daten &#8222;irgendwo&#8220; ablegt. Um diesem Problem Herr zu werden, gibt es zwei Wege.<\/p>\n\n\n\n<p>Wenn man Bind mount benutzt, ist der offensichtlichste Weg, dass man bei den Aufrufen das gleiche Verzeichnis \u00fcbergibt. Dies wird <strong>host-dependant sharing<\/strong> <\/p>\n\n\n\n<p>Um die Volumen nicht f\u00fcr jeden Container neu angeben zu m\u00fcssen, kann man Docker sagen, dass es die Volumen eines oder mehrerer anderer Container \u00fcbernehmen soll. Dies teilt man mit &#8211;volumes-from mit.<\/p>\n\n\n\n<p>Verwaltete Volumen haben einen Lebenszyklus, der unabh\u00e4ngig von irgendwelchen Containern ist, aber man kann sie nur \u00fcber die Container referenzieren.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Besitztum der Volumen<\/h4>\n\n\n\n<p>Verwaltete Volumen sind so genannte zweite Klasse Einheiten. Es gibt keinen Weg, sie zu teilen oder zu l\u00f6schen, weil man keine M\u00f6glichkeit hat, sie einzeln zu identifizieren.<\/p>\n\n\n\n<p>Jeder Container, der ein Volumen mountet, kann als dessen Besitzer angesehen werden.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Volumen l\u00f6schen<\/h4>\n\n\n\n<p>Aufr\u00e4umen von verwalteten Volumen ist eine manuelle Aufgabe. Docker kann keine bind mount Volumen l\u00f6schen, weil diese nicht von Docker verwaltet werden. Docker kann verwaltete Volumen l\u00f6schen, wenn die Container gel\u00f6scht werden.<br><em>docker rm -v &#8230;<\/em><br>versucht alle gebundenen verwalteten Volumen zu l\u00f6schen. Noch von anderen Containern benutzte Volumen k\u00f6nnen nicht gel\u00f6scht werden. L\u00f6scht man einen Container und gibt die Option -v nicht an, entstehen Waisen. Waisen zu l\u00f6schen erfordert viel h\u00e4ndische Arbeit.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Netzwerk<\/h2>\n\n\n\n<p>Will man Container zu Verf\u00fcgung stellen, die z.B. Webserver oder Email-Server betreiben, m\u00fcssen sie auch f\u00fcr das Netzwerk freigegeben werden.<\/p>\n\n\n\n<p>Als <strong>Protokoll<\/strong> bezeichnet man eine Vereinbarung auf eine gemeinsame Sprache.<br>Das <strong>Interface<\/strong> ist die Adresse eines Gespr\u00e4chspartners.<br>Eine <strong>bridge<\/strong> ist ein Adapter zwischen zwei Netzwerken, um diese miteinander zu verbinden.<br><\/p>\n\n\n\n<p>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.<\/p>\n\n\n\n<p>Alle Container sind mit einem virtuellen Netzwerk <em>docker0<\/em> <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Vier Netzwerk Container Archetypen<\/h3>\n\n\n\n<p>Es gibt vier Archetypen und jeder Container folgt genau einem davon:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Closed containers \/ geschlossene Container<\/li><li>bridged containers \/ \u00fcberbr\u00fcckte Container<\/li><li>joined containers \/ vereinigte Container<\/li><li>open containers \/ offene Container<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Container aufr\u00e4umen Wenn Container fertig sind (Status exited) sollten sie aufger\u00e4umt werden, wenn sie nicht gleich wieder verwendet werden. Das geschieht mitdocker rm &lt;ID>Versucht man das bei einem laufenden container, bekommt man eine Fehlermeldung. \u00dcbergibt man beim Erzeugen die Option &#8211;rm, wird der container automatisch aufger\u00e4umt, wenn er in den exited-Status wechselt.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[27],"tags":[],"class_list":["post-218","post","type-post","status-publish","format-standard","hentry","category-docker"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/dtp-soft.de\/index.php?rest_route=\/wp\/v2\/posts\/218","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/dtp-soft.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/dtp-soft.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/dtp-soft.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/dtp-soft.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=218"}],"version-history":[{"count":2,"href":"http:\/\/dtp-soft.de\/index.php?rest_route=\/wp\/v2\/posts\/218\/revisions"}],"predecessor-version":[{"id":221,"href":"http:\/\/dtp-soft.de\/index.php?rest_route=\/wp\/v2\/posts\/218\/revisions\/221"}],"wp:attachment":[{"href":"http:\/\/dtp-soft.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=218"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/dtp-soft.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=218"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/dtp-soft.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=218"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}