Show Menu
Cheatography

Docker Merkliste

Docker Umgebungen / Provider

Instal­lation unter Ubuntu

curl -sSL https://get.docker.com/ | sh
curl -sSL https://get.docker.com/gpg | sudo apt-key add -
sudo docker run hello-world

; um nicht bei jedem Kommando sudo nutzen zu müssen 
sudo usermod -aG docker mylocaluserName
; restart und dann läufts ohne sudo

; Falls dieser Fehler erscheint
;Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
; Dann muss in der Regel noch der Daemon gestartet werden
; Temporär geht das so 
sudo dockerd&


; Bei diesem Fehler 
Error starting daemon: error initializing graphdriver: driver not supported
; half bei mir die Docker Installation zu aktualisieren und
; das Verzeichnis der aufs images zu löschen: sudo rm -rf /var/lib/docker/aufs
; (anschließend neustart)
Dein Kernel sollte mindestens 3.10 besser 3.13 oder höher sein. Prüfe es mittels: uname -r
Weitere Infos unter: https:­//d­ocs.do­cke­r.c­om/­ins­tal­lat­ion­/ub­unt­ulinux/

Docker File - Syntax

FROM
Base Image von dem abgeleitet wird
MAINTAINER
Produzent des Images
LABEL
Hinzufügen von Metain­for­mat­ionen
ARG
Definiert Build Parame­ter­var­iablen deren Werte bereits ins Image geschr­ieben werden
ENV
Definiert Umgebu­ngs­var­iablen welche beim Contai­ner­start mit -e übersc­hrieben werden - im Image werden nur Platzh­alter angelegt
ADD
Hinzufügen von Dateien zum Image aus dem Host
COPY
Kopiert Dateien vom Host in das Image
RUN
Kommando welches beim Build ausgeführt wird
EXPOSE
Freigabe und Mapping von Ports zur Aussenwelt (Host und andere Container)
VOLUME
Definiert Volumen welche mit der Aussenwelt verknüpft werden können (Mount­point)
WORKDIR
Festlegen des Arbeit­sve­rze­ich­nisses
USER
Accoun­twe­chsel beim Build des Images z.b. von root auf jenkins
ENTRYPOINT
Kommando welches beim Contai­ner­start ausgeführt wird (ergänzt den Entryp­oint)
CMD
Kommando welches beim Contai­ner­start ausgeführt wird (ergänzt den Entrypoint z.B. um Parameter)
Die Kommandos im Dockerfile werden in der Regel ausgeführt während des Build Prozesses und auf den im Image liegenden Verzei­chn­issen und Dateien.

Einzige Kommandos welche zur Laufzeit des Images also im Container ausgeführt werden sind: CMD und ENTRYPOINT

Details zu den Kommandos: https:­//d­ocs.do­cke­r.c­om/­v17.09­/en­gin­e/r­efe­ren­ce/­bui­lder/

Command Line Befehle

