© StonePictures/Shutterstock.com
Packer und Jib als Alternativen zur klassischen Dockerfile-Methode

Kreative Wege, Docker Images zu bauen


Ist der klassische Weg, Docker Images über docker build zu bauen, wirklich in jedem Fall die beste Art und Weise? In diesem Artikel geht Roland Huß, Software Engineer bei Red Hat, dieser Frage auf den Grund und stellt zwei alternative und kreative Wege vor, Docker Images zu erstellen.

Erinnert ihr euch noch daran, wie ihr euer erstes Docker Image gebaut habt? Ein Basis-Image auswählen, ein simples Dockerfile schreiben, und mithilfe von docker build wird das Ganze dann gebaut. Das ist eigentlich schon zu einfach, um wahr zu sein. docker build ist auch heute noch der kanonische Weg, Docker Images zu bauen. Aber ist es auch immer die beste Methode für alle Fälle? Welche Alternativen gibt es? In diesem Artikel präsentiere ich zwei alternative und kreative Wege, Docker Images zu bauen.

Packer

Packer ist ein Open-Source-Werkzeug von Hashicorp, mit dem Machine Images für die verschiedensten Plattformen wie Amazon EC2, DigitalOcean, Google Compute Engine, Virtual Box, VMWare oder eben auch Docker erstellt werden können. Viele kennen Packer als den Mechanismus zur Erstellung sogenannter Boxes als Grundlage für Vagrant-Konfigurationen.

Mit einer einzigen Konfigurationsdatei können verschiedene, gleichartige Images erzeugt werden. Dabei ersetzt Packer kein Konfigurationsmanagementsystem (CMS) wie Puppet oder Ansible. Im Gegenteil: CM-Systeme werden genutzt, um die Machine Images reproduzierbar zu bestücken, bevor das Image finalisiert wird.

Packer ist ein in Go geschriebenes Kommandozeilentool, das als einzelnes Binary installiert und für verschiedene Plattformen bereitgestellt wird. Die zu erstellenden Images werden dann über Templates beschrieben. Innerhalb der Templates nutzt Packer drei wichtige Abstraktionen:

  • Builders dienen zum eigentlichen Erstellen der Images im jeweiligen Zielformat. In einem Template können mehrere Builder angegeben werden, die jeweils individuell konfiguriert werden können. Für jedes der konfigurierten Zielsysteme wird parallel ein Image gebaut.

  • Provisioners werden genutzt, um die Images zu bestücken. In diesem Schritt können Dateien kopiert und Shell-Skripte ausgeführt werden. Oder aber es werden vollwertige CM-Systeme wie Puppet, Chef oder Ansible aufgerufen, um Anwendungen in dem Image zu installieren und zu konfigurieren.

  • Post Processors werden aufgerufen, nachdem die finalen Images erzeugt worden sind. Damit kann beispielsweise ein gerade gebautes Docker Image getaggt oder zu einer Registry gepusht werden.

Insbesondere zur Provisionierung von klassischen Virtuellen Maschinen ist Packer sehr gut geeignet, da es hierfür ja oft keinen intrinsischen Build-Mechanismus gibt. Im Gegensatz dazu bietet Docker ja mit dem Dockerfile bereits einen nativen Weg, Docker Images zu erstellen. Dennoch kann Packer eine interessante Alternative auch zum Bauen von Docker Images sein. Anhand eines Beispiels wollen wir uns genauer anschauen, wie das geht:

Builder

Wir wollen nun mit Packer ein Docker Image erzeugen, das mit nginx eine statische Webseite ausliefert. Dazu müssen wir ein Template erstellen, was letztendlich nichts anderes als ein JSON-Dokument ist. Als Builder nehmen wir natürlich einen Docker Builder, den wir wie in Listing 1 dargestellt konfigurieren können

Listing 1

{ "builders": [ { "type": "docker", "image": "centos:7", "commit": true, "changes": [ "EXPOSE 80", "CMD [ \"nginx\", \"-g\", \"daemon off;\" ]" ] } ] }

Jeder Builder hat einen spezifischen type, hier ist es docker. Die weiteren Parameter sind Builder-spezifisch und werden per Builder in der Packer-Dokumentation erklärt. Für den Docker Builder brauchen wir ein Basis-Image (image) und wir spezifieren hier, dass der Container am Ende committet wird, sodass daraus wieder ein Image entsteht. Alternativ kann auch "export_path": "image.tar" spezifiert werden. Damit wird der Container am Ende der Provisionierung als Tar-Archiv exportiert.

Mit changes können Metadaten für einen Commit angepasst werden. Falls das Image nur exportiert werden soll (via export_path), dann wird changes jedoch ignoriert. Das ist eine gute Möglichkeit, mit CMD das Startkommando innerhalb des Image zu definieren. Es wird dann bei einem docker run genutzt.

Mit dieser Konfiguration startet der Docker Builder zunächst einen Container mit dem Basis-Image centos:7 als Vorlage. Danach läuft die Provisionierung (siehe nächster Absatz), bevor dann der Container wieder zu einem Image committet wird. Dieses Image hat zunächst keinen Namen, doch dieser kann mit einem Post-Proze...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang