Docker verwaltet leichte Container für Prozesse. Leicht bedeutet, der Container läuft ohne Hardware-Virtualisierung direkt auf dem Kernel des Hosts – aber streng isoliert mit eigene Dateisystemen, Benutzern und Netzwerken. Docker verwendet dazu Kontrollgruppen und Namensräume.
Debian pflegt kein offizielles Docker-Paket. Daher nimmt man den Schlüssel und das Depot des Docker-Projekts in die Paketquellen auf und installiert den Daemon.
echo "deb https://download.docker.com/linux/debian bullseye stable" \ >> /etc/apt/sources.list curl https://download.docker.com/linux/debian/gpg | apt-key add apt update apt install docker-ce
Mitglieder der Gruppe docker
dürfen Abbilder und
Container verwalten.
adduser User docker
Ein Abbild besteht aus einer Schablone für das Dateisystem beliebig vieler Container plus Metainformationen. Da man den Images aus dem offiziellen Depot nicht grundsätzlich vertrauen kann, ist es ratsam (und einfach), ein eigenes zu bauen.
debootstrap --variant=minbase stable /var/lib/machines/Name cd /var/lib/machines/Name && tar cf - . | docker import - User/Distribution:Codename
Um aus diesem Basis-Abbild ein spezifisches Abbild abzuleiten, startet man einen Container mit einer interaktiven Shell.
docker run -i -t --name Name User/Distribution:Codename /bin/bash
Dort installieren und konfigurieren wir die gewünschten Pakete…
docker run -i -t --name Name User/Distribution:Codename /bin/bash apt install Package cat << . > /etc/motd ## . ## ## ## == ## ## ## ## === /""""""""""""""""\___/ === ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~ \______ o __/ \ \ __/ \____\______/ . exit
…und erzeugt daraus schließlich ein neues Abbild.
docker commit Name User/Subimage
Ein Dockerfile dient als Anleitung für den Bau von Abbildern. Es liegt in einem eigenen Verzeichnis, dem Repository.
Instruktion | Parameter | Beispiel | Beschreibung |
---|---|---|---|
FROM | Image[:Tag=latest] | phrank/debian:bullseye | Basis für das zu erzeugende Image |
LABEL | Name=Value | maintainer=phrank | Metadaten für das Image |
ARG | Name | homedir | Nimmt Umgebungsvariable von außen entgegen |
ENV | Name=Value | HOME=${homedir:/root} | Setzt Umgebungsvariable für folgende Kommandos |
USER | User | daemon | Ändert Benutzerkennung für folgende Kommandos |
SHELL | Path | /bin/zsh | Ändert Shell für folgende Kommandos |
WORKDIR | Path | /etc | Ändert Arbeitsverzeichnis, auch für CMD und ENTRYPOINT |
ADD | Source Dest | whale.txt /etc/motd | Kopiert Dateien vom Repository in den Container |
COPY | Source Dest | ~/.inputrc /root/.inputrc | Kopiert Dateien vom Host in den Container |
RUN | Command | apt install -y nginx | Führt Kommando beim Erzeugen des Containers |
VOLUME | Path | /srv | Montiert externes Verzeichnis |
EXPOSE | Port … | 80 443 | Liste von Ports für die Verknüpfung von Containern |
CMD | Command | ["/bin/uname", "-a"] | Default-Kommando beim Start des Containers |
ENTRYPOINT | Command | ["/usr/bin/nginx"] | Initialer Prozess, kann nicht von run überschrieben werden. |
HEALTHCHECK | CMD Command | CMD test true || exit 1 | Fürt Kommando alle 30 Sekunden aus |
STOPSIGNAL | Signal | SIGKILL | Sendet anderes Signal beim Stoppen des Containers |
ONBUILD | Instruction | RUN rm -rf / | Führt Anweisung als Basis beim Bau verwendet wird |
Kommandos in exec
-Notation benötigen keine Shell.
Beispiel: Webserver
~/repository/webserver/DockerfileFROM User/Distribution:Codename RUN apt install -y nginx CMD nginx EXPOSE 80
Für jedes Abbild ein Verzeichnis mit einem Dockerfile darin anlegen und dort ausführen:
docker build --tag webserver ~/repository/webserver Sending build context to Docker daemon 2.56 kB Sending build context to Docker daemon Step 0 : FROM User/Distribution:Codename:custom ---> 8b4b40246122 … docker run -d -p 8080:80 --name webby webserver
Das Kommando run
erzeugt aus einem Abbild einen neuen
Container, indem es folgende Schritte ausführt:
-i
und -t
).bash
) aus.docker run -i -t Image /bin/bash
Der Container existiert weiter, auch wenn sich das ausgeführte
Programm beendet. Mit dem Kommando start
wird er im
Hintergrund gestartet. Mit attach
kann man Standardein-
und -ausgabe verbinden und mit stop
den Container
beenden.
Aus verschiedenen Gründen kann es sinnvoll sein, Dienste in getrennten Containern laufen zu lassen. Zuerst muss auf dem Host-System IP-Forwarding aktivieren.
sysctl "net.ipv4.ip_forward=1"
Folgender Aufruf startet den Container als Daemon (-d
) mit Portweiterleitung (-p
).
docker run --name=Name -d -p HostPort:GuestPort Image Command
Und so wird ein laufender Container gestoppt:
docker stop Name
Beim Herunterfahren des Containers sendet Docker jedem Prozess ein Signal und tötet nach einer Schonfrist von 10 Sekunden alle noch laufenden Prozesse. Damit containerisierte Dienste einen Neustart des Rechners überleben, meldet man sie beim Init-System an.
/etc/systemd/system/Name.service[Unit] Description=Text Author=DisplayName After=docker.service [Service] Restart=always ExecStart=/usr/bin/docker start -a Name ExecStop=/usr/bin/docker stop Name [Install] WantedBy=local.target
Schließlich starten wir den containerisierten Dienst.
systemctl enable --now Name.service
Ein Schwarm fasst mehrere Rechner mit Docker Engine (Knoten) zu einem Cluster zusammen und verbindet die teilnehmenden Container zu einem virtuellen Netzwerk mit integriertem DHCP- und DNS-Server.
Diese Auflistung soll nur einen Überblick über die verfügbaren Kommandos und Optionen vermitteln und erhebt keinen Anspruch auf Vollständigkeit. Als authoritative Quelle gelten nur die Manpages und die offizielle Dokumentation.
Kommando | Option | Parameter | Beschreibung |
---|---|---|---|
Daemon | |||
docker help | Command | Erklärt Optionen des Kommandos | |
docker version | Zeigt Version der Komponenten | ||
docker info | Zeigt Übersicht der Objekte | ||
docker stats | -a|--all | Beobachtet verwendete Ressourcen | |
docker events | --since=Time | Gibt Echtzeit-Ereignisse aus | |
--until=Time | …in diesem Zeitraum | ||
docker system df | Berechnet verwendeten Plattenplatz | ||
docker system prune | Löscht nicht verwendete Objekte | ||
Depot | |||
docker login | -e|--email=EmailAddress | [Server] | Meldet Benutzer beim Depot an |
-u|--username=User | …mit Name | ||
-p|--password=Pass | …und Passwort | ||
docker logout | [Server] | Meldet Benutzer ab | |
docker search | Keyword | Sucht Image auf dem Docker Hub | |
docker pull | Name[:Tag] | Holt Image vom Depot | |
docker push | Name[:Tag] | Sendet Image zum Depot | |
Image | |||
docker images | [Name] | Listet verfügbare Images auf | |
-a|--all | …mit allen Zwischenschichten | ||
-f|--filter=[…] | …mit bestimmten Eigenschaften | ||
-q|--quiet | …aber nur die Nummer | ||
docker build | -t|--tag="Name:Tag | Path | Url | Baut Image nach Anleitung aus dem Dockerfile im Pfad |
docker import | Url Image[:Tag] | Erzeugt Image aus einem Tar Archiv | |
docker export | Container | Schreibt Dateien des Containers in ein Tar Archiv | |
docker load | -i|--input=File | Liest Image aus Tar Archiv | |
docker save | -o|--output=File | Schreibt Image in Tar Archiv | |
docker tag | Image[:Tag] [RegistryHost/][User/]Name[:Tag] | ||
docker history | Image | Zeigt die Historie eines Images | |
docker image prune | Image | Löscht nicht verwendete Images | |
docker rmi | Image | Löscht ein Image | |
Container erzeugen | |||
docker run | Image [Command] | Führt Kommando in neuem Container aus | |
docker create | Image [Command] | Erzeugt Container aus Image | |
docker start | Container | Startet einen gestoppten Container | |
-a|--attach | Verbindet die Standardausgaben | ||
-i|--interactive | Verbindet die Standardeingabe | ||
docker stop | -t|--time=10 | Stoppt einen laufenden Container (nach 10 Sekunden) | |
docker restart | -t|--time=10 | Startet einen laufenden Container neu | |
docker pause | Container | Pausiert alle Prozesse in einem Container | |
docker unpause | Container | Setzt pausierte Prozesse fort | |
docker wait | Container | Wartet, bis sich der Container beendet hat | |
docker kill | -s|--signal="KILL" | Container | Sendet Signal an laufenden Container |
docker update | Container | Ändert Konfiguration eines Containers | |
docker rename | Container Name | Benennt Container um | |
docker rm | Container | Löscht gestoppten Container | |
-f|--force | Stoppt laufende Container vorher | ||
-l|--link | Löscht nur den Link | ||
-v|--volumes | Löscht auch Volumen | ||
Container untersuchen | |||
docker ps | Listet laufende Container auf | ||
-a|--all | …alle (auch gestoppte) Container | ||
-f|--filter | …die auf das Muster passen | ||
-l|--latest | …nur den zuletzt erzeugten | ||
-n|--last=N | …die letzen paar | ||
-q|--quiet | …nur Container-Nummer ausgeben | ||
-s|--size | …mit Dateigrößen | ||
docker inspect | Container | Zeigt Parameter eines Containers | |
docker logs | -f|--follow | Container | Reicht die Standardausgabe durch |
-t|--timestamps | Zeigt Zeitstempel an | ||
docker port | Container [Port] | Listet Port-Zuordnungen auf | |
docker top | Container | Listet die enthaltenen Prozesse auf | |
docker attach | Container | Verbindet Standardein- und ausgabe | |
docker exec | Container Command | Führt Kommando im Container aus | |
-d|--detach | …im Hintergrund | ||
-e|--env=[] | …mit Umgebungsvariablen | ||
-i|--interactive | …mit offener Standardeingabe | ||
-t|--tty | …mit Pseudo-Terminal | ||
-u|--user=Uid[:Gid] | …als Benutzer (in Gruppe) | ||
--privileged | …mit weitreichenden Privilegien | ||
docker cp | Container:Path Path | Kopiert Dateien vom Container zum Host | |
docker diff | Container | Gibt Änderungen im Dateisystem aus | |
docker commit | -a|--author=Name | Container [Image[:Tag]] | Erzeugt neues Image mit diesen Änderungen |
-m|--message=Text | …mit Kommentar | ||
Volumen | |||
docker volume ls | Volume | Listet Volumen auf | |
docker volume create | -d|--driver=Local | Erzeugt neues Volumen | |
-o|--opt=[] | …mit Optionen für den Treiber | ||
-l|--label=Name | …mit diesem Namen | ||
docker volume inspect | Volume | Zeigt Parameter eines Volumens | |
docker volume prune | Volume | Löscht nicht verwendete Volumen | |
docker volume rm | Volume | Löscht ein Volumen | |
Schwarm | |||
docker swarm init | --advertise-addr=IpAddress | Gründet einen Schwarm | |
docker swarm join | --token=Token | ManagerIp:2377 | Fügt Arbeiter hinzu |
docker swarm leave | @todo | ||
docker swarm unlock | @todo | ||
docker swarm update | @todo | ||
Knoten | |||
docker node ls | Listet Knoten im Schwarm auf | ||
docker node ps | [Node] | Listet Prozesse im (aktuellen) Knoten auf | |
docker node inspect | Node | Gibt Parameter aus | |
docker node promote | Node | Befördert Knoten zum Manager | |
docker node demote | Node | Degradiert Knoten zum Arbeiter | |
docker node update | Node | Ändert Parameter | |
docker node rm | Node | Entfernt Knoten aus dem Schwarm | |
Dienst | |||
docker service ls | Listet alle Dienste auf | ||
docker service ps | Service | Listet die Arbeiter eines Dienstes auf | |
docker service create | --name=Service | Image [Command] | Erzeugt mehrere Container aus einem Image |
--replicas=N | …mit so vielen Arbeitern | ||
docker service inspect | Service | Zeigt Parameter eines Dienstes | |
docker service update | Tauscht das Image aller Arbeiter | ||
docker service scale | Service=N | Ändert Anzahl der Arbeiter | |
docker service rm | Entfernt alle Arbeiter des Dienstes |
Option | Argument | Beschreibung | |
---|---|---|---|
-a | --attach | STDIN | Standardeigabe, |
STDOUT | Standardausgabe und | ||
STDERR | Fehlerausgabe aufzeichnen | ||
-c | --cpu-shares | 0 | Relatives Gewicht festlegen |
--cap-add | [CAP_…] | Linux-Capabilities zuweisen | |
--cap-drop | [CAP_…] | Linux-Capabilities ablegen | |
-d | --detach | false | Als Daemon laufen (nur run ) |
--device | /dev/HostDevice:/dev/ContainerDevice | Gerätedatei durchreichen | |
--dns | IpAddress | DNS-Server festlegen | |
--dns-search | Domain | Suchpräfix verwenden | |
-e | --env | [Name=Value …] | Umgebungsvariable setzen |
--env-file | Path | Umgebung aus Datei lesen | |
--entrypoint | Command | ENTRYPOINT überschreiben | |
--expose | Port | Port durchreichen | |
-h | --hostname | Host | Name des Containers festlegen |
-i | --interactive | false | Standardeingabe offen halten |
-l | --label | Name | Container benennen |
-m | --memory | N[bkmg] | Speicherauslastung begrenzen |
--name | Name | Alias für die Container-Nummer definieren | |
--net | bridge | Virtuelles Netzwerk bauen | |
container:Name:Id | …Stack des Containers | ||
host | …Stack des Hosts (unsicher) | ||
none | …Keines | ||
-p | --publish | [IpAddress:]HostPort:ContainerPort | Ports durchreichen |
-P | --publish-all | false | Alle Ports durchreichen |
--privileged | false | Privilegien erweitern | |
--restart | no | Kein Neustart nach Exit | |
on-failure | Neustart bei Fehler | ||
always | …immer | ||
unless-stopped | …außer wenn gestoppt | ||
--rm | false | Container beim Beenden löschen | |
-t | --tty | false | Pseudo-Terminal verwenden |
-u | --user | Uid[:Gid] | Als Benutzer (in Gruppe) laufen |
-v | --volume | [HostPath:ContainerPath …] | Volumen montieren |
-w | --workdir | Path | Arbeitsverzeichnis wechseln |
docker.io run -it debian sh
run?