docker build -t user/p­oje­ctn­ame:tag projec­tfolder
Docker Image bauen aus einem Projekt mit Dockerfile
docker pull user/p­roject
Lädt ein Image von Docker Hub herunter. Image ID funkti­oniert über User/P­rojekt
docker images
Listet alle lokal verfüg­baren images
docker image inspect <im­age­Id>
Zeigt Detail­inf­orm­ationen zum Image an
docker rmi user/r­epo:tag
Löscht lokal das zugeor­dnete Image.
docker image rm <im­age­Id> [-f]
Löscht ein Image aus der lokalen Registry. Mit -f auch wenn noch Abhäng­igk­eiten zu laufenden Containern bestehen.
docker run
Startet einen Container. Z.B. docker run -it ubuntu bash startet ein Ubuntu mit Shell
docker stop <co­nta­ine­rId>
Tötet den MainThread im Container und beendet ihn dadurch. Die Daten aus dem editie­rbaren Layer bleiben erhalten.
docker start <co­nta­ine­rId>
Startet einen Container wieder an der Stelle an der er gestoppt wurde.
docker ps
Zeigt alle laufenden Container. Mit -a auch alle anderen.
docker rm <co­nta­ine­rId­|na­me:­tag>
Löscht einen nicht laufenden Container
docker exec -it <co­nta­ine­rId> bash
Startet eine zusätz­liche Bash auf dem laufenden Container mit ID
docker commit <co­nta­ine­rId> <me­in-­neu­er-­ima­ge-­nam­e>:­<ta­g-n­ame>
Persis­tiert die Änderungen eines laufenden Containers als Image. z.B: docker commit c3f279­d17e0a SvenDo­wid­eit­/te­sti­mag­e:v­ersion3
docker export <co­nta­ine­rId> -o <fi­len­ame­>.tar
Container als Tar File export­ieren
docker save -o mein-i­mag­e-s­ave.tar <me­in-­ima­ge-­nam­e>
Image als Tar zur Weitergabe export­ieren
docker load -i mein-i­mag­e-s­ave.tar
Docker Image aus Tar lokal einlesen
docker tag <im­age­Id> user/p­roj­ect:tag
Taggen eines lokalen Images
docker login
Intera­ktive Eingabe der Login Daten für Docker Hub
docker push user/r­epo:tag
Upload eines Images zum Docker Hub Portal
docker system prune
Räum lokal mal richtig auf - obsolete Dinge fliegen weg
Bitte beachten Sie, dass vor dem Upload von Images auf Docker Hub eine Regist­rierung bei dieser Platform notwendig ist.

Weiterhin ist für einen author­isi­erten Zugriff vor einem Push ein Login mittels docker login auf der Komman­dozeile durchz­ufü­hren.

Best Praxis ist ein automa­tisch baubares Images auf Github als Projekt zu hosten und mit Docker Hub zu verbinden.

Docker in Docker (nested docker)

Du willst einen Docker Daemon in einem Docker Container starten und weißt nicht wie es geht? Dann kennst Du auch nicht die Probleme welche daraus result­ieren. Zunächst lies also diese beiden Artikel:
* https:­//i­tne­xt.i­o/­doc­ker­-in­-do­cke­r-5­219­58d­34efd
* https:­//g­ith­ub.c­om­/jp­eta­zzo­/dind
Jetzt weißt Du was Du wirklich willst und entsch­eidest zwischen blauer oder roter Pille?

A) Du willst eigentlich nur Container in einem Container starten z.B. um zu Testen oder zu bauen (Jenkins etc. ...) und diese dürfen durchaus im Hostsystem angelegt werden? Dann nimm ein von docker abgele­itetes image und mounte beim Start als Volume den docker Socket. Dein Docker Client im Container kann ab jetzt genau wie der Docker Client vom Host über den selben docker Deamon neue Container starten und Images pullen.
docker run -ti -v /var/r­un/­doc­ker.so­ck:­/va­r/r­un/­doc­ker.sock docker


B) Du willst wirklich einen echten versch­ach­telten Docker - also im Container einen eigenen Docker deamon. Dann starte ein vom docker­:dind Image abgele­itetes Image mit Sonder­pri­vil­egien. Alles wird gut - aber wundere Dich nicht wo Dein Speicher bleibt.
docker run --priv­ileged -d docker­:dind

Jenkins im Container

docker run -p 8080:8080 -p 50000:­50000 -v /var/r­un/­doc­ker.so­ck:­/va­r/r­un/­doc­ker.sock -v /usr/b­in/­doc­ker­:/u­sr/­bin­/docker -v /var/l­ib/­jen­kin­s_h­ome­:/v­ar/­jen­kin­s_home -e "­DOC­KER­_GI­D_O­N_H­OST­=do­cke­r_g­rou­p_i­d" oose/d­ock­erj­enkins

Troubl­esh­ooting

# Kein Image im Manifest beim pull
Fehlerbild
> latest: Pulling from librar­y/o­penjdk

> no matching manifest for unknown in the manifest list entries

Ursache
Das angefo­rderte Image unters­tützt die vorlie­gende Archit­ektur nicht
Analyse
> docker info  -f '{{.OSType}}/{{.Architecture}}'

