Docker Von Grund auf Bilder bauen

Docker-Container sind auf dem Vormarsch, eine bewährte Methode für die Bereitstellung und Verwaltung von Cloud-nativen verteilten Systemen. Container sind Instanzen von Docker-Images. Es stellt sich heraus, dass es viel zu wissen und zu Bildern gibt. 

In diesem zweiteiligen Tutorial werde ich ausführlich auf Docker-Bilder eingehen. Im ersten Teil habe ich die Grundprinzipien, Designüberlegungen und die Überprüfung von Bildeinbauten besprochen. In diesem Teil beschäftige ich mich mit dem Erstellen eigener Bilder, der Fehlerbehebung und dem Arbeiten mit Image-Repositorys. 

Wenn Sie auf der anderen Seite herauskommen, wissen Sie genau, was Docker-Images genau sind und wie Sie sie effektiv in Ihren eigenen Anwendungen und Systemen einsetzen können.

Bilder bauen

Es gibt zwei Möglichkeiten, Bilder zu erstellen. Sie können einen vorhandenen Container ändern und dann als neues Image festlegen, oder Sie können eine Docker-Datei schreiben und zu einem Image erstellen. Wir gehen beide durch und erklären die Vor- und Nachteile.

Manuelle Builds

Bei manuellen Builds behandeln Sie Ihren Container wie einen normalen Computer. Sie installieren Pakete, Sie schreiben Dateien, und wenn Sie alles gesagt und getan haben, legen Sie sie fest und erhalten ein neues Image, das Sie als Vorlage verwenden, um viele weitere identische Container zu erstellen oder sogar andere Images zu erstellen.

Beginnen wir mit dem alpinen Image, einem sehr kleinen und spartanischen Image, das auf Alpine Linux basiert. Wir können es im interaktiven Modus ausführen, um in eine Shell zu gelangen. Unser Ziel ist es, eine Datei namens "yeah" hinzuzufügen, die den Text "it works!" Enthält. in das Stammverzeichnis und dann ein neues Bild mit dem Namen "yeah-alpine" erstellen. 

Auf geht's. Schön, wir sind schon im Hauptverzeichnis. Mal sehen, was da ist.

> docker run -it alpine / bin / sh / # ls bin dev etc home lib linuxrc media mnt proz-wurzel sbin srv sys tmp usr var

Welcher Editor ist verfügbar? Kein Vim, kein Nano?

/ # vim / bin / sh: vim: nicht gefunden / # nano / bin / sh: nano: nicht gefunden

Naja. Wir möchten nur eine Datei erstellen:

/ # echo "es funktioniert!" > yeah / # cat yeah es funktioniert! 

Ich habe die interaktive Shell verlassen, und ich kann den Container namens "vibrant_spenc" mit sehen docker ps --all. Das --alles Flag ist wichtig, da der Container nicht mehr läuft.

> docker ps --all CONTAINER ID BILDBEFEHL ERSTELLTE STATUSNAMEN c8faeb05de5f alpine "/ bin / sh" vor 6 Minuten Beendet vibrant_spence

Hier erstelle ich ein neues Bild aus dem "vibrate_spence" -Container. Ich fügte die Commit-Nachricht "mein, mein, mein" hinzu, um dies zu erreichen.

> docker-Commit -m "Mine, Mine, Mine" vibrant_spence yeah-alpine sha256: e3c98cd21f4d85a1428 ... e220da99995fd8bf6b49aa

Lass es uns überprüfen. Ja, es gibt ein neues Bild und in seiner Geschichte können Sie eine neue Ebene mit dem Kommentar "Mine, Mine, Mine" sehen.

> docker images>             







































4/4 / 4std 4e38e38c8ce0 4.8 MB nsqio / nsq zuletzt 2a82c70fe5e3 70.7 MB> docker history yeah-alpine BILDGRÖSSE KOMMENTAR e3c98cd21f4d vor 40 Sekunden 66 B Mine, Mine, Mine 4e38e38c8ce0 7 Monate zuvor 4.8 MB

Nun zum richtigen Test. Löschen Sie den Container und erstellen Sie einen neuen Container aus dem Bild. Das erwartete Ergebnis ist, dass die "yeah" -Datei im neuen Container vorhanden ist.

> docker rm vibrant_spence vibrant_spence> docker run -it yeah-alpine / bin / sh / # cat Ja, es funktioniert! / #

Was kann ich sagen? Ja, es funktioniert!

Verwenden einer Dockerfile

