DevOps / Software-Entwicklung

Docker Basics – Befehle und Life Hacks

Docker ist eine besondere Art der Virtualisierung. Der Vorteil gegenüber VMWare, Hyper-V, KVM oder Xen ist, dass Docker nativ den Kernel des Betriebssystems nutzt und keinen Hypervisor dazwischen hat. Das macht Docker sehr schnell, leistungsfähig und performant. Beim Aufsetzen eines ELK-Stacks bin ich das erste Mal auf Docker gestoßen und wollte heraus finden ob diese Aufgabe dadurch schneller bewerkstelligt werden kann. Dabei sind mir immer wiederkehrende Befehle aufgefallen, welche ich in diesem Artikel genauer erklären möchte und Ihnen eine Hilfestellung sein können, wenn auch Sie beginnen sich mit Docker zu beschäftigen.

Docker

 

Docker Installation

Docker muss zuerst auf dem Hostsystem installiert werden, dies wird unter https://docs.docker.com/engine/installation/ genauer erklärt.

Es wird empfohlen einige Änderungen in den Einstellungen von Docker vorzunehmen. So können Sie diese Änderungen unter Windows vornehmen: Um in die Einstellungen zu gelangen klickt man mit Rechtsklick auf das Dockericon im Systemtray -Settings.

  • Shared Drives -shard C drive
  • Advanced -Memory auf 4096 MB erhöhen

 

Images vs Container

Docker arbeitet mit Images und Container. Images können als eine Art Template oder Blueprint gesehen werden. Ein Image selbst kann nicht gestartet werden. Ein Container basiert auf einem Image. Wenn man es mit objekt-orientierter Programmierung vergleichen will, ist ein Image eine Klasse und ein Container eine Instanz.

Ein Docker Image kann wie ein Package gesehen sehen werden: es beinhaltet neben der benötigten Runtime alle libraries, config files und natürlich auch die Applikation, die gestartet werden soll.

Ein Docker Container ist, wie bereits erwähnt, eine laufende Instanz eines Docker Images, welche komplett isoliert auf dem Betriebssystem läuft. Ein Docker Container hält also alle Daten, die von diesem Container verarbeitet oder erzeugt wurden (z.B.: Logfiles). Das bedeutet, wenn der Conainer gelöscht wird, werden auch alle enthaltenen Daten gelöscht. Außer es gibt ein volume mount auf die lokale Festplatte d.h: ein Ordner innerhalb des Dockercontainers wird auf einen Ordner im Hostsystem gemappt, beide Ordner sind somit immer inhaltsgleich, aber dazu später mehr.
Steht ein Service unter großer Last, so kann ein weiterer Container mit dem gleichen Image erstellt und die Last anschließend zwischen diesen Containern aufgeteilt werden.

 

Dockerfile

In dem Dockerfile wird beschrieben, wie ein Image aufgebaut ist und generiert werden soll. Dabei basiert ein Image immer auf einem anderen Image oder es wird von scratch erstellt. Durch diesen Aufbau kann jedes Images nur einen Teil der Infrasttuktur beitragen und muss nicht die gesamte Laufzeitumgebung in einem Image zusammenstellen (was möglich, aber sehr unübersichtlich wäre). Auf welchem Image ein Dockerfile basiert wird mit dem Schlüsselwort FROM angegeben. Sehen wir uns ein Beispiel dazu an.

Das Image wordpress basiert auf dem Image php:5.6-apache, welches auf dem Image debian:jessie basiert. Das Debian Image wiederum basiert auf keinem anderen Image, daher steht in diesem Dockerfile „FROM scratch“.

 

Die wichtigsten Dockerfile build instructions:

  • FROM  hier wird das Image angegeben auf dem das neue Image basiert. Wenn es auf keinem Image basieren soll, kann auch Scratch angegeben werden.
  • MAINTAINER Wer ist für dieses Image zuständig und führt die Wartung durch?
  • COPY kopiert den Inhalt des angegebenen Pfades in den Container zu dem angegebenen Pfad
  • ADD wie COPY, nur kann dieser Befehl komprimierte Dateien automatisch öffnen und entpacken. Wenn diese Funktion nicht benötigt wird, sollte stattdessen COPY  verwendet werden.
  • RUN führt ein Shell Script aus. In Linux auf der /bin/bash in Windows auf der cmd. Das auszuführende Script muss sich schon innerhalb des Containers befinden. Dieser Befehl wird verwendet um den Container zu erstellen. Wenn dieser bereits erstellt und gestartet wurde, werden die Befehle mit CMD oder ENTRYPOINT angegeben.
  • ENV setzt Umgebungsvariablen innerhalb des Containers
  • USER setzt den User unter welchem die Scripte ausgeführt werden
  • ENTRYPOINT legt fest welcher Befehl beim Start des Containers ausgeführt werden soll.
  • CMD dieser Befehl wird nach dem Starten des Docker Containers ausgeführt. Es gibt drei verschiedene Formen des Befehls. Die Hauptaufgabe des CMD Befehles ist es aber Defaultwerte für die Ausführung von ENTRYPOINT bereit zu stellen.
    • CMD [executeable,param1,param2] , führt “excuteable” mit den angegebenen Parametern aus.
    • CMD [param1,param2] , diese Parameter werden dem executable des Entrypoint hinzugefügt.
    • CMD command param1 param2 , shell Format zum Ausführen von Befehlen

 