Lösung (Beisp­iel­suche nach openjdk)
> mkdir ~/dock­er-­tes­tconfig

> touch ~/dock­er-­tes­tco­nfi­g/c­onf­ig.json

{
"­exp­eri­men­tal­": "­ena­ble­d"
}
> docker --config ~/dock­er-­tes­tconfig manifest inspect -v librar­y/o­pen­jdk­:latest | jq .[].Pl­atform

Quelle
https:­//s­ucc­ess.do­cke­r.c­om/­art­icl­e/e­rro­r-p­ull­ing­-im­age­-no­-ma­tch­ing­-ma­nifest

Netzwerke bilden: user-d­efined bridge

Im default Netzwerk (also ohne irgend­welche Anpass­ungen) finden sich die einzelnen Container (z.B. frontend und backend) einer App nicht. Hier konnte man früher mit dem jetzt nicht mehr unters­tützten docker run Argument
--link
eine Verbindung schaffen. Der Weg wird explizit als veraltet und nicht empfohlen beschr­ieben.

Der neue Weg sind die Definition von "­use­r-d­efi­ned­-brigde Netzwe­rke­n". Alle Container eines Netzwerkes können direkt untere­inander kommun­izieren (über den Contai­ner­namen welcher als Hostname im DNS fungiert). Hierbei wird von automatic service discovery gespro­chen. Die Zuordn­ungen können on the fly erstellt und entfernt werden:

# ein Netzwerk my-net erstellen

docker network rm my-net