Das Erstellen von Images aus modifizierten Containern ist cool, aber es gibt keine Verantwortlichkeit. Es ist schwer, die Änderungen zu verfolgen und zu wissen, welche Änderungen vorgenommen wurden. Die disziplinierte Methode zum Erstellen von Bildern besteht darin, sie mithilfe einer Docker-Datei zu erstellen.

Die Docker-Datei ist eine Textdatei, die einem Shellskript ähnelt, jedoch mehrere Befehle unterstützt. Jeder Befehl, der das Dateisystem ändert, erstellt eine neue Ebene. Im ersten Teil haben wir die Wichtigkeit der richtigen Unterteilung Ihres Bildes in Ebenen diskutiert. Die Dockerfile ist an und für sich ein großes Thema. 

Ich werde hier nur ein paar Befehle demonstrieren, um ein anderes Bild zu erstellen, "oh-yeah-alpine", basierend auf einer Dockerfile. Neben der Erstellung der berüchtigten "yeah" -Datei installieren wir auch vim. Die alpine Linux-Distribution verwendet ein Paketverwaltungssystem namens "apk". Hier ist die Dockerfile:

FROM alpine # Kopiere die "yeah" -Datei vom Host. COPY yeah / yeah # Aktualisiere und installiere vim mit apk RUN. Apk update && apk add vim CMD cat / yeah

Das Grundbild ist alpin. Es kopiert die "yeah" -Datei aus demselben Host-Verzeichnis, in dem sich die Docker-Datei befindet (der Build-Kontext-Pfad). Dann läuft es apk update und installiert vim. Schließlich wird der Befehl festgelegt, der ausgeführt wird, wenn der Container ausgeführt wird. In diesem Fall wird der Inhalt der Datei "yeah" auf dem Bildschirm ausgegeben.

OK. Nun, da wir wissen, worauf wir uns einlassen, bauen wir dieses Ding. Die Option "-t" legt das Repository fest. Ich habe kein Tag angegeben, daher wird es standardmäßig "neueste" sein..

> docker build -t oh-yeah-alpine. Build-Kontext an Docker-Dämon senden 3.072 kB Schritt 1/4: FROM alpine ---> 4e38e38c8ce0 Schritt 2/4: KOPIEREN yeah / yeah ---> 1b2a228cc2a5 Entfernen des Zwischencontainers a6221f725845 Schritt 3/4: RUN apk update && apk add vim ---> Ausführen in e2c0524bd792 http://dl-cdn.alpinelinux.org/… /APKINDEX.tar.gz http://dl-cdn.alpinelinux.org/x86_64/APKINDEX.tar.gz v3 abrufen. 4.6-60-gc61f5bf [http://dl-cdn.alpinelinux.org/alpine/v3.4/main] v3.4.6-33-g38ef2d2 [http://dl-cdn.alpinelinux.org/… / v3. 4 / community] OK: 5977 verschiedene Pakete verfügbar (1/5) Installieren von lua5.2-libs (5.2.4-r2) (2/5) Installieren von ncurses-terminfo-base (6.0-r7) (3/5) Installieren ncurses-terminfo (6.0-r7) (4/5) Installation von ncurses-libs (6.0-r7) (5/5) Installation von vim (7.4.1831-r2) Ausführen von busybox-1.24.2-r9.trigger OK: 37 MiB in 16 Paketen ---> 7fa4cba6d14f Entfernen des Zwischencontainers e2c0524bd792 Schritt 4/4: CMD cat / yeah ---> Ausführen in 351b4f1c1eb1 ---> e124405f28f4 Entfernen des Zwischencontainers 351b4f1c1eb1 Successf vollständig gebaut e124405f28f4

Sieht gut aus. Vergewissern Sie sich, dass das Bild erstellt wurde:

> docker images | grep oh-yeah oh-yeah-alpine latest e124405f28f4 Vor einer Minute 30,5 MB

Beachten Sie, wie die Installation von vim und seine Abhängigkeiten die Größe des Containers von 4,8 MB des Basis-Alpinimage auf 30,5 MB vergrößert haben!

Es ist alles sehr nett. Aber funktioniert es??

> docker run oh-yeah-alpine es funktioniert!

Oh ja, es funktioniert!

Falls Sie immer noch misstrauisch sind, gehen wir in den Container und untersuchen die "yeah" -Datei mit unserem frisch installierten vim.

> docker run -it oh-yeah-alpine / bin / sh / # vim yeah es funktioniert! ~ ~… ~ "Ja" 1L, 10C

Der Build Context und die .dockerignore-Datei