Die Befehle CMD und ENTRYPOINT darf es jeweils nur einmal geben. Kommen diese Befehle dennoch öfter in einem Dockerfile vor, hat nur der jeweils letzte Befehl einen Effekt.

  • VOLUME mountpoint von Hostsystem in dem Container. Der angebenene Ordner steht auch innerhalb des Containers zur Verfügung. Auf diese Weise können Daten zwischen den Containern ausgetauscht werden.
  • EXPOSE gibt die Ports an, auf welche der Container hört. Wenn nichts angeben wird handelt es sich um TCP. Wenn /udp angegeben wird kann auf das UDP Protokoll umgestellt werden.
  • ONBUILD fügt einen Trigger hinzu der ausgeführt wird wenn dieses Image als Base Image (also im FROM Befehl eines anderen Dockerfiles) verwendet wird. Nach ONBUILD kann eine der oben genannten build instructions angegeben werden.

 

Beispiel wordpress Dockerfile:

Quelle:03.01.2018: https://github.com/docker-library/wordpress/blob/618490d4bdff6c5774b84b717979bfe3d6ba8ad1/apache/Dockerfile#L5-L9

 

Mit dem Befehl docker build -t myWordpress .  kann das dockerimage gebaut werden, was dieser Befehl genau macht oder was der Parameter -t bedeutet wird in den Docker Commands im folgenden Absatz genauer erklärt.

 

Docker Commands

Eine vollständige Übersicht über alle Docker command line Befehle gibt es bei Docker unter https://docs.docker.com/engine/reference/commandline/docker/#child-commands, die wichtigsten Befehle werden ich hier kurz erklären. Diese Befehle können in der Unix shell oder unter Windows im cmd angewendet werden. Auf Windows empfiehlt es sich aber hierfür die Powershell zu nutzen.

Wenn (CONTAINER | SERVICENAME) angegeben ist, dann kann statt dem Containernamen auch der Name des Services eines Docker-Composestacks (Docker-Compose wird nachfolgend in Anwendungsstacks mit docker-compose genauer erklärt) angegeben werden.

  • docker build -t "imagename"  buildet ein Docker Image aus einer Datei namens „Dockerfile“ (ohne Dateiendung), das Image bekommt den Namen der mit -t als Parameter übergeben wurde.
  • docker run -d -p 8080:80 "imagename"  erstellt und startet einen Container basierend auf den Images,
    • -p  mappt den port 8080 (des Hostsystems) im Container auf den port 80.
    • -d  startet den Container im detached mode, der Container wird im Hintergrund gestartet und die console wird nicht von der Ausgabe des Docker Containers blockiert.
  • docker images  zeigt alle gebauten oder heruntergeladenen Images an
  • docker image rm IMAGE  entfernt das angegebene Image
  • docker container ls -a  zeigt alle laufenden Container an, der Parameter -a zeigt auch alle derzeit nicht laufenden an. Dieser Command ersetzt docker ps welcher aber auch weiterhin noch funktioniert.
  • docker start CONTAINER  startet den angegeben Container.
  • docker logs -f (CONTAINER | SERVICENAME)  zeigt den log output des Containers
    • -f : mit dem Parameter -f wird der folgende log output live ausgegeben.
  • docker attach (CONTAINER | SERVICENAME)  hängt den Standard Input und Output auf die aktuelle Konsole. Man kann wie mit ssh eine Verbindung in den Container aufbauen. Achtung: dies ist keine richtige ssh Verbindung. Das merkt man insbesondere wenn man die Verbindung wieder auflösen will. CTRL-c oder exit stoppt auch den Container. Die Verbindung kann mit CTRL-p CTRL-q gelöst werden.
  • docker exec -it CONTAINER /bin/sh  mit exec kann ein Befehl innerhalb des Containers ausgeführt werden. Wird der Befehl /bin/sh (wenn eine bash vorhanden ist kann auch /bin/bash verwendet werden) angegeben, ist dies eine alternative Variante um auf die shell im Container zuzugreifen. Wichtig ist, das die Option -it angegeben wird. Der Vorteil dieser Variante gegenüber docker attach ist, dass die shell wie gewohnt mit exit verlassen werden kann und der Container dabei nicht gestoppt wird.
  • docker stop CONTAINER  stoppt den angegeben Container. Der Container wird heruntergefahren.
  • docker kill CONTAINER  der Container wird mit einem Kill signal gestoppt.
  • docker rm CONTAINER  entfernt den Docker Container (nur den Container nicht das Image)

 

Die folgenden Befehle können nicht in der Windows commandline cmd eingegeben werden, sondern müssen auf Windowssystemen in der Powershell ausgeführt werden. In Unix Systemen können diese Befehle normal ausgeführt werden.

  • docker rm $(docker ps -aq)  löscht alle Container (docker ps -aq der parameter -q beschränkt die Ausgabe auf die Ids. Der Befehl gibt also die Ids aller Container zurück und mit $ wird über all diese Ids iteriert und docker rm ausgeführt)
  • docker image rm $(docker images -q)  löscht alle Images aus dem lokalen Repository (wie oben beschrieben nur mit docker images -q)

 

Dockerignore

Mit einem .dockerignore File können gewisse Dateien von Docker beim Builden eines Images ignoriert werden. Das .dockerignore File funktioniert ähnlich wie ein .gitignore File. Es werden Dateinamen mit Endungen oder ganze Ordner angegeben. Dabei können auch Wildcards (*) verwendet werden. Alle Ordner oder Dateien, die in dem .dockerignore angegeben sind, werden bei einem COPY oder ADD nicht mitkopiert.

 

Soweit mal die ersten Befehle, die ich für sehr wichtig erachte im Umgang mit Docker. Im nächsten Teil sehen wir uns an, wie man einen kompletten Anwendungsstack mit Docker Compose aufbauen kann.

Zum zweiten Teil: Anwendungsstacks mit Docker Compose

Download Cheatsheet: Docker_Basics_Cheatsheet

Passende Artikel

Antwort schreiben

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*