`# den Container my-nginx dem Netzwerk my-net zuordnen'
docker network connect my-net my-nginx

# den Container my-nginx aus dem Netzwerk my-net entfernen

docker network disconnect my-net my-nginx


Zusätzlich lassen sich über publish Portma­ppings herste­llen:
--publish 8080:80
mappt Port 80 im Container auf 8080 im Host.

Beispiele zum konkreten Aufbau von Netzwerken findet man hier:
https:­//d­ocs.do­cke­r.c­om/­net­wor­k/n­etw­ork­-tu­tor­ial­-st­and­alo­ne/­#us­e-u­ser­-de­fin­ed-­bri­dge­-ne­tworks

Netzwerke über versch­iedene Docker Deamon's nennen sich Overlay Netze:
https:­//d­ocs.do­cke­r.c­om/­net­wor­k/o­verlay/
 

Allgemeine Infos

Docker ist ein System welches fertige Systeme (ähnlich einer virtuellen Machine) bereit­stellen kann. Diese Systeme werden in Docker Images beschr­ieben (eine Art Template oder Klasse). Von diesen Images lassen sich dann beliebig viele Laufze­iti­nst­anzen starten. Jede Laufze­iti­nstanz eines Images wird Container genannt (sozusagen die konkrete Ausprägung einer System­kla­sse).

In jedem Container soll es nur einen Hauptt­hread geben. Solange dieser ausgeführt wird, gilt der Container als gestartet. Ist der Hauptt­hread beendet so geht der Container in den Zustand gestoppt über.

Die Images sind in Layer untert­eilt. Jeder Layer enthält die Deltas welche auf dem Filesystem stattf­anden. Images selbst sind TAR Archive. Die Layer im Image sind nur lesbar und nicht beschr­eibbar.

Beim Start eines Containers wird auch ein zusätz­licher beschr­eib­barer Layer on top angelegt. In diesem können die Anwend­ungen Änderungen am Filesystem vornehmen. Nach dem Stop eines Containers bleibt dieser Layer in diesem konkreten Container erhalten. Der Zustand lässt sich per docker commit persis­tieren.

Docker Images können automa­tisiert per Dockerfile über docker build erstellt werden. Um die Größe der Images klein zu halten (sie explodiert extrem schnell), sollte von kleinen Root Images (alpine) abgeleitet und ein Multistage Build genutzt werden.

Container mit Sicher­hei­tsi­nfo­rma­tionen wie Passwö­rtern oder gültig konfig­uri­erten GIT Zugängen sollte man niemals auf den HUB schieben!

Wird ein Container auf einem Remote Host gestartet (z.B. weil dort der Docker Daemon läuft) so beziehen sich die Parameter wie Port- und Volume­nma­ppings auf diesen Remote­host.

Beim Mappen von Volumen werden die Berech­tig­ungen wie User-ID und Gruppen-ID aus dem Container zum Schreiben auf das gemountete Volumen benutzt. Wenn die ID 100 im Container dem Nutzer jenkins gehört und der Hauptt­hread unter Nutzer jenkins läuft und dieser auf die gemoun­teten Volumen schreibt, dann wird auf dem Host mit der Nutzer ID 100 geschr­ieben auch wenn diese dann dem Nutzer Klaus oder root gehört. Zur Anwendung kommen natürlich dann die Berech­tig­ungen im Hostsy­stem. Wenn Klaus also keine Rechte zum Schreiben besitzt wird der Jenkins Nutzer aus dem Container im Host nicht auf das Volumen schreiben können.

Letztlich muss auch noch beachtet werden, dass Docker Images Archit­ektur spezifisch sind. Falls das vom Hub geladene Image nicht zur ausfüh­renden Archit­ektur passt kann man versuchen es selbst auf dieser Archit­ektur zu bauen. Dazu benötigt man natürlich das Dockerfile aber das ist über den Hub und die Verlinkung zum Projekt meist zu bekommen.
Proble­mat­ischer wird es wenn das im Dockerfile genutzte base Image nicht Archit­ektur agnostisch ist. Die aktuellen offizi­ellen Base Images großer Tools versuchen zwar agnostisch bzgl. der Archit­ektur zu sein aber das muss man evtl. prüfen und kann es nicht einfach als gegeben hinnehmen.
( https:­//s­tac­kov­erf­low.co­m/q­ues­tio­ns/­527­679­83/­doc­ker­-er­ror­-st­and­ard­-in­it-­lin­ux-­go1­85-­exe­c-u­ser­-pr­oce­ss-­cau­sed­-ex­ec-­for­mat-e )

Remote­zugriff auf die Docker Engine

ACHTUNG - Remote Zugriff ist Böse - Clients spielen Root - ACHTUNG

Der Docker Deamon läuft normal­erweise lokal und stellt den Socket
unix:/­//v­ar/­run­/do­cke­r.sock
für Anfragen von docker cli bereit.
Das kann heraus­gef­unden werden mittels:
sudo netstat -lnpx | grep docker.sock


Die Default Ports des Deamon sind 2375 (unver­sch­lüs­selt) und 2376 (versc­hlü­sselt).

Der aktuelle Status des Deamon lässt sich so ermitteln:
systemctl status docker.se­rvice



Der Zugriff auf einen Remote Docker Deamon kann per REST API oder über Docker CLI oder einem Dritta­nbieter Client vorgen­ommen werden.

1) Zugriff über Docker-CLI in der Shell

Hier muss die Umgebu­ngs­var­iable DOCKER­_HOST auf den Docker socket des Remote Daemon gesetzt werden. Ab da sendet Docker CLI alle Befehle an den Remote Deamon. Beispiel:

export DOCKER­_HO­ST=­tcp­://­X.X.X.X­:2376


2) Zugriff über das REST API

Dokume­ntation der Doker Engine REST API: https:­//d­ocs.do­cke­r.c­om/­eng­ine­/ap­i/v­ers­ion­-hi­story/

Ein Beispiel für das Absetzen von Kommandos per REST Client:
GET http:/­/x.x.x.x:­237­6/c­ont­ain­ers­/json -> entspricht einem docker ps


Auf dem Rechner des Docker Deamon muss der REST Zugriff freige­sch­alten werden.
API aktivieren ( https:­//s­ucc­ess.do­cke­r.c­om/­art­icl­e/h­ow-­do-­i-e­nab­le-­the­-re­mot­e-a­pi-­for­-do­ckerd ):
# /etc/s­yst­emd­/sy­ste­m/d­ock­er.s­er­vic­e.d­/ov­err­ide.conf anlegen mit inhalt

[Service]

ExecStart=

ExecSt­art­=/u­sr/­bin­/do­ckerd -H fd:// -H tcp://­0.0.0.0­:2376


$ sudo systemctl daemon­-reload

$ sudo systemctl restart docker.se­rvice


# Docker Deamon bei System­start automa­tisch starten lassen
$ sudo systemctl enable docker

docker run Options

-i
interacive Mode = -a STDIN
--sig-­pro­xy=true
Alle Signale werden an den Contai­ner­thread weiter­gel­eitet (nur ohne -t möglich)
-t
Stellt im Container eine Pseudo TTY bereit
-a stderr -a stdin -a stdout
-a verbindet stellt Streams des Hosts im Container zur Verfügung. Gülige Werte: STDIN, STDOUT, STDERR
-D
Schaltet den Debug Mode aktiv
Aufbau der Komman­doz­eile:
docker run [OPTIONS] IMAGE[­:TA­G|@­DIGEST] [COMMAND] [ARG...]

Details siehe hier: https:­//d­ocs.do­cke­r.c­om/­v17.09­/en­gin­e/r­efe­ren­ce/­run­/#f­ore­ground

Multistage Builds (Kompa­ktiere das Image)

Kleine und kompakte Images zu erzeugen war bislang schwierig - der alte Trick alles in eine Zeile zu pappen und mit && zu verknüpfen ist schwer wartbar und docker erkennt nicht immer wenn etwas neu gebaut werden muss. Dann gibt es hier und da auch schon mal veraltete images in denen die Änderung von eben gar nicht gegriffen hat.

Die Lösung: Multistage Builds durch mehrere FROM Anweis­ungen im Docker­file. Der Trick dabei: COPY --from=0 kopiert nur die Deltas aus dem letzten Stage (Das 0. FROM).

Besser Du benennst die einzelnen Stages:
FROM golang­:1.7.3 as builder

und nutzt die benannten Stages so:
COPY --from­=bu­ilder ...

Docker Image Analyse

Lokale Ablage der Images
* https:­//s­tac­kov­erf­low.co­m/q­ues­tio­ns/­192­348­31/­whe­re-­are­-do­cke­r-i­mag­es-­sto­red­-on­-th­e-h­ost­-ma­chine

Image Formate
* aufs
* overlay2
* ...

Grobe Infos auslesen
>docker image inspect <im­age­Id>


Image Explorer Werkzeuge
* https:­//g­ith­ub.c­om­/wa­goo­dma­n/dive

Image per Hand extrah­ieren
>docker save <im­age­Id> -o <fi­len­ame­>.tar

Spezif­ische Eclipse Instal­lation erstellen

>sudo docker run -it -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix batmat/docker-eclipse

; jetzt alle Plugins installieren und in einer anderen console folgendes eingeben
>docker ps
; Hiermit lässt sich die Container ID bestimmen und mit
>docker commit containerID  username/imagename:version
; den Container als Image persistieren.
; Das neue Image lässt sich dann starten mit:
>sudo docker run -it -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix containerID:version
Der Hauptgrund für dieses Vorgehen ist ein besteh­endes Linux System welches nicht verändert werden soll. Dennoch möchte man manchmal mit einer Eclips­e-Luna neue DSLs entwickeln und mit einer Eclips­e-K­epler neue RPC Anwend­ungen schreiben. Die benötigten Plugins und deren richtige Version können ein in die Hölle treiben. Daher ganz entspannt zukünftig nur den richtigen Docker Container starten. Klar vorher einmal bereit­stellen :)

Docker URL Aufbau

Allgemeine Syntax für Docker URL: [regis­try­-ur­l]/­[na­mes­pac­e]/­[image]

zum Beispiel: docker.io­/li­bra­ry/­mys­ql:­latest
 

Comments

No comments yet. Add yours below!

Add a Comment

Your Comment

Please enter your name.

    Please enter your email address

      Please enter your Comment.

          Related Cheat Sheets

          More Cheat Sheets by FunThomas424242

          Praktische Java Libs Cheat Sheet