Ich habe es dir nicht erzählt, aber ursprünglich, als ich das ach ja alpine Image bauen wollte, hing es nur einige Minuten. Das Problem war, dass ich die Docker-Datei gerade in meinem Home-Verzeichnis abgelegt habe. Wenn Docker ein Image erstellt, packt es zunächst das gesamte Verzeichnis, in dem sich die Docker-Datei befindet (einschließlich Unterverzeichnissen), und stellt es für COPY-Befehle in der Docker-Datei zur Verfügung. 

Docker versucht nicht, intelligent zu sein und Ihre COPY-Befehle zu analysieren. Es packt einfach das Ganze. Beachten Sie, dass der Build-Inhalt nicht in Ihrem Image endet, der Build-Befehl wird jedoch verlangsamt, wenn der Build-Kontext unnötig groß ist.

In diesem Fall habe ich einfach die Dockerfile und das "yeah" in ein Unterverzeichnis kopiert und den Docker-Build-Befehl in diesem Unterverzeichnis ausgeführt. Manchmal haben Sie jedoch eine komplizierte Verzeichnisstruktur, aus der Sie bestimmte Unterverzeichnisse und Dateien kopieren und andere ignorieren möchten. Geben Sie die .dockerignore-Datei ein. 

Mit dieser Datei können Sie genau steuern, was in den Build-Kontext einbezogen wird. Mein Lieblingstrick ist es, zuerst alles auszuschließen und dann die benötigten Teile einzubauen. In diesem Fall könnte ich beispielsweise die folgende .dockerignore-Datei erstellen und die Docker-Datei und das "yeah" in meinem Home-Verzeichnis behalten:

# ALLES zuerst ausschließen * # Jetzt selektiv Sachen einschließen! Yeah

Es ist nicht erforderlich, die "Dockerfile" selbst oder die ".dockerignore" -Datei in den Buildkontext aufzunehmen.

Kopieren vs. Montieren

Sie müssen manchmal Dateien in das Image kopieren, in anderen Fällen möchten Sie jedoch, dass Ihre Container dynamischer sind und mit Dateien auf dem Host arbeiten. Hier kommen Volumen und Reittiere ins Spiel. 

Das Mounten von Host-Verzeichnissen ist ein anderes Ballspiel. Die Daten gehören dem Host und nicht dem Container. Die Daten können geändert werden, wenn der Container angehalten wird. Derselbe Container kann mit verschiedenen gemounteten Host-Verzeichnissen gestartet werden.

Bilder kennzeichnen

Das Kennzeichnen von Bildern ist sehr wichtig, wenn Sie ein auf Microservices basierendes System entwickeln und viele Bilder generieren, die manchmal miteinander verbunden werden müssen. Sie können einem Bild beliebig viele Tags hinzufügen. 

Sie haben bereits das Standard-Tag "latest" gesehen. Manchmal ist es sinnvoll, andere Tags hinzuzufügen, wie "getestet", "Release-1.4" oder das Git-Commit, das dem Image entspricht.

Sie können ein Bild während eines Builds oder später markieren. So fügen Sie einem vorhandenen Bild ein Tag hinzu: Beachten Sie, dass Sie, obwohl es ein Tag genannt wird, auch ein neues Repository zuweisen können.

> docker-Tag oh-yeah-alpine oh-yeah-alpine: cool-tag> docker-Tag oh-yeah-alpine oh-yeah-alpine-2> docker images | oh oh oh yeah-alpine-2 neueste e124405f28f4 30,5 MB oh-yeah-alpine cool-tag e124405f28f4 30,5 MB oh-yeah-alpine neueste e124405f28f4 30,5 MB

Sie können die Markierung auch aufheben, indem Sie ein Bild anhand seines Tagnamens entfernen. Dies ist etwas beängstigend, denn wenn Sie den letzten Tag versehentlich entfernen, verlieren Sie das Bild. Wenn Sie jedoch Bilder aus einer Docker-Datei erstellen, können Sie das Bild einfach neu erstellen.

> docker rmi oh-yeah-alpine-2 Untagged: oh-yeah-alpine-2: aktuell> docker rmi oh-yeah-alpine: cool-tag Untagged: oh-yeah-alpine: cool-tag

Wenn ich versuche, das letzte verbleibende markierte Bild zu entfernen, erhalte ich eine Fehlermeldung, da es von einem Container verwendet wird.

> docker rmi oh-yeah-alpine Fehlerantwort vom Daemon: Konflikt: Repository-Referenz "oh-yeah-alpine" kann nicht entfernt werden (muss erzwingen) - Container a1443a7ca9d2 verwendet das referenzierte Bild e124405f28f4

Aber wenn ich den Behälter entferne…

> Docker rmi oh-yeah-alpine Untagged: oh-yeah-Alpin: latest Deleted: sha256: e124405f28f48e ... 441d774d9413139e22386c4820df Gelöscht: sha256: 7fa4cba6d14fdf ... d8940e6c50d30a157483de06fc59 Gelöscht: sha256: 283d461dadfa6c ... dbff864c6557af23bc5aff9d66de Gelöscht: sha256: 1b2a228cc2a5b4 ... 23c80a41a41da4ff92fcac95101e Gelöscht: sha256: fe5fe2290c63a0 … 8af394bb4bf15841661f71c71e9a> docker images | grep oh-ja

Ja. Es ist weg. Aber mach dir keine Sorgen. Wir können es wieder aufbauen:

> docker build -t oh-yeah-alpine. > docker images | grep oh-yeah oh-yeah-alpine letzte 1e831ce8afe1 vor 1 Minuten 30.5 MB 

Ja, es ist wieder da. Dockerfile für den Sieg!

Mit Bildregistern arbeiten

Bilder sind in einigen Punkten sehr ähnlich zu Git-Repositories. Sie werden auch aus einer geordneten Menge von Commits erstellt. Sie können sich zwei Bilder vorstellen, die dieselben Basisbilder wie Verzweigungen verwenden (obwohl es in Docker kein Zusammenführen oder Umbasieren gibt). Ein Bildregister entspricht einem zentralen Git-Hosting-Dienst wie GitHub. Ratet mal, wie heißt das offizielle Docker-Image-Register? Das ist richtig, Docker Hub. 

Bilder ziehen

Wenn Sie ein Image ausführen, falls es nicht existiert, versucht Docker, es aus einer Ihrer konfigurierten Image-Registries zu ziehen. Standardmäßig wird Docker Hub verwendet, Sie können es jedoch in Ihrer Datei "~ / .docker / config.json" steuern. Wenn Sie eine andere Registrierung verwenden, können Sie deren Anweisungen befolgen. Dazu müssen Sie sich normalerweise mit ihren Anmeldeinformationen anmelden.

Löschen Sie das Bild "Hallo-Welt" und ziehen Sie es erneut mit Docker ziehen Befehl.

> dockere images | grep hallo-welt hallo-welt neueste c54a2cc56cbb vor 7 Monaten 1.85 kB> docker rmi hallo-welt hallo-welt

Es ist weg. Lass uns jetzt ziehen.

> docker pull hallo-world Standard-Tag verwenden: neueste: Aus Bibliothek / hallo-world ziehen 78445dd45222: Vollständige Digest-Funktion: sha256: c5515758d4c5e1e… 07e6f927b07d05f6d12a1ac8d7 Status: neueres Bild für hallo-world: latest> dockere images | grep hallo-world hallo-world letzte 48b5124b2768 vor 2 Wochen 1.84 kB

Die neueste Hallo-Welt wurde durch eine neuere Version ersetzt.

Bilder schieben

Das Schieben von Bildern ist etwas komplizierter. Zuerst müssen Sie ein Konto bei Docker Hub (oder einer anderen Registrierung) erstellen. Als Nächstes melden Sie sich an. Dann müssen Sie das Bild, das Sie verschieben möchten, nach Ihrem Kontonamen kennzeichnen (in meinem Fall "g1g1")..

> docker login -u g1g1 -p  Login erfolgreich> docker-Tag hallo-world g1g1 / hallo-world> docker images | grep hallo g1g1 / hallo-world letzte 48b5124b2768 vor 2 Wochen 1.84 kB Hallo-world letzte 48b5124b2768 vor 2 Wochen 1.84 kB 

Jetzt kann ich das mit g1g1 / hello-world gekennzeichnete Bild verschieben.

> docker push g1g1 / hallo-world Der Push bezieht sich auf ein Repository [docker.io/g1g1/hello-world] 98c944e98de8: Aus Bibliothek / Hallo-Welt am neuesten: Digest: sha256: c5515758d4c5e… f6d12a1ac8d7 Größe: 524

Fazit

Docker-Images sind die Vorlagen für Ihre Container. Sie sind so konzipiert, dass sie effizient sind und eine maximale Wiederverwendung durch Verwendung eines Schicht-Dateisystemspeichertreibers ermöglichen. 

Docker bietet eine Vielzahl von Tools zum Auflisten, Überprüfen, Erstellen und Kennzeichnen von Bildern. Sie können Bilder in Bildregister wie Docker Hub ziehen und verschieben, um Ihre Bilder auf einfache Weise zu verwalten und freizugeben.